/********************************************************************
* COPYRIGHT:
* Copyright (C) 2001-2012 IBM, Inc.   All Rights Reserved.
*
********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <limits.h>
#include <string.h>
#include "unicode/uperf.h"
#include "uoptions.h"
#include "unicode/coll.h"
#include <unicode/ucoleitr.h>

#if !U_PLATFORM_HAS_WIN32_API
#define DWORD uint32_t
#define WCHAR wchar_t
#endif

/* To store an array of string<UNIT> in continue space.
Since string<UNIT> itself is treated as an array of UNIT, this 
class will ease our memory management for an array of string<UNIT>.
*/

//template<typename UNIT> 
#define COMPATCT_ARRAY(CompactArrays, UNIT) \
struct CompactArrays{\
    CompactArrays(const CompactArrays & );\
    CompactArrays & operator=(const CompactArrays & );\
    int32_t   count;/*total number of the strings*/ \
    int32_t * index;/*relative offset in data*/ \
    UNIT    * data; /*the real space to hold strings*/ \
    \
    ~CompactArrays(){free(index);free(data);} \
    CompactArrays():data(NULL), index(NULL), count(0){ \
    index = (int32_t *) realloc(index, sizeof(int32_t)); \
    index[0] = 0; \
    } \
    void append_one(int32_t theLen){ /*include terminal NULL*/ \
    count++; \
    index = (int32_t *) realloc(index, sizeof(int32_t) * (count + 1)); \
    index[count] = index[count - 1] + theLen; \
    data = (UNIT *) realloc(data, sizeof(UNIT) * index[count]); \
    } \
    UNIT * last(){return data + index[count - 1];} \
    UNIT * dataOf(int32_t i){return data + index[i];} \
    int32_t lengthOf(int i){return index[i+1] - index[i] - 1; }	/*exclude terminating NULL*/  \
};

//typedef CompactArrays<UChar> CA_uchar;
//typedef CompactArrays<char> CA_char;
//typedef CompactArrays<uint8_t> CA_uint8;
//typedef CompactArrays<WCHAR> CA_win_wchar;

COMPATCT_ARRAY(CA_uchar, UChar)
COMPATCT_ARRAY(CA_char, char)
COMPATCT_ARRAY(CA_uint8, uint8_t)
COMPATCT_ARRAY(CA_win_wchar, WCHAR)


struct DataIndex {
    static DWORD        win_langid;     // for qsort callback function
    static UCollator *  col;            // for qsort callback function
    uint8_t *   icu_key;
    UChar *     icu_data;
    int32_t     icu_data_len;
    char*       posix_key;
    char*       posix_data;
    int32_t     posix_data_len;
    char*       win_key;
    WCHAR *     win_data;
    int32_t     win_data_len;
};
DWORD DataIndex::win_langid;
UCollator * DataIndex::col;



class CmdKeyGen : public UPerfFunction {
    typedef	void (CmdKeyGen::* Func)(int32_t);
    enum{MAX_KEY_LENGTH = 5000};
    UCollator * col;
    DWORD       win_langid;
    int32_t     count;
    DataIndex * data;
    Func 	    fn; 

    union { // to save sapce
        uint8_t		icu_key[MAX_KEY_LENGTH];
        char        posix_key[MAX_KEY_LENGTH];
        WCHAR		win_key[MAX_KEY_LENGTH];
    };
public:
    CmdKeyGen(UErrorCode, UCollator * col,DWORD win_langid, int32_t count, DataIndex * data,Func fn,int32_t)
        :col(col),win_langid(win_langid), count(count), data(data), fn(fn){}

        virtual long getOperationsPerIteration(){return count;}

        virtual void call(UErrorCode* status){
            for(int32_t i = 0; i< count; i++){
                (this->*fn)(i);
            }
        }

        void icu_key_null(int32_t i){
            ucol_getSortKey(col, data[i].icu_data, -1, icu_key, MAX_KEY_LENGTH);
        }

        void icu_key_len(int32_t i){
            ucol_getSortKey(col, data[i].icu_data, data[i].icu_data_len, icu_key, MAX_KEY_LENGTH);
        }

#if U_PLATFORM_HAS_WIN32_API
        // pre-generated in CollPerfTest::prepareData(), need not to check error here
        void win_key_null(int32_t i){
            //LCMAP_SORTsk             0x00000400  // WC sort sk (normalize)
            LCMapStringW(win_langid, LCMAP_SORTKEY, data[i].win_data, -1, win_key, MAX_KEY_LENGTH);
        }

        void win_key_len(int32_t i){
            LCMapStringW(win_langid, LCMAP_SORTKEY, data[i].win_data, data[i].win_data_len, win_key, MAX_KEY_LENGTH);
        }
#endif

        void posix_key_null(int32_t i){
            strxfrm(posix_key, data[i].posix_data, MAX_KEY_LENGTH);
        }
};


class CmdIter : public UPerfFunction {
    typedef	void (CmdIter::* Func)(UErrorCode* , int32_t );
    int32_t             count;
    CA_uchar *          data;
    Func                fn;
    UCollationElements *iter;
    int32_t             exec_count;
public:
    CmdIter(UErrorCode & status, UCollator * col, int32_t count, CA_uchar *data, Func fn, int32_t,int32_t)
        :count(count), data(data), fn(fn){
            exec_count = 0;
            UChar dummytext[] = {0, 0};
            iter = ucol_openElements(col, NULL, 0, &status);
            ucol_setText(iter, dummytext, 1, &status);
        }
        ~CmdIter(){
            ucol_closeElements(iter);
        }

        virtual long getOperationsPerIteration(){return exec_count ? exec_count : 1;}

        virtual void call(UErrorCode* status){
            exec_count = 0;
            for(int32_t i = 0; i< count; i++){
                (this->*fn)(status, i);
            }
        }

        void icu_forward_null(UErrorCode* status, int32_t i){
            ucol_setText(iter, data->dataOf(i), -1, status);
            while (ucol_next(iter, status) != UCOL_NULLORDER) exec_count++;
        }

        void icu_forward_len(UErrorCode* status, int32_t i){
            ucol_setText(iter, data->dataOf(i), data->lengthOf(i) , status);
            while (ucol_next(iter, status) != UCOL_NULLORDER) exec_count++;
        }

        void icu_backward_null(UErrorCode* status, int32_t i){
            ucol_setText(iter, data->dataOf(i), -1, status);
            while (ucol_previous(iter, status) != UCOL_NULLORDER) exec_count++;
        }

        void icu_backward_len(UErrorCode* status, int32_t i){
            ucol_setText(iter, data->dataOf(i), data->lengthOf(i) , status);
            while (ucol_previous(iter, status) != UCOL_NULLORDER) exec_count++;
        }
};

class CmdIterAll : public UPerfFunction {
    typedef	void (CmdIterAll::* Func)(UErrorCode* status);
    int32_t     count;
    UChar *     data;
    Func        fn;
    UCollationElements *iter;
    int32_t     exec_count;

public:
    enum CALL {forward_null, forward_len, backward_null, backward_len};

    ~CmdIterAll(){
        ucol_closeElements(iter);
    }
    CmdIterAll(UErrorCode & status, UCollator * col, int32_t count,  UChar * data, CALL call,int32_t,int32_t)
        :count(count),data(data)
    {
        exec_count = 0;
        if (call == forward_null || call == backward_null) {
            iter = ucol_openElements(col, data, -1, &status);
        } else {
            iter = ucol_openElements(col, data, count, &status);
        }

        if (call == forward_null || call == forward_len){
            fn = &CmdIterAll::icu_forward_all;
        } else {
            fn = &CmdIterAll::icu_backward_all;
        }
    }
    virtual long getOperationsPerIteration(){return exec_count ? exec_count : 1;}

    virtual void call(UErrorCode* status){
        (this->*fn)(status);
    }

    void icu_forward_all(UErrorCode* status){
        int strlen = count - 5;
        int count5 = 5;
        int strindex = 0;
        ucol_setOffset(iter, strindex, status);
        while (TRUE) {
            if (ucol_next(iter, status) == UCOL_NULLORDER) {
                break;
            }
            exec_count++;
            count5 --;
            if (count5 == 0) {
                strindex += 10;
                if (strindex > strlen) {
                    break;
                }
                ucol_setOffset(iter, strindex, status);
                count5 = 5;
            }
        }
    }

    void icu_backward_all(UErrorCode* status){
        int strlen = count;
        int count5 = 5;
        int strindex = 5;
        ucol_setOffset(iter, strindex, status);
        while (TRUE) {
            if (ucol_previous(iter, status) == UCOL_NULLORDER) {
                break;
            }
            exec_count++;
            count5 --;
            if (count5 == 0) {
                strindex += 10;
                if (strindex > strlen) {
                    break;
                }
                ucol_setOffset(iter, strindex, status);
                count5 = 5;
            }
        }
    }

};

struct CmdQsort : public UPerfFunction{

    static int q_random(const void * a, const void * b){
        uint8_t * key_a = ((DataIndex *)a)->icu_key;
        uint8_t * key_b = ((DataIndex *)b)->icu_key;

        int   val_a = 0;
        int   val_b = 0;
        while (*key_a != 0) {val_a += val_a*37 + *key_a++;}
        while (*key_b != 0) {val_b += val_b*37 + *key_b++;}
        return val_a - val_b;
    }

#define QCAST() \
    DataIndex * da = (DataIndex *) a; \
    DataIndex * db = (DataIndex *) b; \
    ++exec_count

    static int icu_strcoll_null(const void *a, const void *b){
        QCAST(); 
        return ucol_strcoll(da->col, da->icu_data, -1, db->icu_data, -1) - UCOL_EQUAL;
    }

    static int icu_strcoll_len(const void *a, const void *b){
        QCAST();
        return ucol_strcoll(da->col, da->icu_data, da->icu_data_len, db->icu_data, db->icu_data_len) - UCOL_EQUAL;
    }

    static int icu_cmpkey (const void *a, const void *b){ 
        QCAST(); 
        return strcmp((char *) da->icu_key, (char *) db->icu_key); 
    }

#if U_PLATFORM_HAS_WIN32_API
    static int win_cmp_null(const void *a, const void *b) {
        QCAST();
        //CSTR_LESS_THAN		1
        //CSTR_EQUAL			2
        //CSTR_GREATER_THAN		3
        int t = CompareStringW(da->win_langid, 0, da->win_data, -1, db->win_data, -1);
        if (t == 0){
            fprintf(stderr, "CompareStringW error, error number %x\n", GetLastError());
            exit(-1);
        } else{
            return t - CSTR_EQUAL;
        }
    }

    static int win_cmp_len(const void *a, const void *b) {
        QCAST();
        int t = CompareStringW(da->win_langid, 0, da->win_data, da->win_data_len, db->win_data, db->win_data_len);
        if (t == 0){
            fprintf(stderr, "CompareStringW error, error number %x\n", GetLastError());
            exit(-1);
        } else{
            return t - CSTR_EQUAL;
        }
    }
#endif

#define QFUNC(name, func, data) \
    static int name (const void *a, const void *b){ \
    QCAST(); \
    return func(da->data, db->data); \
    }

    QFUNC(posix_strcoll_null, strcoll, posix_data)
        QFUNC(posix_cmpkey, strcmp, posix_key)
#if U_PLATFORM_HAS_WIN32_API
        QFUNC(win_cmpkey, strcmp, win_key)
        QFUNC(win_wcscmp, wcscmp, win_data)
#endif
        QFUNC(icu_strcmp, u_strcmp, icu_data)
        QFUNC(icu_cmpcpo, u_strcmpCodePointOrder, icu_data)

private:        
    static int32_t exec_count; // potential muilt-thread problem

    typedef	int (* Func)(const void *, const void *);

    Func    fn;
    void *  base;   //Start of target array. 
    int32_t num;    //Array size in elements. 
    int32_t width;  //Element size in bytes. 

    void *  backup; //copy source of base
public:
    CmdQsort(UErrorCode & status,void *theBase, int32_t num, int32_t width, Func fn, int32_t,int32_t)
        :backup(theBase),num(num),width(width),fn(fn){
            base = malloc(num * width);
            time_empty(100, &status); // warm memory/cache
        }

        ~CmdQsort(){
            free(base);
        }

        void empty_call(){
            exec_count = 0;
            memcpy(base, backup, num * width);
        }

        double time_empty(int32_t n, UErrorCode* status) {
            UTimer start, stop;
            utimer_getTime(&start); 
            while (n-- > 0) {
                empty_call();
            }
            utimer_getTime(&stop);
            return utimer_getDeltaSeconds(&start,&stop); // ms
        }

        virtual void call(UErrorCode* status){
            exec_count = 0;
            memcpy(base, backup, num * width);
            qsort(base, num, width, fn);
        }
        virtual double time(int32_t n, UErrorCode* status) {
            double t1 = time_empty(n,status);
            double t2 = UPerfFunction::time(n, status);
            return  t2-t1;// < 0 ? t2 : t2-t1;
        }

        virtual long getOperationsPerIteration(){ return exec_count?exec_count:1;}
};
int32_t CmdQsort::exec_count;


class CmdBinSearch : public UPerfFunction{
public:
    typedef	int (CmdBinSearch::* Func)(int, int);

    UCollator * col;
    DWORD       win_langid;
    int32_t     count;
    DataIndex * rnd;
    DataIndex * ord;
    Func 	    fn;
    int32_t     exec_count;

    CmdBinSearch(UErrorCode, UCollator * col,DWORD win_langid,int32_t count,DataIndex * rnd,DataIndex * ord,Func fn)
        :col(col),win_langid(win_langid), count(count), rnd(rnd), ord(ord), fn(fn),exec_count(0){}


        virtual void call(UErrorCode* status){
            exec_count = 0;
            for(int32_t i = 0; i< count; i++){ // search all data
                binary_search(i);
            }
        }
        virtual long getOperationsPerIteration(){ return exec_count?exec_count:1;}

        void binary_search(int32_t random)	{
            int low   = 0;
            int high  = count - 1;
            int guess;
            int last_guess = -1;
            int r;
            while (TRUE) {
                guess = (high + low)/2;
                if (last_guess == guess) break; // nothing to search

                r = (this->*fn)(random, guess);
                exec_count++;

                if (r == 0)	
                    return;	// found, search end.
                if (r < 0) {
                    high = guess;
                } else {
                    low  = guess;
                }
                last_guess = guess;
            } 
        }

        int icu_strcoll_null(int32_t i, int32_t j){
            return ucol_strcoll(col, rnd[i].icu_data, -1, ord[j].icu_data,-1);
        }

        int icu_strcoll_len(int32_t i, int32_t j){
            return ucol_strcoll(col, rnd[i].icu_data, rnd[i].icu_data_len, ord[j].icu_data, ord[j].icu_data_len);
        }

        int icu_cmpkey(int32_t i, int32_t j) {
            return strcmp( (char *) rnd[i].icu_key, (char *) ord[j].icu_key );
        }

#if U_PLATFORM_HAS_WIN32_API
        int win_cmp_null(int32_t i, int32_t j) {
            int t = CompareStringW(win_langid, 0, rnd[i].win_data, -1, ord[j].win_data, -1);
            if (t == 0){
                fprintf(stderr, "CompareStringW error, error number %x\n", GetLastError());
                exit(-1);
            } else{
                return t - CSTR_EQUAL;
            }
        }

        int win_cmp_len(int32_t i, int32_t j) {
            int t = CompareStringW(win_langid, 0, rnd[i].win_data, rnd[i].win_data_len, ord[j].win_data, ord[j].win_data_len);
            if (t == 0){
                fprintf(stderr, "CompareStringW error, error number %x\n", GetLastError());
                exit(-1);
            } else{
                return t - CSTR_EQUAL;
            }
        }
#endif

#define BFUNC(name, func, data) \
    int name(int32_t i, int32_t j) { \
    return func(rnd[i].data, ord[j].data); \
    }

        BFUNC(posix_strcoll_null, strcoll, posix_data)
            BFUNC(posix_cmpkey, strcmp, posix_key)
            BFUNC(win_cmpkey, strcmp, win_key)
            BFUNC(win_wcscmp, wcscmp, win_data)
            BFUNC(icu_strcmp, u_strcmp, icu_data)
            BFUNC(icu_cmpcpo, u_strcmpCodePointOrder, icu_data)
};

class CollPerfTest : public UPerfTest {
public:
    UCollator *     col;
    DWORD           win_langid;

    UChar * icu_data_all;
    int32_t icu_data_all_len;

    int32_t         count;
    CA_uchar *      icu_data;
    CA_uint8 *      icu_key;
    CA_char *       posix_data;
    CA_char *       posix_key;
    CA_win_wchar *  win_data;
    CA_char *       win_key;

    DataIndex * rnd_index; // random by icu key
    DataIndex * ord_win_data;
    DataIndex * ord_win_key;
    DataIndex * ord_posix_data;
    DataIndex * ord_posix_key;
    DataIndex * ord_icu_data;
    DataIndex * ord_icu_key;
    DataIndex * ord_win_wcscmp;
    DataIndex * ord_icu_strcmp;
    DataIndex * ord_icu_cmpcpo;

    virtual ~CollPerfTest(){
        ucol_close(col);
        delete [] icu_data_all;
        delete icu_data;
        delete icu_key;
        delete posix_data;
        delete posix_key;
        delete win_data;
        delete win_key;
        delete[] rnd_index;
        delete[] ord_win_data;
        delete[] ord_win_key;
        delete[] ord_posix_data;
        delete[] ord_posix_key;
        delete[] ord_icu_data;
        delete[] ord_icu_key;
        delete[] ord_win_wcscmp;
        delete[] ord_icu_strcmp;
        delete[] ord_icu_cmpcpo;
    }

    CollPerfTest(int32_t argc, const char* argv[], UErrorCode& status):UPerfTest(argc, argv, status){
        col = NULL;
        icu_data_all = NULL;
        icu_data = NULL;
        icu_key = NULL;
        posix_data = NULL;
        posix_key = NULL;
        win_data =NULL;
        win_key = NULL;

        rnd_index = NULL;
        ord_win_data= NULL;
        ord_win_key= NULL;
        ord_posix_data= NULL;
        ord_posix_key= NULL;
        ord_icu_data= NULL;
        ord_icu_key= NULL;
        ord_win_wcscmp = NULL;
        ord_icu_strcmp = NULL;
        ord_icu_cmpcpo = NULL;

        if (U_FAILURE(status)){
            return;
        }

        // Parse additional arguments

        UOption options[] = {
            UOPTION_DEF("langid", 'i', UOPT_REQUIRES_ARG),        // Windows Language ID number.
                UOPTION_DEF("rulefile", 'r', UOPT_REQUIRES_ARG),      // --rulefile <filename>
                // Collation related arguments. All are optional.
                // To simplify parsing, two choice arguments are disigned as NO_ARG.
                // The default value is UPPER word in the comment
                UOPTION_DEF("c_french", 'f', UOPT_NO_ARG),          // --french <on | OFF>
                UOPTION_DEF("c_alternate", 'a', UOPT_NO_ARG),       // --alternate <NON_IGNORE | shifted>
                UOPTION_DEF("c_casefirst", 'c', UOPT_REQUIRES_ARG), // --casefirst <lower | upper | OFF>
                UOPTION_DEF("c_caselevel", 'l', UOPT_NO_ARG),       // --caselevel <on | OFF>
                UOPTION_DEF("c_normal", 'n', UOPT_NO_ARG),          // --normal <on | OFF> 
                UOPTION_DEF("c_strength", 's', UOPT_REQUIRES_ARG),  // --strength <1-5>
        };
        int32_t opt_len = (sizeof(options)/sizeof(options[0]));
        enum {i, r,f,a,c,l,n,s};   // The buffer between the option items' order and their references

        _remainingArgc = u_parseArgs(_remainingArgc, (char**)argv, opt_len, options);

        if (_remainingArgc < 0){
            status = U_ILLEGAL_ARGUMENT_ERROR;
            return;
        }

        if (locale == NULL){
            locale = "en_US";   // set default locale
        }

#if U_PLATFORM_HAS_WIN32_API
        if (options[i].doesOccur) {
            char *endp;
            int tmp = strtol(options[i].value, &endp, 0);
            if (endp == options[i].value) {
                status = U_ILLEGAL_ARGUMENT_ERROR;
                return;
            }
            win_langid = MAKELCID(tmp, SORT_DEFAULT);
        } else {
            win_langid = uloc_getLCID(locale);
        }
#endif

        //  Set up an ICU collator
        if (options[r].doesOccur) {
            // TODO: implement it
        } else {
            col = ucol_open(locale, &status);
            if (U_FAILURE(status)) {
                return;
            }
        }

        if (options[f].doesOccur) {
            ucol_setAttribute(col, UCOL_FRENCH_COLLATION, UCOL_ON, &status);
        } else {
            ucol_setAttribute(col, UCOL_FRENCH_COLLATION, UCOL_OFF, &status);
        }

        if (options[a].doesOccur) {
            ucol_setAttribute(col, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &status);
        }

        if (options[c].doesOccur) { // strcmp() has i18n encoding problem
            if (strcmp("lower", options[c].value) == 0){
                ucol_setAttribute(col, UCOL_CASE_FIRST, UCOL_LOWER_FIRST, &status);
            } else if (strcmp("upper", options[c].value) == 0) {
                ucol_setAttribute(col, UCOL_CASE_FIRST, UCOL_UPPER_FIRST, &status);
            } else {
                status = U_ILLEGAL_ARGUMENT_ERROR;
                return;
            }
        }

        if (options[l].doesOccur){
            ucol_setAttribute(col, UCOL_CASE_LEVEL, UCOL_ON, &status);
        }

        if (options[n].doesOccur){
            ucol_setAttribute(col, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
        }

        if (options[s].doesOccur) {
            char *endp;
            int tmp = strtol(options[l].value, &endp, 0);
            if (endp == options[l].value) {
                status = U_ILLEGAL_ARGUMENT_ERROR;
                return;
            }
            switch (tmp) {
            case 1:	ucol_setAttribute(col, UCOL_STRENGTH, UCOL_PRIMARY, &status);		break;
            case 2:	ucol_setAttribute(col, UCOL_STRENGTH, UCOL_SECONDARY, &status);		break;
            case 3:	ucol_setAttribute(col, UCOL_STRENGTH, UCOL_TERTIARY, &status);		break;
            case 4:	ucol_setAttribute(col, UCOL_STRENGTH, UCOL_QUATERNARY, &status);	break;
            case 5:	ucol_setAttribute(col, UCOL_STRENGTH, UCOL_IDENTICAL, &status);		break;
            default: status = U_ILLEGAL_ARGUMENT_ERROR;					return;
            }
        }
        prepareData(status);
    }

    //to avoid use the annoying 'id' in TESTCASE(id,test) macro or the like
#define TEST(testname, classname, arg1, arg2, arg3, arg4, arg5, arg6) \
    if(temp == index) {\
    name = #testname;\
    if (exec) {\
    UErrorCode status = U_ZERO_ERROR;\
    UPerfFunction * t = new classname(status,arg1, arg2, arg3, arg4, arg5, arg6);\
    if (U_FAILURE(status)) {\
    delete t;\
    return NULL;\
    } else {\
    return t;\
    }\
    } else {\
    return NULL;\
    }\
    }\
    temp++\


    virtual UPerfFunction* runIndexedTest( /*[in]*/int32_t index, /*[in]*/UBool exec, /*[out]*/const char* &name, /*[in]*/ char* par = NULL ){
        int temp = 0;

#define TEST_KEYGEN(testname, func)\
    TEST(testname, CmdKeyGen, col, win_langid, count, rnd_index, &CmdKeyGen::func, 0)
        TEST_KEYGEN(TestIcu_KeyGen_null, icu_key_null);
        TEST_KEYGEN(TestIcu_KeyGen_len,  icu_key_len);
        TEST_KEYGEN(TestPosix_KeyGen_null, posix_key_null);
#if U_PLATFORM_HAS_WIN32_API
        TEST_KEYGEN(TestWin_KeyGen_null, win_key_null);
        TEST_KEYGEN(TestWin_KeyGen_len, win_key_len);
#endif

#define TEST_ITER(testname, func)\
    TEST(testname, CmdIter, col, count, icu_data, &CmdIter::func,0,0)
        TEST_ITER(TestIcu_ForwardIter_null, icu_forward_null);
        TEST_ITER(TestIcu_ForwardIter_len, icu_forward_len);
        TEST_ITER(TestIcu_BackwardIter_null, icu_backward_null);
        TEST_ITER(TestIcu_BackwardIter_len, icu_backward_len);

#define TEST_ITER_ALL(testname, func)\
    TEST(testname, CmdIterAll, col, icu_data_all_len, icu_data_all, CmdIterAll::func,0,0)
        TEST_ITER_ALL(TestIcu_ForwardIter_all_null, forward_null);
        TEST_ITER_ALL(TestIcu_ForwardIter_all_len, forward_len);
        TEST_ITER_ALL(TestIcu_BackwardIter_all_null, backward_null);
        TEST_ITER_ALL(TestIcu_BackwardIter_all_len, backward_len);

#define TEST_QSORT(testname, func)\
    TEST(testname, CmdQsort, rnd_index, count, sizeof(DataIndex), CmdQsort::func,0,0)
        TEST_QSORT(TestIcu_qsort_strcoll_null, icu_strcoll_null);
        TEST_QSORT(TestIcu_qsort_strcoll_len, icu_strcoll_len);
        TEST_QSORT(TestIcu_qsort_usekey, icu_cmpkey);
        TEST_QSORT(TestPosix_qsort_strcoll_null, posix_strcoll_null);
        TEST_QSORT(TestPosix_qsort_usekey, posix_cmpkey);
#if U_PLATFORM_HAS_WIN32_API
        TEST_QSORT(TestWin_qsort_CompareStringW_null, win_cmp_null);
        TEST_QSORT(TestWin_qsort_CompareStringW_len, win_cmp_len);
        TEST_QSORT(TestWin_qsort_usekey, win_cmpkey);
#endif

#define TEST_BIN(testname, func)\
    TEST(testname, CmdBinSearch, col, win_langid, count, rnd_index, ord_icu_key, &CmdBinSearch::func)
        TEST_BIN(TestIcu_BinarySearch_strcoll_null, icu_strcoll_null);
        TEST_BIN(TestIcu_BinarySearch_strcoll_len, icu_strcoll_len);
        TEST_BIN(TestIcu_BinarySearch_usekey, icu_cmpkey);
        TEST_BIN(TestIcu_BinarySearch_strcmp, icu_strcmp);
        TEST_BIN(TestIcu_BinarySearch_cmpCPO, icu_cmpcpo);
        TEST_BIN(TestPosix_BinarySearch_strcoll_null, posix_strcoll_null);
        TEST_BIN(TestPosix_BinarySearch_usekey, posix_cmpkey);
#if U_PLATFORM_HAS_WIN32_API
        TEST_BIN(TestWin_BinarySearch_CompareStringW_null, win_cmp_null);
        TEST_BIN(TestWin_BinarySearch_CompareStringW_len, win_cmp_len);
#endif
        TEST_BIN(TestWin_BinarySearch_usekey, win_cmpkey);
        TEST_BIN(TestWin_BinarySearch_wcscmp, win_wcscmp);

        name="";
        return NULL;
    }



    void prepareData(UErrorCode& status){
        if(U_FAILURE(status)) return;
        if (icu_data) return; // prepared

        icu_data = new CA_uchar();

        // Following code is borrowed from UPerfTest::getLines();
        const UChar*    line=NULL;
        int32_t         len =0;
        for (;;) {
            line = ucbuf_readline(ucharBuf,&len,&status);
            if(line == NULL || U_FAILURE(status)){break;}

            // Refer to the source code of ucbuf_readline()
            // 1. 'len' includs the line terminal symbols
            // 2. The length of the line terminal symbols is only one character
            // 3. The Windows CR LF line terminal symbols will be converted to CR

            if (len == 1) {
                continue; //skip empty line
            } else {
                icu_data->append_one(len);
                memcpy(icu_data->last(), line, len * sizeof(UChar));
                icu_data->last()[len -1] = NULL;
            }
        }
        if(U_FAILURE(status)) return;

        // UTF-16 -> UTF-8 conversion.
        UConverter   *conv = ucnv_open("utf-8", &status); // just UTF-8 for now.
        if (U_FAILURE(status)) return;

        count = icu_data->count;

        icu_data_all_len =  icu_data->index[count]; // includes all NULLs
        icu_data_all_len -= count;  // excludes all NULLs
        icu_data_all_len += 1;      // the terminal NULL
        icu_data_all = new UChar[icu_data_all_len];
        icu_data_all[icu_data_all_len - 1] = 0; //the terminal NULL

        icu_key  = new CA_uint8;
        win_data = new CA_win_wchar;
        win_key  = new CA_char;
        posix_data = new CA_char;
        posix_key = new CA_char;
        rnd_index = new DataIndex[count];
        DataIndex::win_langid = win_langid;
        DataIndex::col        = col;


        UChar * p = icu_data_all;
        int32_t s;
        int32_t t;
        for (int i=0; i < count; i++) {
            // ICU all data
            s = sizeof(UChar) * icu_data->lengthOf(i);
            memcpy(p, icu_data->dataOf(i), s);
            p += icu_data->lengthOf(i);

            // ICU data

            // ICU key
            s = ucol_getSortKey(col, icu_data->dataOf(i), -1,NULL, 0);
            icu_key->append_one(s);
            t = ucol_getSortKey(col, icu_data->dataOf(i), -1,icu_key->last(), s);
            if (t != s) {status = U_INVALID_FORMAT_ERROR;return;}

            // POSIX data
            s = ucnv_fromUChars(conv,NULL, 0, icu_data->dataOf(i), icu_data->lengthOf(i), &status);
            if (status == U_BUFFER_OVERFLOW_ERROR || status == U_ZERO_ERROR){
                status = U_ZERO_ERROR;
            } else {
                return;
            }
            posix_data->append_one(s + 1); // plus terminal NULL
            t = ucnv_fromUChars(conv,posix_data->last(), s, icu_data->dataOf(i), icu_data->lengthOf(i), &status);
            if (U_FAILURE(status)) return;
            if ( t != s){status = U_INVALID_FORMAT_ERROR;return;}
            posix_data->last()[s] = 0;

            // POSIX key
            s = strxfrm(NULL, posix_data->dataOf(i), 0);
            if (s == INT_MAX){status = U_INVALID_FORMAT_ERROR;return;}
            posix_key->append_one(s);
            t = strxfrm(posix_key->last(), posix_data->dataOf(i), s);
            if (t != s) {status = U_INVALID_FORMAT_ERROR;return;}

#if U_PLATFORM_HAS_WIN32_API
            // Win data
            s = icu_data->lengthOf(i) + 1; // plus terminal NULL
            win_data->append_one(s);
            memcpy(win_data->last(), icu_data->dataOf(i), sizeof(WCHAR) * s);

            // Win key
            s = LCMapStringW(win_langid, LCMAP_SORTKEY, win_data->dataOf(i), win_data->lengthOf(i), NULL,0);
            if (s == 0) {status = U_INVALID_FORMAT_ERROR;return;}
            win_key->append_one(s);
            t = LCMapStringW(win_langid, LCMAP_SORTKEY, win_data->dataOf(i), win_data->lengthOf(i), (WCHAR *)(win_key->last()),s);
            if (t != s) {status = U_INVALID_FORMAT_ERROR;return;}
#endif
        };

        // append_one() will make points shifting, should not merge following code into previous iteration
        for (int i=0; i < count; i++) {
            rnd_index[i].icu_key = icu_key->dataOf(i);
            rnd_index[i].icu_data = icu_data->dataOf(i);
            rnd_index[i].icu_data_len = icu_data->lengthOf(i);
            rnd_index[i].posix_key = posix_key->last();
            rnd_index[i].posix_data = posix_data->dataOf(i);
            rnd_index[i].posix_data_len = posix_data->lengthOf(i);
#if U_PLATFORM_HAS_WIN32_API
            rnd_index[i].win_key = win_key->dataOf(i);
            rnd_index[i].win_data = win_data->dataOf(i);
            rnd_index[i].win_data_len = win_data->lengthOf(i);
#endif
        };

        ucnv_close(conv);
        qsort(rnd_index, count, sizeof(DataIndex), CmdQsort::q_random);

#define SORT(data, func) \
    data = new DataIndex[count];\
    memcpy(data, rnd_index, count * sizeof(DataIndex));\
    qsort(data, count, sizeof(DataIndex), CmdQsort::func)

        SORT(ord_icu_data, icu_strcoll_len);
        SORT(ord_icu_key, icu_cmpkey);
        SORT(ord_posix_data, posix_strcoll_null);
        SORT(ord_posix_key, posix_cmpkey);
#if U_PLATFORM_HAS_WIN32_API
        SORT(ord_win_data, win_cmp_len);
        SORT(ord_win_key, win_cmpkey);
        SORT(ord_win_wcscmp, win_wcscmp);
#endif
        SORT(ord_icu_strcmp, icu_strcmp);
        SORT(ord_icu_cmpcpo, icu_cmpcpo);
    }
};


int main(int argc, const char *argv[])
{

    UErrorCode status = U_ZERO_ERROR;
    CollPerfTest test(argc, argv, status);

    if (U_FAILURE(status)){
        printf("The error is %s\n", u_errorName(status));
        //TODO: print usage here
        return status;
    }

    if (test.run() == FALSE){
        fprintf(stderr, "FAILED: Tests could not be run please check the "
            "arguments.\n");
        return -1;
    }
    return 0;
}

