// Copyright (C) 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/**
 * Copyright (c) 1999-2016, International Business Machines Corporation and
 * others. All Rights Reserved.
 *
 * Generator for source/i18n/collunsafe.h
 * see Makefile
 */

#include <stdio.h>
#include "unicode/uversion.h"
#include "unicode/uniset.h"
#include "collationroot.h"
#include "collationtailoring.h"

/**
 * Define the type of generator to use. Choose one.
 */
#define SERIALIZE 1   //< Default: use UnicodeSet.serialize() and a new internal c'tor
#define RANGES 0      //< Enumerate ranges (works, not as fast. No support in collationdatareader.cpp)
#define PATTERN 0     //< Generate a UnicodeSet pattern (depends on #11891 AND probably slower. No support in collationdatareader.cpp)

int main(int argc, const char *argv[]) {
    UErrorCode errorCode = U_ZERO_ERROR;

    // Get the unsafeBackwardsSet
    const CollationCacheEntry *rootEntry = CollationRoot::getRootCacheEntry(errorCode);
    if(U_FAILURE(errorCode)) {
      fprintf(stderr, "Err: %s getting root cache entry\n", u_errorName(errorCode));
      return 1;
    }
    const UVersionInfo &version = rootEntry->tailoring->version;
    const UnicodeSet *unsafeBackwardSet = rootEntry->tailoring->unsafeBackwardSet;
    char verString[20];
    u_versionToString(version, verString);
    fprintf(stderr, "Generating data for ICU %s, Collation %s\n", U_ICU_VERSION, verString);
    int32_t rangeCount = unsafeBackwardSet->getRangeCount();
    
#if SERIALIZE
    fprintf(stderr, ".. serializing\n");
    // UnicodeSet serialization
    
    UErrorCode preflightCode = U_ZERO_ERROR;
    // preflight
    int32_t serializedCount = unsafeBackwardSet->serialize(NULL,0,preflightCode);
    if(U_FAILURE(preflightCode) && preflightCode != U_BUFFER_OVERFLOW_ERROR) {
      fprintf(stderr, "Err: %s preflighting unicode set\n", u_errorName(preflightCode));
      return 1;
    }
    uint16_t *serializedData = new uint16_t[serializedCount];
    // serialize
    unsafeBackwardSet->serialize(serializedData, serializedCount, errorCode);
    if(U_FAILURE(errorCode)) {
      delete [] serializedData;
      fprintf(stderr, "Err: %s serializing unicodeset\n", u_errorName(errorCode));
      return 1;
    }
#endif
    
#if PATTERN
    fprintf(stderr,".. pattern. (Note: collationdatareader.cpp does not support this form also see #11891)\n");
    // attempt to use pattern
    
    UnicodeString pattern;
    UnicodeSet set(*unsafeBackwardSet);
    set.compact();
    set.toPattern(pattern, FALSE);

    if(U_SUCCESS(errorCode)) {
      // This fails (bug# ?) - which is why this method was abandoned.
      
      // UnicodeSet usA(pattern, errorCode);
      // fprintf(stderr, "\n%s:%d: err creating set A %s\n", __FILE__, __LINE__, u_errorName(errorCode));
      // return 1;
    }


    const UChar *buf = pattern.getBuffer();
    int32_t needed = pattern.length();

    // print
    {
      char buf2[2048];
      int32_t len2 = pattern.extract(0, pattern.length(), buf2, "utf-8");
      buf2[len2]=0;
      fprintf(stderr,"===\n%s\n===\n", buf2);
    }

    const UnicodeString unsafeBackwardPattern(FALSE, buf, needed);
  if(U_SUCCESS(errorCode)) {
    //UnicodeSet us(unsafeBackwardPattern, errorCode);
    //    fprintf(stderr, "\n%s:%d: err creating set %s\n", __FILE__, __LINE__, u_errorName(errorCode));
  } else {
    fprintf(stderr, "Uset OK - \n");
  }
#endif


  // Generate the output file.

  printf("// collunsafe.h\n");
  printf("// %s\n", U_COPYRIGHT_STRING);
  printf("\n");
  printf("// To be included by collationdatareader.cpp, and generated by gencolusb.\n");
  printf("// Machine generated, do not edit.\n");
  printf("\n");
  printf("#ifndef COLLUNSAFE_H\n"
         "#define COLLUNSAFE_H\n"
         "\n"
         "#include \"unicode/utypes.h\"\n"
         "\n"
         "#define COLLUNSAFE_ICU_VERSION \"" U_ICU_VERSION "\"\n");
  printf("#define COLLUNSAFE_COLL_VERSION \"%s\"\n", verString);

  
  
#if PATTERN
  printf("#define COLLUNSAFE_PATTERN 1\n");
  printf("static const int32_t collunsafe_len = %d;\n", needed);
  printf("static const UChar collunsafe_pattern[collunsafe_len] = {\n");
  for(int i=0;i<needed;i++) {
    if( (i>0) && (i%8 == 0) ) {
      printf(" // %d\n", i);
    }
    printf("0x%04X", buf[i]); // TODO check
    if(i != (needed-1)) {
      printf(", ");
    }
    }
  printf(" //%d\n};\n", (needed-1));
#endif

#if RANGE
    fprintf(stderr, "COLLUNSAFE_RANGE - no code support in collationdatareader.cpp for this\n");
    printf("#define COLLUNSAFE_RANGE 1\n");
    printf("static const int32_t unsafe_rangeCount = %d;\n", rangeCount);
    printf("static const UChar32 unsafe_ranges[%d] = { \n", rangeCount*2);
    for(int32_t i=0;i<rangeCount;i++) {
      printf(" 0x%04X, 0x%04X, // %d\n",
             unsafeBackwardSet->getRangeStart(i),
             unsafeBackwardSet->getRangeEnd(i),
             i);
    }
    printf("};\n");
#endif

#if SERIALIZE
    printf("#define COLLUNSAFE_SERIALIZE 1\n");    
    printf("static const int32_t unsafe_serializedCount = %d;\n", serializedCount);
    printf("static const uint16_t unsafe_serializedData[%d] = { \n", serializedCount);
    for(int32_t i=0;i<serializedCount;i++) {
      if( (i>0) && (i%8 == 0) ) {
        printf(" // %d\n", i);
      }
      printf("0x%04X", serializedData[i]); // TODO check
      if(i != (serializedCount-1)) {
        printf(", ");
      }
    }  
    printf("};\n");
#endif
    
    printf("#endif\n");
    fflush(stderr);
    fflush(stdout);
    return(U_SUCCESS(errorCode)?0:1);
}
