/*
*******************************************************************************
*
*   Copyright (C) 2003, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*
* File colprobe.cpp
*
* Modification History:
*
*   Date        Name        Description
*   03/18/2003  weiv        Creation.
*******************************************************************************
*/

#include "uoptions.h"
#include "unicode/ucol.h"
#include "unicode/ucoleitr.h"
#include "unicode/ures.h"
#include "unicode/uniset.h"
#include "unicode/usetiter.h"
#include "unicode/ustring.h"
#include "unicode/uchar.h"
#include "unicode/uscript.h"
#include "unicode/locid.h"
#include "unicode/ucnv.h"
#include "uprops.h"
#include "hash.h"
#include "ucol_imp.h"

#include "unicode/ustdio.h"
#include "unicode/utrans.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

// unix tolower
#include <ctype.h>
// unix setlocale
#include <locale.h>

#include "colprobe.h"

#include "line.h"
#include "sortedlines.h"
#include "strengthprobe.h"

void testWin(StrengthProbe &probe, UErrorCode &status) ;

#if defined WIN32
#include <io.h>
#include <windows.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <direct.h>

int createDir(const char* dirName) {
  struct _stat myStat;
  int result = _stat(dirName, &myStat);
 
  if(result == -1) {
    result = _mkdir(dirName);
    return result;
  } else if(myStat.st_mode & _S_IFDIR) {
    return 0;
  } else {
    return 1;
  }
}

//#elif defined POSIX
#else
#include <sys/stat.h>
#include <unistd.h>

int createDir(const char* dirName) {
  struct stat myStat;
  int result = stat(dirName, &myStat);
 
  if(result == -1) {
    result = mkdir(dirName, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH);
    return result;
  } else if(S_ISDIR(myStat.st_mode)) {
    return 0;
  } else {
    return 1;
  }
}
//
//  Stubs for Windows API functions when building on UNIXes.
//
typedef int DWORD;
inline int CompareStringW(DWORD, DWORD, UChar *, int, UChar *, int) {return 0;};
//#else
//#error "Not POSIX or Windows. Won't work."
#endif

#include "line.h"

static UBool gVerbose = FALSE;
static UBool gDebug = FALSE;
static UBool gQuiet = FALSE;
static UBool gExemplar = FALSE;

DWORD          gWinLCID;
int            gCount;
UCollator     *gCol;
UCollator     *gUCA;
UConverter    *utf8cnv;
CompareFn gComparer;
int       gRefNum;
UnicodeSet gExcludeSet;
UnicodeSet gRepertoire;

const UChar separatorChar = 0x0030;

UPrinter *logger;
UPrinter *debug;
UPrinter *tailoringBundle;
UPrinter *referenceBundle;
UPrinter *bundle;
FILE     *fTailoringDump;
FILE     *fDefaultDump;

const char *progName = "colprobe";

const char *gLocale = NULL;
int32_t platformIndex = -1;
int32_t gPlatformNo = 0;
int32_t gPlatformIndexes[10];
int32_t gLocaleNo = 0;
const char* gLocales[100];
UBool gRulesStdin = FALSE;
const char *outputFormat = "HTML";
const char *outExtension = "html";

enum {
  HELP1,
    HELP2,
    VERBOSE,
    QUIET,
    VERSION,
    ICUDATADIR,
    COPYRIGHT,
    LOCALE,
    PLATFORM,
    DEBUG, 
    EXEMPLAR,
    RULESSTDIN,
    REFERENCE,
    EXCLUDESET,
    REPERTOIRE,
  INTERACTIVE,
  PRINTREF,
  DIFF, 
  OUTPUT
};

UOption options[]={
  /*0*/ UOPTION_HELP_H,
  /*1*/ UOPTION_HELP_QUESTION_MARK,
  /*2*/ UOPTION_VERBOSE,
  /*3*/ UOPTION_QUIET,
  /*4*/ UOPTION_VERSION,
  /*5*/ UOPTION_ICUDATADIR,
  /*6*/ UOPTION_COPYRIGHT,
  /*7*/ UOPTION_DEF("locale", 'l', UOPT_REQUIRES_ARG),
  /*8*/ UOPTION_DEF("platform", 'p', UOPT_REQUIRES_ARG),
  /*9*/ UOPTION_DEF("debug", 'D', UOPT_NO_ARG),
  /*10*/ UOPTION_DEF("exemplar", 'E', UOPT_NO_ARG),
  /*11*/ UOPTION_DEF("rulesstdin", 'R', UOPT_NO_ARG),
  /*12*/ UOPTION_DEF("ref", 'c', UOPT_REQUIRES_ARG),
  /*13*/ UOPTION_DEF("excludeset", 'x', UOPT_REQUIRES_ARG),
  /*14*/ UOPTION_DEF("repertoire", 't', UOPT_REQUIRES_ARG),
  /*15*/ UOPTION_DEF("interactive", 'I', UOPT_NO_ARG),
  /*16*/ UOPTION_DEF("printref", 0, UOPT_NO_ARG),
  /*17*/ UOPTION_DEF("diff", 0, UOPT_NO_ARG),
  /*18*/ UOPTION_DEF("output", 0, UOPT_REQUIRES_ARG)
};

UChar compA[256];
UChar compB[256];
int32_t compALen = 0;
int32_t compBLen = 0;

char compUTF8A[256];
char compUTF8B[256];
int32_t compUTF8ALen = 0;
int32_t compUTF8BLen = 0;

int UNIXstrcmp(const void *a, const void *b) {
  UErrorCode status = U_ZERO_ERROR;
    gCount++;
    int t;
    compALen = unorm_normalize((*(Line **)a)->name, (*(Line **)a)->len, UNORM_NFC, 0, compA, 256, &status);
    compBLen = unorm_normalize((*(Line **)b)->name, (*(Line **)b)->len, UNORM_NFC, 0, compB, 256, &status);
    compUTF8ALen = ucnv_fromUChars(utf8cnv, compUTF8A, 256, compA, compALen, &status);
    compUTF8A[compUTF8ALen] = 0;
    compUTF8BLen = ucnv_fromUChars(utf8cnv, compUTF8B, 256, compB, compBLen, &status);
    compUTF8B[compUTF8BLen] = 0;
    t = strcoll(compUTF8A, compUTF8B);
    return t;
}

int UNIXgetSortKey(const UChar *string, int32_t len, uint8_t *buffer, int32_t buffCapacity) {
  UErrorCode status = U_ZERO_ERROR;
  compALen = unorm_normalize(string, len, UNORM_NFC, 0, compA, 256, &status);
  compUTF8ALen = ucnv_fromUChars(utf8cnv, compUTF8A, 256, compA, compALen, &status);
  compUTF8A[compUTF8ALen] = 0;
  return (strxfrm((char *)buffer, compUTF8A, buffCapacity)+1);
}

#ifdef WIN32
int Winstrcmp(const void *a, const void *b) {
  UErrorCode status = U_ZERO_ERROR;
    gCount++;
    int t;
    //compALen = unorm_compose(compA, 256, (*(Line **)a)->name, (*(Line **)a)->len, FALSE, 0, &status);
    //compBLen = unorm_compose(compB, 256, (*(Line **)b)->name, (*(Line **)b)->len, FALSE, 0, &status);
    compALen = unorm_normalize((*(Line **)a)->name, (*(Line **)a)->len, UNORM_NFC, 0, compA, 256, &status);
    compBLen = unorm_normalize((*(Line **)b)->name, (*(Line **)b)->len, UNORM_NFC, 0, compB, 256, &status);
    t = CompareStringW(gWinLCID,  SORT_STRINGSORT, //0,
      compA, compALen, 
      compB, compBLen);

/*    
    t = CompareStringW(gWinLCID, 0, 
      (*(Line **)a)->name, (*(Line **)a)->len, 
      (*(Line **)b)->name, (*(Line **)b)->len);
*/
    return t-2;
}

int WingetSortKey(const UChar *string, int32_t len, uint8_t *buffer, int32_t buffCapacity) {
  UErrorCode status = U_ZERO_ERROR;
  compALen = unorm_normalize(string, len, UNORM_NFC, 0, compA, 256, &status);
  return LCMapStringW(gWinLCID, LCMAP_SORTKEY | SORT_STRINGSORT, compA, compALen, (unsigned short *)buffer, buffCapacity);
}

#if 0
int Winstrcmp(const void *a, const void *b) {
  UErrorCode status = U_ZERO_ERROR;
  uint8_t b1[256], b2[256];
  int32_t b1Len, b2Len;
  b1Len = WingetSortKey((*(Line **)a)->name, (*(Line **)a)->len, b1, 256);
  b2Len = WingetSortKey((*(Line **)b)->name, (*(Line **)b)->len, b2, 256);

  b1[b1Len] = 0;
  b2[b2Len] = 0;
  
  return strcmp((const char *)b1, (const char *)b2);
}
#endif

#else
int Winstrcmp(const void *a, const void *b) {
  if(a == b);
  return 0;
}
int WingetSortKey(const UChar *, int32_t , uint8_t *, int32_t ) {
  return 0;
}
#endif

int ICUstrcmp(const void *a, const void *b) {
    gCount++;
    UCollationResult t;
    t = ucol_strcoll(gCol, 
      (*(Line **)a)->name, (*(Line **)a)->len,  
      (*(Line **)b)->name, (*(Line **)b)->len);
    if (t == UCOL_LESS) return -1;
    if (t == UCOL_GREATER) return +1;
    return 0;
}

int ICUgetSortKey(const UChar *string, int32_t len, uint8_t *buffer, int32_t buffCapacity) {
  return ucol_getSortKey(gCol, string, len, buffer, buffCapacity);
}

struct {
  const char* name;
  CompareFn comparer;
  GetSortKeyFn skgetter;
} platforms[] = {
  { "icu", ICUstrcmp, ICUgetSortKey },
  { "w2k", Winstrcmp, WingetSortKey},
  { "winxp", Winstrcmp, WingetSortKey},
  { "aix", UNIXstrcmp, UNIXgetSortKey},
  { "linux", UNIXstrcmp, UNIXgetSortKey}
};


void stringToLower(char *string) {
  uint32_t i = 0;
  for(i = 0; i < strlen(string); i++) {
    string[i] = tolower(string[i]);
  }
}

void usage(const char *name) {
  logger->log("Usage: %s --locale loc_name --platform platform\n", name);
}

void listKnownPlatforms() {
  uint32_t i = 0;
  logger->log("Known platforms:\n");
  for(i = 0; i < sizeof(platforms)/sizeof(platforms[0]); i++) {
    logger->log("\t%s\n", platforms[i]);
  }
}

void addPlatform(const char *platform) {
  uint32_t i;
  //stringToLower(platform);
  int32_t oldPlatformNo = gPlatformNo;

  for(i = 0; i < sizeof(platforms)/sizeof(platforms[0]); i++) {
    if(strcmp(platform, platforms[i].name) == 0) {
      gPlatformIndexes[gPlatformNo++] = i;
    }
  }
  if(gPlatformNo == oldPlatformNo) {
    logger->log("Unknown platform %s\n", platform);
    listKnownPlatforms();
  }
}

void processArgs(int argc, char* argv[], UErrorCode &status)
{
  int32_t i = 0;
  U_MAIN_INIT_ARGS(argc, argv);

  argc = u_parseArgs(argc, argv, (int32_t)(sizeof(options)/sizeof(options[0])), options);

  if(argc < 0) {
    logger->log("Unknown option: %s\n", argv[-argc]);
    usage(progName);
    return;
  }

  if(options[0].doesOccur || options[1].doesOccur) {
    usage(progName);
    return;
  }
  if(options[VERBOSE].doesOccur) {
    gVerbose = TRUE;
  }
  if(options[DEBUG].doesOccur) {
    gDebug = TRUE;
    gVerbose = TRUE;
  }
  if(options[EXEMPLAR].doesOccur) {
    gExemplar = TRUE;
  }
  if(options[QUIET].doesOccur) {
    gQuiet = TRUE;
  }

  // ASCII based options specified on the command line
  // this is for testing purposes, will allow to load
  // up ICU rules and then poke through them.
  // In that case, we test only ICU and don't need 
  // a locale.
  if(options[RULESSTDIN].doesOccur) {
    gRulesStdin = TRUE;
    addPlatform("icu");
    return;
  } 

  if(options[LOCALE].doesOccur) {
    gLocale = options[LOCALE].value;
  } else {
    gLocale = argv[1];
    //for(i = 1; i < argc; i++) {
    //gLocales[gLocaleNo++] = argv[i];
    //}
  }

  if(options[PLATFORM].doesOccur) {
    addPlatform(options[PLATFORM].value);
  } else { // there is a list of platforms 
    addPlatform("icu");
  }

  if(options[REFERENCE].doesOccur) {
    for(i = 0; i < (int32_t)(sizeof(platforms)/sizeof(platforms[0])); i++) {
      if(strcmp(options[REFERENCE].value, platforms[i].name) == 0) {
        gRefNum = i;
        break;
      }
    }
    if(i == sizeof(platforms)/sizeof(platforms[0])) {
      logger->log("Unknown reference %s!\n", options[REFERENCE].value);
      status = U_ILLEGAL_ARGUMENT_ERROR;
      return;
    }
  } else {
    gRefNum = 0;
  }

  if(options[EXCLUDESET].doesOccur) {
    gExcludeSet.applyPattern(UnicodeString(options[EXCLUDESET].value), status);
    if(U_FAILURE(status)) {
      logger->log("Cannot construct exclude set from argument %s. Error %s\n", options[EXCLUDESET].value, u_errorName(status));
      return;
    } else {
      UnicodeString pattern;
      logger->log(gExcludeSet.toPattern(pattern, TRUE), TRUE);
    }
  }

  if(options[REPERTOIRE].doesOccur)  {
    gRepertoire.applyPattern(UnicodeString(options[REPERTOIRE].value), status);
    if(U_FAILURE(status)) {
      logger->log("Cannot construct repertoire from argument %s. Error %s\n", options[REPERTOIRE].value, u_errorName(status));
      return;
    }
  }

  if(options[OUTPUT].doesOccur) {
    outputFormat = options[OUTPUT].value;
    if(strcmp(outputFormat, "HTML") == 0) {
      outExtension = "html";
    } else if(strcmp(outputFormat, "XML") == 0) {
      outExtension = "xml";
    } else {
      outExtension = "txt";
    }
  }

}

// Check whether upper case comes before lower case or vice-versa
int32_t 
checkCaseOrdering(void) {
  UChar stuff[][3] = {
    { 0x0061, separatorChar, 0x0061}, //"aa",
    { 0x0061, separatorChar, 0x0041 }, //"a\\u00E0",
    { 0x0041, separatorChar, 0x0061 }, //"\\u00E0a",
    { 0x0041, separatorChar, 0x0041 }, //"\\u00E0a",
    //{ 0x00E0, separatorChar, 0x00E0 }  //"\\u00E0\\u00E0"
  };
  const int32_t size = sizeof(stuff)/sizeof(stuff[0]);

  Line **sortedLines = new Line*[size];
  Line lines[size];

  int32_t i = 0;
  int32_t ordered = 0, reversed = 0;

  for(i = 0; i < size; i++) {
    lines[i].setName(stuff[i], 3);
  }
  //setArray(sortedLines, lines, size);
  qsort(sortedLines, size, sizeof(Line*), gComparer);

  for(i = 0; i < size; i++) {
    if(*(sortedLines+i) == &lines[i]) {
      ordered++;
    }
    if(*(sortedLines+i) == &lines[size-i-1]) {
      reversed++;
    }
  }

  delete[] sortedLines;
  if(ordered == size) {
    return 0; // in normal order
  } else if(reversed == size) {
    return 1; // in reversed order
  } else {
    return -1; // unknown order
  }
}

void
getExemplars(const char *locale, UnicodeSet &exemplars, UErrorCode &status) {
  // first we fill out structures with exemplar characters.
  UResourceBundle *res = ures_open(NULL, locale, &status);
  UnicodeString exemplarString = ures_getUnicodeStringByKey(res, "ExemplarCharacters", &status);
  exemplars.clear();
  exemplars.applyPattern(exemplarString, status);
  ures_close(res);
}


void
getFileNames(const char *name, char *tailoringName, char *tailoringDumpName, char *defaultName, char *defaultDumpName, char *diffName) {
  if(tailoringName) {
    strcpy(tailoringName, platforms[gPlatformIndexes[0]].name);
    strcat(tailoringName, "/");
    strcat(tailoringName, name);
    strcat(tailoringName, "_raw.");
    strcat(tailoringName, outExtension);
  }
  if(tailoringDumpName) {
    strcpy(tailoringDumpName, platforms[gPlatformIndexes[0]].name);
    strcat(tailoringDumpName, "/");
    strcat(tailoringDumpName, name);
    strcat(tailoringDumpName, ".dump");
  }

  if(diffName) {
    strcpy(diffName, platforms[gPlatformIndexes[0]].name);
    strcat(diffName, "/");
    strcat(diffName, name);
    strcat(diffName, "_collation.");
    strcat(diffName, outExtension);
  }

  if(defaultName) {
    strcpy(defaultName, platforms[gRefNum].name);
    strcat(defaultName, "/");
    strcat(defaultName, name);
    strcat(defaultName, "_default_raw.");
    strcat(defaultName, outExtension);
  }

  if(defaultDumpName) {
    strcpy(defaultDumpName, platforms[gRefNum].name);
    strcat(defaultDumpName, "/");
    strcat(defaultDumpName, name);
    strcat(defaultDumpName, "_default.dump");
  }
}

void 
setFiles(const char *name, UErrorCode &status) {
  if(U_FAILURE(status)) {
    return;
  }
  int32_t i = 0;
  char tailoringName[256];
  char tailoringDumpName[256];
  char defaultName[256];
  char defaultDumpName[256];
  char diffName[256];

  getFileNames(name, tailoringName, tailoringDumpName, defaultName, defaultDumpName, diffName);
  if(options[PLATFORM].doesOccur && !options[DIFF].doesOccur) {  
    if(createDir(platforms[gPlatformIndexes[0]].name) == 0) {
      tailoringBundle = new UPrinter(tailoringName, "en", "utf-8", NULL, FALSE);
      fTailoringDump = fopen(tailoringDumpName, "wb");
    } else {
      status = U_FILE_ACCESS_ERROR;
      return;
    }
  }

  if(options[REFERENCE].doesOccur && !options[DIFF].doesOccur) {
    if(createDir(platforms[gRefNum].name) == 0) {
      referenceBundle = new UPrinter(defaultName, "en", "utf-8", NULL, FALSE);
      fDefaultDump = fopen(defaultDumpName, "wb");
    } else {
      status = U_FILE_ACCESS_ERROR;
      return;
    }
  }

  if((options[PLATFORM].doesOccur && options[REFERENCE].doesOccur) || options[DIFF].doesOccur) {
    if(createDir(platforms[gPlatformIndexes[0]].name) == 0) {
      bundle = new UPrinter(diffName, "en", "utf-8", NULL, FALSE);
    }
  }
  if(options[DIFF].doesOccur) {
    fTailoringDump = fopen(tailoringDumpName, "rb");
    fDefaultDump = fopen(defaultDumpName, "rb");
  }
}


UErrorCode status = U_ZERO_ERROR;
static UnicodeSet UNASSIGNED(UnicodeString("[:Cn:]"), status);
static UnicodeSet GENERAL_ACCENTS(UnicodeString("[[:block=Combining Diacritical Marks:]-[:Cn:]]"), status);
//static UnicodeSet ASCII_BASE(UnicodeString("[[:ASCII:]-[:L:]-[:N:]]"), status);
static UnicodeSet ASCII_BASE(UnicodeString("[[:ASCII:]]"), status);
static UnicodeSet ALPHABETIC(UnicodeString("[:alphabetic:]"), status);
//static UnicodeSet CONTROL(UnicodeString("[[:control:][\\u0000-\\u002F]]"), status);
static UnicodeSet BMP(UnicodeString("[\\u0000-\\uFFFF]"), status);

static UnicodeSet CONTROL(UnicodeString("[:control:]"), status);

UCollator *
setLocale(const char* locale, UErrorCode &status)
{
  gWinLCID = uloc_getLCID(locale);
  setlocale(LC_COLLATE, locale);

  if(gCol) {
    ucol_close(gCol);
  }
  gCol = ucol_open(locale, &status);
  ucol_setAttribute(gCol, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
  //ucol_setAttribute(col, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &status);
  //ucol_setAttribute(col, UCOL_STRENGTH, UCOL_QUATERNARY, &status);

  return gCol;
}



UCollator *
setReference(UErrorCode &status) 
{
  gWinLCID = uloc_getLCID("en");
  setlocale(LC_COLLATE, "en_US.UTF-8");
  if(gCol) {
    ucol_close(gCol);
  }
  gCol = ucol_open("root", &status);
  ucol_setAttribute(gCol, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
  return gCol;
}

void
processInteractive() {
  char command[256];
  while(fgets(command, 256, stdin)) {

  }
}

UChar probeChars[][4] = {
  { 0x0061, 0x0062, 0x00E1, 0x0041 }, // latin with a-grave
  { 0x0041, 0x0042, 0x00C1, 0x0061 }, // upper first
  { 0x006E, 0x006F, 0x00F1, 0x004E }, // latin with n-tilda
  { 0x004E, 0x004F, 0x00D1, 0x006E }, // upper first
  { 0x0433, 0x0493, 0x0491, 0x0413 }, // Cyrillic
  { 0x0413, 0x0492, 0x0490, 0x0433 }, // upper first
  { 0x3045, 0x3047, 0x3094, 0x3046 }  // Hiragana/Katakana (last resort)

};

void
processCollator(UCollator *col, UErrorCode &status) {
  int32_t i = 0;
  uint32_t j = 0;
  gCol = col;
  UChar ruleString[16384];
  char myLoc[256];

  int32_t ruleStringLength = ucol_getRulesEx(gCol, UCOL_TAILORING_ONLY, ruleString, 16384);
  logger->log(UnicodeString(ruleString, ruleStringLength), TRUE);
  const char *locale = ucol_getLocale(gCol, ULOC_REQUESTED_LOCALE, &status);
  if(locale == NULL) {
    locale = "en";
  }
  strcpy(myLoc, locale);
  UnicodeSet exemplarUSet;
  UnicodeSet RefRepertoire;

  UnicodeSet tailored;

  tailored = *((UnicodeSet *)ucol_getTailoredSet(gCol, &status));
  tailored.removeAll(CONTROL);


  UnicodeString pattern;
  int sanityResult;

  UnicodeSet hanSet;
  UBool hanAppears = FALSE;

  debug->log("\nGenerating order for platform: %s\n", platforms[gPlatformIndexes[0]].name);
  gComparer = platforms[gPlatformIndexes[0]].comparer;

  StrengthProbe probe(platforms[gPlatformIndexes[0]].comparer, platforms[gPlatformIndexes[0]].skgetter, 0x0030, probeChars[0][0], probeChars[0][1], probeChars[0][2], probeChars[0][3]);
  sanityResult = probe.checkSanity();
  j = 0;
  while(sanityResult && j+1 < sizeof(probeChars)/sizeof(probeChars[0])) {
   j++;
   sanityResult =  probe.setProbeChars(probeChars[j][0], probeChars[j][1], probeChars[j][2], probeChars[j][3]);
  }
  if(sanityResult) {
    logger->log("Bad choice of probe characters! Sanity returned %i. Exiting\n", sanityResult, sanityResult);
    return;
  }
  logger->log("Probe chars: %C, %C, %C, %C\n", probeChars[j][0], probeChars[j][1], probeChars[j][2], probeChars[j][3]); 

  debug->off();

  if(gRepertoire.size()) {
    exemplarUSet = gRepertoire;
  } else {
    generateRepertoire(locale, exemplarUSet, hanAppears, status);
  }
  exemplarUSet.addAll(tailored);
  hanSet.applyIntPropertyValue(UCHAR_SCRIPT, USCRIPT_HAN, status);
  exemplarUSet.removeAll(hanSet);
  
  logger->log(exemplarUSet.toPattern(pattern, TRUE), TRUE);

  exemplarUSet = flatten(exemplarUSet, status);
  logger->log(exemplarUSet.toPattern(pattern, TRUE), TRUE);

  if(!options[PRINTREF].doesOccur) {

    logger->log("\n*** Detecting ordering for the locale\n\n");

    debug->on();
    SortedLines lines(exemplarUSet, gExcludeSet, probe, logger, debug);
    lines.analyse(status);
    lines.calculateSortKeys();
    debug->log("\n*** Final order\n\n");
    debug->log(lines.toPrettyString(TRUE, TRUE), TRUE);
    lines.toFile(fTailoringDump, TRUE, status);
    tailoringBundle->log(lines.toOutput(outputFormat, myLoc, platforms[gPlatformIndexes[0]].name, NULL, TRUE, TRUE, hanAppears), TRUE);
    //debug->off();

    if(options[REFERENCE].doesOccur) {
      status = U_ZERO_ERROR;
      lines.getRepertoire(RefRepertoire);
      setReference(status);

      logger->log(exemplarUSet.toPattern(pattern, TRUE), TRUE);
      logger->log(RefRepertoire.toPattern(pattern, TRUE), TRUE);

      StrengthProbe RefProbe(platforms[gRefNum].comparer, platforms[gRefNum].skgetter);
      logger->log("\n*** Detecting ordering for reference\n\n");
      SortedLines RefLines(exemplarUSet, gExcludeSet, RefProbe, logger, debug);
      RefLines.analyse(status);
      referenceBundle->log(RefLines.toOutput(outputFormat, myLoc, platforms[gRefNum].name, NULL, TRUE, TRUE, FALSE), TRUE);
      RefLines.toFile(fDefaultDump, TRUE, status);

      lines.reduceDifference(RefLines);
      logger->log("\n*** Final rules\n\n");
      logger->log(lines.toPrettyString(TRUE), TRUE);
      bundle->log(lines.toOutput(outputFormat, myLoc, platforms[gPlatformIndexes[0]].name, platforms[gRefNum].name, TRUE, TRUE, hanAppears), TRUE);
    }
  } else {
    setReference(status);
    StrengthProbe RefProbe(platforms[gRefNum].comparer, platforms[gRefNum].skgetter);
    logger->log("\n*** Detecting ordering for reference\n\n");
    SortedLines RefLines(exemplarUSet, gExcludeSet, RefProbe, logger, debug);
    RefLines.analyse(status);
    logger->log(RefLines.toPrettyString(TRUE), TRUE);
    referenceBundle->log(RefLines.toOutput(outputFormat, myLoc, platforms[gRefNum].name, NULL, TRUE, TRUE, FALSE), TRUE);
  }
  if(hanAppears) {
    // there are Han characters. This is a huge block. The best we can do is to just sort it, compare to empty
    // and spit it out. Anything else would be a suicide (actually is - kernel just kills you :)
    logger->log("\n*** Detecting order for Han\n");
    debug->off();
    setLocale(gLocale, status);
    exemplarUSet.clear();
    exemplarUSet.applyIntPropertyValue(UCHAR_SCRIPT, USCRIPT_HAN, status);
    exemplarUSet = flatten(exemplarUSet, status);
    SortedLines han(exemplarUSet, gExcludeSet, probe, logger, debug);
    han.sort(TRUE, TRUE);
    han.classifyRepertoire();
    han.getBounds(status);
    tailoringBundle->log("Han ordering:<br>\n");
    tailoringBundle->log(han.toOutput(outputFormat, myLoc, platforms[gPlatformIndexes[0]].name, NULL, TRUE, FALSE, FALSE), TRUE);
    bundle->log(han.toOutput(outputFormat, myLoc, platforms[gPlatformIndexes[0]].name, NULL, TRUE, FALSE, FALSE), TRUE);
  }
  ucol_close(gCol);
}

void
processLocale(const char *locale, UErrorCode &status) {
  setLocale(locale, status);
  setFiles(locale, status);
  if(U_FAILURE(status)) {
    return;
  }

  debug->log("Locale %s (LCID:%06X, unix:%s)\n", locale, gWinLCID, setlocale(LC_COLLATE, NULL));
  tailoringBundle->log("// Ordering for locale %s (LCID:%06X, unix:%s), platform %s reference %s<br>\n", 
    locale, gWinLCID, setlocale(LC_COLLATE, NULL), 
    platforms[gPlatformIndexes[0]].name, platforms[gRefNum].name);
  if(options[REFERENCE].doesOccur) {
    referenceBundle->log("// Reference for locale %s (LCID:%06X, unix:%s), platform %s reference %s<br>\n", 
      locale, gWinLCID, setlocale(LC_COLLATE, NULL), 
      platforms[gPlatformIndexes[0]].name, platforms[gRefNum].name);
  }


  processCollator(gCol, status);
}



UBool 
hasCollationElements(const char *locName) {

  UErrorCode status = U_ZERO_ERROR;
  UResourceBundle *ColEl = NULL;

  UResourceBundle *loc = ures_open(NULL, locName, &status);;

  if(U_SUCCESS(status)) {
    status = U_ZERO_ERROR;
    ColEl = ures_getByKey(loc, "CollationElements", ColEl, &status);
    if(status == U_ZERO_ERROR) { /* do the test - there are real elements */
      ures_close(ColEl);
      ures_close(loc);
      return TRUE;
    }
    ures_close(ColEl);
    ures_close(loc);
  }
  return FALSE;
}

int
main(int argc,
     char* argv[])
{
  UErrorCode status = U_ZERO_ERROR;
  logger = new UPrinter(stdout, "en", "latin-1");
  debug =  new UPrinter(stderr, "en", "latin-1");

/*
  USet *wsp = uprv_openRuleWhiteSpaceSet(&status);
  uset_add(wsp, 0x0041);
  uset_remove(wsp, 0x0041);
  UnicodeString pat;
  ((UnicodeSet *)wsp)->toPattern(pat, TRUE);
  pat.setCharAt(pat.length(), 0);
  escapeString(pat.getBuffer(), pat.length(), log);
  u_fflush(log);
*/

  processArgs(argc, argv, status);
  int32_t i = 0;



  if(U_FAILURE(status) || gPlatformNo == 0) {
    return -1;
  }

  utf8cnv = ucnv_open("utf-8", &status);    // we are just doing UTF-8 locales for now.
  gUCA = ucol_open("root", &status);

  if(options[INTERACTIVE].doesOccur) {
    processInteractive();
  } else {
    if(gRulesStdin) {
      char buffer[1024];
      UChar ruleBuffer[16384];
      UChar *rules = ruleBuffer;
      int32_t maxRuleLen = 16384;
      int32_t rLen = 0;
      while(fgets(buffer, 1024, stdin)) {
        if(buffer[0] != '/' && buffer[1] != '/') {
          rLen = u_unescape(buffer, rules, maxRuleLen);
          rules += rLen;
          maxRuleLen -= rLen;
        }
      }
      UParseError parseError;
      //escapeString(ruleBuffer, rules-ruleBuffer, log);//
      debug->log("%U\n", ruleBuffer);

      UCollator *col = ucol_openRules(ruleBuffer, rules-ruleBuffer, UCOL_DEFAULT, UCOL_DEFAULT, &parseError, &status);
      if(U_SUCCESS(status)) {
        setFiles("stdinRules", status);
        processCollator(col, status);
      } else {
        logger->log("Error %s\n", u_errorName(status));
      }
    } else if(options[DIFF].doesOccur) {
      logger->log("Diffing two dumps\n");
      // must have locale, platform and ref in order to be 
      // able to find dump files.
      setFiles(gLocale, status);
  
      if(fTailoringDump && fDefaultDump) {
	    SortedLines tailoring(fTailoringDump, logger, debug, status);
	    logger->log(tailoring.toString(TRUE), TRUE);
	    SortedLines reference(fDefaultDump, logger, debug, status);
	    logger->log(reference.toString(TRUE), TRUE);
	    tailoring.reduceDifference(reference);
	    logger->log("\n*** Final rules\n\n");
	    logger->log(tailoring.toPrettyString(TRUE), TRUE);
	    //result->log(lines.toPrettyString(TRUE), TRUE);
	    bundle->log(tailoring.toOutput(outputFormat, gLocale, platforms[gPlatformIndexes[0]].name, platforms[gRefNum].name, TRUE, TRUE, FALSE), TRUE);
      }

    } else {
      if(gLocale) {
        processLocale(gLocale, status);
      } else if(gLocaleNo) {
        for(i = 0; i < gLocaleNo; i++) {
          processLocale(gLocales[i], status);
        }
      } else { // do the loop through all the locales
        int32_t noOfLoc = uloc_countAvailable();
        const char *locName = NULL;
        for(i = 0; i<noOfLoc; i++) {
          status = U_ZERO_ERROR;
          locName = uloc_getAvailable(i);
          if(hasCollationElements(locName)) {
            processLocale(locName, status);
          }
        }
      }
    }
  }


  ucol_close(gUCA);
  ucnv_close(utf8cnv);

  delete logger;
  delete debug;
  if(tailoringBundle) {
    delete tailoringBundle;
  }
  if(referenceBundle) {
    delete referenceBundle;
  }
  if(bundle) {
    delete bundle;
  }
  if(fTailoringDump) {
    fclose(fTailoringDump);
  }
  if(fDefaultDump) {
    fclose(fDefaultDump);
  }
  return 0;
}


UnicodeString propertyAndValueName(UProperty prop, int32_t i) {
  UnicodeString result;
  result.append(u_getPropertyName(prop, U_LONG_PROPERTY_NAME));
  result.append("=");
  result.append(u_getPropertyValueName(prop, i, U_LONG_PROPERTY_NAME));

    //+ "(" + prop + "," + i + ") ";
  return result;
}


void generateRepertoire(const char *locale, UnicodeSet &rep, UBool &hanAppears, UErrorCode &status) {
    UnicodeString dispName;
    debug->log("Getting repertoire for %s\n", locale);
    tailoringBundle->log("// Scripts in repertoire: ");
    if(options[REFERENCE].doesOccur) {
      referenceBundle->log("// Scripts in repertoire: ");
    }
	rep.clear();
    UnicodeSet delta;
    
    UScriptCode script[256];
    int32_t i = 0;
    // now add the scripts for the locale
    UProperty prop = UCHAR_SCRIPT;
	int32_t scriptLength = uscript_getCode(locale, script, 256, &status);
    if(scriptLength) {
	  for (i = 0; i < scriptLength; ++i) {
        if(script[i] == USCRIPT_HAN) {
          hanAppears = TRUE;
          continue;
        }
        delta.applyIntPropertyValue(prop, script[i], status);
        debug->log("Adding ");
        debug->log(propertyAndValueName(prop, script[i]), TRUE);
        tailoringBundle->log("// ");
        tailoringBundle->log(propertyAndValueName(prop, script[i]), TRUE);
        if(options[REFERENCE].doesOccur) {
          referenceBundle->log("// ");
          referenceBundle->log(propertyAndValueName(prop, script[i]), TRUE);
        }
		rep.addAll(delta);
	  }
    } else {
      delta.applyIntPropertyValue(UCHAR_SCRIPT, USCRIPT_LATIN, status);
      rep.addAll(delta);
    }
    
    // now see which blocks those overlap, and add
    prop = UCHAR_BLOCK;
    int32_t min = u_getIntPropertyMinValue(prop);
    int32_t max = u_getIntPropertyMaxValue(prop);
    UnicodeSet checkDelta;
    for (i = min; i <= max; ++i) {
        // skip certain blocks
        const char *name = u_getPropertyValueName(prop, i, U_LONG_PROPERTY_NAME);
        if (strcmp(name, "Superscripts_and_Subscripts") == 0
        || strcmp(name, "Letterlike_Symbols") == 0
        || strcmp(name, "Alphabetic_Presentation_Forms") == 0
        || strcmp(name, "Halfwidth_and_Fullwidth_Forms") == 0) continue;

        delta.applyIntPropertyValue(prop, i, status).removeAll(UNASSIGNED);
        if (!rep.containsSome(delta)) continue;
        if (rep.containsAll(delta)) continue; // just to see what we are adding
        debug->log("Adding ");
        debug->log(propertyAndValueName(prop, i), TRUE);                
        tailoringBundle->log("// ");
        tailoringBundle->log(propertyAndValueName(prop, i), TRUE);
        if(options[REFERENCE].doesOccur) {
          referenceBundle->log("// ");
          referenceBundle->log(propertyAndValueName(prop, i), TRUE);
        }
        rep.addAll(delta);
    }
    
    // add ASCII and general accents
    rep.addAll(GENERAL_ACCENTS).addAll(ASCII_BASE);
    rep.removeAll(CONTROL);
    //delta.applyIntPropertyValue(UCHAR_SCRIPT, USCRIPT_HAN, status);
    //rep.removeAll(delta);

    // now add the exemplar characters
    // can't get at them from Java right now
    tailoringBundle->log("<br>\n");
    if(options[REFERENCE].doesOccur) {
      referenceBundle->log("<br>\n");
    }
}

UnicodeSet flatten(const UnicodeSet &source, UErrorCode &status) {
    UnicodeSet result;
    UnicodeSetIterator it(source);
    UnicodeString item, itemNFKD, toNormalize;
    while (it.next()) {
        // would be nicer if UnicodeSetIterator had a getString function
        if (it.isString()) {
          Normalizer::normalize(it.getString(), UNORM_NFD, 0, item, status);
          Normalizer::normalize(it.getString(), UNORM_NFKD, 0, itemNFKD, status);
        } else {
          toNormalize.setTo(it.getCodepoint());
          Normalizer::normalize(toNormalize, UNORM_NFD, 0, item, status);
          Normalizer::normalize(toNormalize, UNORM_NFKD, 0, itemNFKD, status);
        }
        result.addAll(item);
        result.addAll(itemNFKD);
    }
    return result;
}


void testWin(StrengthProbe &probe, UErrorCode &status) 
{
  UnicodeSet trailings(UnicodeString("[\\uFE7D\\uFE7C\\u30FD\\uFF70\\u30FC\\u309D\\u3032\\u3031\\u3005\\u0651]"), status);
  char intChar[] = "\\uFE7D\\uFE7C\\u30FD\\uFF70\\u30FC\\u309D\\u3032\\u3031\\u3005\\u0651";
  UChar interesting[256];
  int32_t intLen = u_unescape(intChar, interesting, 256);
  UChar i = 0;
  UChar j = 0,  k = 0;
  int32_t count;
  Line myCh, combo, trial, inter, kLine;
  for(i = 0; i < intLen; i++) {
    inter.setTo(interesting[i]);
    logger->log(inter.toString(TRUE), TRUE);
    logger->log("----------------------\n");
    for(j = 0; j < 0xFFFF; j++) {
      myCh.setTo(j);
      if(probe.distanceFromEmptyString(myCh) == UCOL_IDENTICAL) {
        continue;
      }
      logger->log(myCh.toString(TRUE));
      combo.setTo(j);
      combo.append(interesting[i]);
      count = 0;
      for(k = 0; k < 0xFFFF; k++) {
        kLine.setTo(k);
        trial.setTo(j);
        trial.append(k);
        if(probe.compare(kLine, inter) < 0) {
          if(probe.compare(trial, combo) >= 0) {
            count++;
          }
        }
      }
      logger->log("%i %i\n", count, count);
    }
  }
}

