/********************************************************************
 * COPYRIGHT:
 * Copyright (C) 2001-2006 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>



/* 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);
	}

    // 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);
	}

	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 = icu_forward_all;
        } else {
            fn = 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); 
}

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;
    }
}

#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)
QFUNC(win_cmpkey, strcmp, win_key)
QFUNC(win_wcscmp, wcscmp, win_data)
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 );
	}

	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;
        }
	}

#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
        }

//#ifdef U_WINDOWS
        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);
        TEST_KEYGEN(TestWin_KeyGen_null, win_key_null);
        TEST_KEYGEN(TestWin_KeyGen_len, win_key_len);

        #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);
        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);
        
        #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);
        TEST_BIN(TestWin_BinarySearch_CompareStringW_null, win_cmp_null);
        TEST_BIN(TestWin_BinarySearch_CompareStringW_len, win_cmp_len);
        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;}

            // 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;}

	    };

        // 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);
            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);
        };

        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);
        SORT(ord_win_data, win_cmp_len);
        SORT(ord_win_key, win_cmpkey);
        SORT(ord_win_wcscmp, win_wcscmp);
        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;
}

