/*
*******************************************************************************
*
*   Copyright (C) 2009-2012, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*/

#ifndef COLL_FE_DEBUG
#define COLL_FE_DEBUG 0
#endif

#include <icuglue/icuglue.h>
#include <unicode/coll.h>
//#include <unicode/tblcoll.h>
#include <unicode/ucol.h>
#include <string.h>
#include <stdio.h>
#include "unicode/ustring.h"

#if COLL_FE_DEBUG
#define debugfprintf(x) fprintf x
#else
#define debugfprintf(x)
#endif

/*
 * Before ICU 50.0.2 (50m2) - there was a different collator signature.
 * see: ticket:9460 ticket:9346
 */
#if (U_ICU_VERSION_MAJOR_NUM < 50) || ((U_ICU_VERSION_MAJOR_NUM==50)&&(U_ICU_VERSION_MINOR_NUM==0)&&(U_ICU_VERSION_PATCHLEVEL_NUM<2))
#define PRE_50_0_2_COLLATOR
#define CONST_BEFORE_50_0_2 const
#define CONST_AFTER_50_0_2 
#define REF_AFTER_50_0_2
#else
/* "current" API */
#define CONST_BEFORE_50_0_2
#define CONST_AFTER_50_0_2 const
#define REF_AFTER_50_0_2 &
#endif

/**
 * Macro to define the Collator_glue_4_2 class 
 */
#define GLUE_VER(x) class GLUE_SYM_V( Collator, x ) : public Collator {  \
    \
  public:  static Collator *create(const Locale &loc, const char *ver); \
  private: UCollator *_this; GLUE_SYM_V( Collator, x ) ( UCollator* tn ) : _this(tn){} \
    virtual ~ GLUE_SYM_V ( Collator, x) ();                             \
  public:                                                               \
    virtual void* getDynamicClassID() const;                            \
    static void* getStaticClassID() ;                                   \
    virtual Collator* clone() const;                                    \
    virtual UCollationResult compare(const UnicodeString&, const UnicodeString&, UErrorCode&) const; \
    virtual UCollationResult compare(const UnicodeString&, const UnicodeString&, int32_t, UErrorCode&) const; \
    virtual UCollationResult compare(const UChar*, int32_t, const UChar*, int32_t, UErrorCode&) const; \
    virtual CollationKey& getCollationKey(const UnicodeString&, CollationKey&, UErrorCode&) const; \
    virtual CollationKey& getCollationKey(const UChar*, int32_t, CollationKey&, UErrorCode&) const; \
    virtual int32_t hashCode() const;                                   \
    virtual CONST_BEFORE_50_0_2 Locale getLocale(ULocDataLocaleType, UErrorCode&) const; \
    virtual ECollationStrength getStrength() const;                     \
    virtual void setStrength(ECollationStrength);                       \
    virtual void getVersion(uint8_t*) const;                            \
    virtual void setAttribute(UColAttribute, UColAttributeValue, UErrorCode&) ; \
    virtual UColAttributeValue getAttribute(UColAttribute, UErrorCode&) CONST_AFTER_50_0_2; \
    virtual uint32_t setVariableTop(const UChar*, int32_t, UErrorCode&); \
    virtual uint32_t setVariableTop(const UnicodeString REF_AFTER_50_0_2, UErrorCode&);        \
    virtual void setVariableTop(uint32_t, UErrorCode&);                 \
    virtual uint32_t getVariableTop(UErrorCode&) const;                 \
    virtual Collator* safeClone() CONST_AFTER_50_0_2 ;                                      \
    virtual int32_t getSortKey(const UnicodeString&, uint8_t*, int32_t) const; \
    virtual int32_t getSortKey(const UChar*, int32_t, uint8_t*, int32_t) const; \
  public: static int32_t countAvailable();                              \
  public: static int32_t appendAvailable(UnicodeString* strs, int32_t i, int32_t count); \
  public: virtual int32_t internalGetShortDefinitionString(const char *locale, char *buffer, int32_t capacity, UErrorCode &status) const; \
  };

/** ==================================== The following code runs inside the 'target' version (i.e. old ICU) ========== **/
#if defined ( ICUGLUE_VER )


// these from tblcoll.h
static Collator::ECollationStrength _getECollationStrength(
                                       const UCollationStrength &strength) 
{
    switch (strength)
    {
    case UCOL_PRIMARY :
        return Collator::PRIMARY;
    case UCOL_SECONDARY :
        return Collator::SECONDARY;
    case UCOL_TERTIARY :
        return Collator::TERTIARY;
    case UCOL_QUATERNARY :
        return Collator::QUATERNARY;
    default :
        return Collator::IDENTICAL;
    }
}

static UCollationStrength _getUCollationStrength(
                             const Collator::ECollationStrength &strength) 
{
    switch (strength)
    {
    case Collator::PRIMARY :
        return UCOL_PRIMARY;
    case Collator::SECONDARY :
        return UCOL_SECONDARY;
    case Collator::TERTIARY :
        return UCOL_TERTIARY;
    case Collator::QUATERNARY :
        return UCOL_QUATERNARY;
    default :
        return UCOL_IDENTICAL;
    }
}



/* code for some version */
#include <icuglue/gluren.h>

#include "oicu.h"

/* Expand GLUE_VER to define the class */
#ifdef GLUE_VER
GLUE_VER( ICUGLUE_VER )
#endif

GLUE_SYM ( Collator ) :: ~ GLUE_SYM(Collator) () {
#if COLL_FE_DEBUG
    fprintf(stderr, "VCF " ICUGLUE_VER_STR " ucol_close");
#endif
    OICU_ucol_close(_this);
}

#if 0
U_CFUNC int32_t U_CALLCONV
GLUE_SYM ( glue_calcSortKey) (const    UCollator    *coll,
        const    UChar        *source,
        int32_t        sourceLength,
        uint8_t        **result,
        uint32_t        resultLength,
        UBool allocateSKBuffer,
        UErrorCode *status);

#endif

Collator *
GLUE_SYM ( Collator ) :: create (const Locale &loc, const char */*ver*/) {
  // TODO: save 'ver' off.
    UErrorCode status = U_ZERO_ERROR;
    char locBuf[200];
    char kwvBuf[200];
    int32_t len = loc.getKeywordValue("collation", kwvBuf, 200, status);
    strcpy(locBuf,loc.getBaseName());
    if(len>0) {
        strcat(locBuf,"@collator=");
        strcat(locBuf,kwvBuf);
    }
    UCollator * uc =  OICU_ucol_open( locBuf, status);
    if(U_FAILURE(status)) return NULL; // TODO: ERR?
    Collator *c =  new GLUE_SYM( Collator ) ( uc );
#if COLL_FE_DEBUG
    fprintf(stderr, "VCF " ICUGLUE_VER_STR " ucol_open=%s ->> %p\n", locBuf, c);
#endif
    return c;
}

UOBJECT_DEFINE_RTTI_IMPLEMENTATION( GLUE_SYM( Collator ) )

Collator* GLUE_SYM ( Collator ) :: clone() const  {
    UErrorCode status = U_ZERO_ERROR;
#if COLL_FE_DEBUG
    fprintf(stderr, "VCF " ICUGLUE_VER_STR " clone %p -> " , this);
#endif
    UCollator *clc = OICU_ucol_safeClone( _this, NULL, 0, &status);
#if COLL_FE_DEBUG
    fprintf(stderr, "VCF " ICUGLUE_VER_STR " .. safeclone %s _this %p-> %p " , u_errorName(status), _this, clc);
#endif
    if(U_FAILURE(status)||clc==NULL) return NULL;
    Collator *c = new GLUE_SYM( Collator ) ( clc );
#if COLL_FE_DEBUG
    fprintf(stderr, "VCF " ICUGLUE_VER_STR " .. wrap(%p) -> %p\n", clc, c);
#endif

    return c;
}


UCollationResult GLUE_SYM ( Collator ) :: compare(const UnicodeString&, const UnicodeString&, UErrorCode&) const  {
    return (UCollationResult)0;
}


UCollationResult GLUE_SYM ( Collator ) :: compare(const UnicodeString&, const UnicodeString&, int32_t, UErrorCode&) const  {
    return (UCollationResult)0;
}


UCollationResult GLUE_SYM ( Collator ) :: compare(const UChar* s, int32_t sl, const UChar* d , int32_t dl, UErrorCode&/*e*/ ) const  {
    return OICU_ucol_strcoll(_this, s, sl, d, dl);
}

#include "unicode/sortkey.h"

static CollationKey kk;

CollationKey& GLUE_SYM ( Collator ) :: getCollationKey(const UnicodeString&, CollationKey&, UErrorCode&) const  {
  //#if COLL_FE_DEBUG
    fprintf(stderr,  "VCF " ICUGLUE_VER_STR " GCK - notimp");
    //#endif
return kk;
}


CollationKey& GLUE_SYM ( Collator ) :: getCollationKey(const UChar*, int32_t, CollationKey&, UErrorCode&) const  {
    fprintf(stderr,  "VCF " ICUGLUE_VER_STR " GKK2 - notimp");
return kk;
}


int32_t GLUE_SYM ( Collator ) :: hashCode() const  {
    return 0;
}


CONST_BEFORE_50_0_2 Locale GLUE_SYM ( Collator ) :: getLocale(ULocDataLocaleType, UErrorCode&) const  {
    return Locale();
}


Collator::ECollationStrength
 GLUE_SYM ( Collator ) :: getStrength() const  {
    return _getECollationStrength(OICU_ucol_getStrength(_this));
}


void GLUE_SYM ( Collator ) :: setStrength(ECollationStrength s)  {
    OICU_ucol_setStrength(_this, _getUCollationStrength(s));
}


void GLUE_SYM ( Collator ) :: getVersion(uint8_t*) const  {
}


void GLUE_SYM ( Collator ) :: setAttribute(UColAttribute, UColAttributeValue, UErrorCode&) {
}


UColAttributeValue GLUE_SYM ( Collator ) :: getAttribute(UColAttribute, UErrorCode&) CONST_AFTER_50_0_2 {
return (UColAttributeValue)0;
}


uint32_t GLUE_SYM ( Collator ) :: setVariableTop(const UChar*, int32_t, UErrorCode&)  {
return 0;
}


uint32_t GLUE_SYM ( Collator ) :: setVariableTop(const UnicodeString REF_AFTER_50_0_2, UErrorCode&)  {
return 0;
}


void GLUE_SYM ( Collator ) :: setVariableTop(uint32_t, UErrorCode&)  {
}


uint32_t GLUE_SYM ( Collator ) :: getVariableTop(UErrorCode&) const  {
return 0;
}


Collator* GLUE_SYM ( Collator ) :: safeClone() CONST_AFTER_50_0_2 {
    return clone();
}


int32_t GLUE_SYM ( Collator ) :: getSortKey(const UnicodeString& s, uint8_t*buf, int32_t len) const  {
#if COLL_FE_DEBUG
  fprintf(stderr,  "VCF " ICUGLUE_VER_STR " GSK");
#endif
    return getSortKey(s.getBuffer(),s.length(), buf, len);
}




int32_t GLUE_SYM ( Collator ) :: getSortKey(const UChar*s, int32_t l, uint8_t*d, int32_t b) const  {
#if COLL_FE_DEBUG
    fprintf(stderr,  "VCF " ICUGLUE_VER_STR " GKS");
#endif
    return OICU_ucol_getSortKey(_this, s,l,d,b);
}

int32_t GLUE_SYM (Collator ) ::  internalGetShortDefinitionString(const char *locale, char *buffer, int32_t capacity, UErrorCode &status) const {
  if(U_FAILURE(status)) return 0;
  int32_t intRes = OICU_ucol_getShortDefinitionString(_this, locale, buffer, capacity, &status);
  int32_t newRes = (intRes += 7); /* _PICU38 */
  int32_t remainCap = capacity - newRes;

  if(remainCap < 0 && U_SUCCESS(status)) {
    status = U_BUFFER_OVERFLOW_ERROR; /* ran out of space on our watch */
  }
  if(U_SUCCESS(status)) {
    char *p = buffer+strlen(buffer);
    strncat(p,"_PICU",5);
    p +=5 ;
    CPY_VERSTR(p, ICUGLUE_VER_STR);
    p +=2;
    if(remainCap>0) {
      *(p++)=0;
    }
  }
  return newRes;
}



 int32_t GLUE_SYM ( Collator ) :: countAvailable() {
    int32_t count =  OICU_ucol_countAvailable();
    return count;
 }
 
 
int32_t GLUE_SYM ( Collator ) :: appendAvailable(UnicodeString* strs, int32_t i, int32_t /*count*/) {
   int avail = OICU_ucol_countAvailable();
   UErrorCode status = U_ZERO_ERROR;
   OICU_u_init(&status);
#if COLL_FE_DEBUG
   fprintf(stderr,  "VCF " ICUGLUE_VER_STR " avail %d - init %s\n", avail, u_errorName(status));
#endif   
    for(int j=0;j<avail;j++) {
         strs[i+j].append(OICU_ucol_getAvailable(j));
         strs[i+j].append("@sp=icu");
         
         if(IS_OLD_VERSTR(ICUGLUE_VER_STR)) {
           strs[i+j].append( ICUGLUE_VER_STR[OLD_VERSTR_MAJ] );  // X_y
           strs[i+j].append( ICUGLUE_VER_STR[OLD_VERSTR_MIN] );  // x_Y
         } else {
           strs[i+j].append( ICUGLUE_VER_STR[NEW_VERSTR_MAJ] );  // Xy_
           strs[i+j].append( ICUGLUE_VER_STR[NEW_VERSTR_MIN] );  // xY_
         }

#if COLL_FE_DEBUG
         { 
            char foo[999];
            const UChar *ss = strs[i+j].getTerminatedBuffer();
            u_austrcpy(foo, ss);
            debugfprintf((stderr,  "VCF " ICUGLUE_VER_STR " appending [%d+%d=%d] <<%s>>\n", i, j, i+j, foo));
        }
#endif
    }
    return OICU_ucol_countAvailable();
 }



#else
/** ==================================== The following code runs inside the 'provider' version (i.e. current ICU) ========== **/

// define Collator_XX
#include "icuglue/glver.h"

// generate list of versions
static
#include <icuglue/fe_verlist.h>

class VersionCollatorFactory : public CollatorFactory {
public:
  virtual Collator *createCollator(const Locale &loc);
  virtual const UnicodeString *getSupportedIDs(int32_t &count, UErrorCode &status);
  virtual void* getDynamicClassID() const; 
  static void* getStaticClassID() ; 
};

UOBJECT_DEFINE_RTTI_IMPLEMENTATION( VersionCollatorFactory )

Collator *VersionCollatorFactory::createCollator(const Locale &loc) {
    // pull off provider #
    char provider[200];
    UErrorCode status = U_ZERO_ERROR;
#if COLL_FE_DEBUG
    fprintf(stderr,  "VCF:CC %s\n", loc.getName());
#endif
    int32_t len = loc.getKeywordValue("sp", provider, 200, status);
    if(U_FAILURE(status)||len==0) return NULL;
#if COLL_FE_DEBUG
    fprintf(stderr,  "VCF:KWV> %s/%d\n", u_errorName(status), len);
#endif
    provider[len]=0;
#if COLL_FE_DEBUG
    fprintf(stderr,  "VCF:KWV %s\n", provider);
#endif
    if(strncmp(provider,"icu",3)) return NULL;
    const char *icuver=provider+3;
#if COLL_FE_DEBUG
    fprintf(stderr,  "VCF:ICUV %s\n", icuver);
#endif
    
#if defined(GLUE_VER)
#undef GLUE_VER
#endif

#define GLUE_VER(x) \
    debugfprintf((stderr,"%c/%c|%c/%c\n", icuver[0],(#x)[0],icuver[1],(#x)[2]));  \
    if(CMP_VERSTR(icuver, (#x))) {                                      \
      Collator *c = glue ## Collator ## x :: create(loc, icuver); \
      debugfprintf((stderr, "VCF::CC %s -> %p\n", loc.getName(), c)); \
      return c; \
    }

#include "icuglue/glver.h"
#if COLL_FE_DEBUG
    fprintf(stderr,  "VCF:CC %s failed\n", loc.getName());
#endif

    return NULL;
}


static const UnicodeString *gLocales = NULL;
static  int32_t gLocCount = 0; 

const UnicodeString
*VersionCollatorFactory::getSupportedIDs(int32_t &count, UErrorCode &/*status*/) {
  if(gLocales==NULL) {
    count = 0;
    
    
    /* gather counts */
#if defined(GLUE_VER)
#undef GLUE_VER
#endif
#define GLUE_VER(x) count += glue ## Collator ## x :: countAvailable();
#include "icuglue/glver.h"

#if COLL_FE_DEBUG
    printf("VCF: count=%d\n", count);
#endif
    UnicodeString *strs = new  UnicodeString[count];
    int32_t i = 0;

#if defined(GLUE_VER)
#undef GLUE_VER
#endif
#define GLUE_VER(x) i += glue ## Collator ## x :: appendAvailable(strs, i, count);
#include "icuglue/glver.h"

#if COLL_FE_DEBUG
    printf("VCF: appended count=%d\n", count);
#endif

    gLocCount = count;
    gLocales = strs;
  }
  count = gLocCount;
  return gLocales;
}


/* Plugin Code */

#include <stdio.h>
#include <unicode/uversion.h>

static URegistryKey rk = NULL;

void coll_provider_register(UErrorCode &status) {
  rk = Collator::registerFactory(new VersionCollatorFactory(), status);
}

void coll_provider_unregister(UErrorCode &status) {
  Collator::unregister(rk, status);
}

/* Plugin- only ICU 4.4+ */
#if (U_ICU_VERSION_MAJOR_NUM > 4) || ((U_ICU_VERSION_MAJOR_NUM==4)&&(U_ICU_VERSION_MINOR_NUM>3))
#include "unicode/icuplug.h"

U_CAPI UPlugTokenReturn U_EXPORT2 coll_provider_plugin (UPlugData *data, UPlugReason reason, UErrorCode *status);

U_CAPI UPlugTokenReturn U_EXPORT2 coll_provider_plugin (UPlugData *data, UPlugReason reason, UErrorCode *status)
{
  switch(reason) {
  case UPLUG_REASON_QUERY:
    uplug_setPlugName(data, "Collation Provider Plugin");
    uplug_setPlugLevel(data, UPLUG_LEVEL_HIGH);
    break;
  case UPLUG_REASON_LOAD:
    coll_provider_register(*status);
    break;
  case UPLUG_REASON_UNLOAD:
    coll_provider_unregister(*status);
    break;
  default:
    break; /* not handled */
  }
  return UPLUG_TOKEN;
}
#else

/* 
   Note: this ICU version must explicitly call 'coll_provider_plugin'
*/

#endif /* plugin */

#endif /* provider side (vs target) */
