/*
**********************************************************************
* Copyright (c) 2002-2006, International Business Machines
* Corporation and others.  All Rights Reserved.
**********************************************************************
*/
#ifndef _STRINGPERF_H
#define _STRINGPERF_H

#include <string>

#include "unicode/utypes.h"
#include "unicode/unistr.h"

#include "unicode/uperf.h"

typedef std::wstring stlstring;	

/* Define all constants for test case operations */
#define MAXNUMLINES	40000	//Max number of lines in a test data file
#define MAXSRCLEN 20		//Max length of one line. maybe a larger number, but it need more mem
#define LOOPS 100			//Iterations
//#define LOOPS 10
#define catenate_STRLEN 2

const UChar uTESTCHAR1 =  'a';
const wchar_t wTESTCHAR1 = 'a';
const UnicodeString uEMPTY;
const stlstring sEMPTY;
UnicodeString unistr;
stlstring stlstr;
// Simulate construction with a single-char string for basic_string
wchar_t simulate[2]={wTESTCHAR1, 0};

/* Constants for scan operation */
U_STRING_DECL(scan_STRING, "Dot. 123. Some more data.", 25);
const UnicodeString uScan_STRING=UnicodeString(scan_STRING);
const stlstring sScan_STRING=stlstring(L"Dot. 123. Some more data.");

/* global variables or constants for concatenation operation */
U_STRING_DECL(uCatenate_STR, "!!", 2);
const stlstring sCatenate_STR=stlstring(L"!!");
static UnicodeString* catICU;
static stlstring* catStd;
UBool bCatenatePrealloc;

/* type defines */
typedef struct WLine WLine;
struct  WLine {
    wchar_t   name[100];
    int32_t   len;
}; //struct to store one line of wchar_t string

enum FnType { Fn_ICU, Fn_STD };
typedef FnType FnType;
typedef void (*ICUStringPerfFn)(const UChar* src,int32_t srcLen, UnicodeString s0);
typedef void (*StdStringPerfFn)(const wchar_t* src,int32_t srcLen, stlstring s0);


class StringPerfFunction : public UPerfFunction
{
public:

    virtual long getEventsPerIteration(){
        int loops = LOOPS;
        if (catICU) { delete catICU;}
        if (catStd) { delete catStd;}

        if (bCatenatePrealloc) {

            int to_alloc = loops * MAXNUMLINES * (MAXSRCLEN + catenate_STRLEN);
            catICU = new UnicodeString(to_alloc,'a',0);
            //catICU = new UnicodeString();

            catStd = new stlstring();
            //catStd -> reserve(loops * MAXNUMLINES * (MAXSRCLEN + catenate_STRLEN));
            catStd -> reserve(110000000);
        } else {
            catICU = new UnicodeString();
            catStd = new stlstring();
        }

        return -1;
    }

    virtual void call(UErrorCode* status)
    {
        if(line_mode_==TRUE){
            if(uselen_){
                for(int32_t i = 0; i< numLines_; i++){
                    if (fnType_==Fn_ICU) {
                        (*fn1_)(lines_[i].name,lines_[i].len,uS0_[i]);
                    } else {
                        (*fn2_)(wlines_[i].name,wlines_[i].len,sS0_[i]);
                    }
                }
            }else{
                for(int32_t i = 0; i< numLines_; i++){
                    if (fnType_==Fn_ICU) {
                        (*fn1_)(lines_[i].name,-1,uS0_[i]);
                    } else {
                        (*fn2_)(wlines_[i].name,-1,sS0_[i]);
                    }
                }
            }
        }else{
            if(uselen_){
                if (fnType_==Fn_ICU) {
                    (*fn1_)(src_,srcLen_,*ubulk_);
                } else {
                    (*fn2_)(wsrc_,wsrcLen_,*sbulk_);
                }
            }else{
                if (fnType_==Fn_ICU) {
                    (*fn1_)(src_,-1,*ubulk_);
                } else {
                    (*fn2_)(wsrc_,-1,*sbulk_);
                }
            }
        }
    }

    virtual long getOperationsPerIteration()
    {
        if(line_mode_==TRUE){
            return numLines_;
        }else{
            return 1;
        }
    }

    StringPerfFunction(ICUStringPerfFn func, ULine* srcLines, int32_t srcNumLines, UBool uselen)
    {

        fn1_ = func;
        lines_=srcLines;
        wlines_=NULL;
        numLines_=srcNumLines;
        uselen_=uselen;
        line_mode_=TRUE;
        src_ = NULL;
        srcLen_ = 0;
        wsrc_ = NULL;
        wsrcLen_ = 0;
        fnType_ = Fn_ICU;

        uS0_=new UnicodeString[numLines_];
        for(int32_t i=0; i<numLines_; i++) {
            uS0_[i]=UnicodeString(lines_[i].name, lines_[i].len);
        }
        sS0_=NULL;
        ubulk_=NULL;
        sbulk_=NULL;
    }

    StringPerfFunction(StdStringPerfFn func, ULine* srcLines, int32_t srcNumLines, UBool uselen)
    {

        fn2_ = func;
        lines_=srcLines;
        wlines_=NULL;
        numLines_=srcNumLines;
        uselen_=uselen;
        line_mode_=TRUE;
        src_ = NULL;
        srcLen_ = 0;
        wsrc_ = NULL;
        wsrcLen_ = 0;
        fnType_ = Fn_STD;

        uS0_=NULL;
        ubulk_=NULL;
        sbulk_=NULL;

        //fillin wlines_[], sS0_[]
        prepareLinesForStd();
    }

    StringPerfFunction(ICUStringPerfFn func, UChar* source, int32_t sourceLen, UBool uselen)
    {

        fn1_ = func;
        lines_=NULL;
        wlines_=NULL;
        numLines_=0;
        uselen_=uselen;
        line_mode_=FALSE;
        src_ = new UChar[sourceLen];
        memcpy(src_, source, sourceLen * U_SIZEOF_UCHAR);
        srcLen_ = sourceLen;
        wsrc_ = NULL;
        wsrcLen_ = 0;
        fnType_ = Fn_ICU;

        uS0_=NULL;
        sS0_=NULL;	
        ubulk_=new UnicodeString(src_,srcLen_);
        sbulk_=NULL;
    }

    StringPerfFunction(StdStringPerfFn func, UChar* source, int32_t sourceLen, UBool uselen)
    {

        fn2_ = func;
        lines_=NULL;
        wlines_=NULL;
        numLines_=0;
        uselen_=uselen;
        line_mode_=FALSE;
        src_ = new UChar[sourceLen];
        memcpy(src_, source, sourceLen * U_SIZEOF_UCHAR);
        srcLen_ = sourceLen;
        fnType_ = Fn_STD;

        uS0_=NULL;
        sS0_=NULL;
        ubulk_=NULL;

        //fillin wsrc_, sbulk_
        prepareBulkForStd();

    }

    ~StringPerfFunction()
    {
        //free(src_);
        free(wsrc_);
        delete[] src_;
        delete ubulk_;
        delete sbulk_;
        delete[] uS0_;
        delete[] sS0_;
        delete[] wlines_;
    }

private:
    void prepareLinesForStd(void)
    {
        UErrorCode err=U_ZERO_ERROR;

        wlines_=new WLine[numLines_];
        wchar_t ws[100];
        int32_t wcap = sizeof(ws) / sizeof(*ws);
        int32_t wl;
        wchar_t* wcs;

        sS0_=new stlstring[numLines_];
        for(int32_t i=0; i<numLines_; i++) {
            if(uselen_) {
                wcs = u_strToWCS(ws, wcap, &wl, lines_[i].name, lines_[i].len, &err);
                memcpy(wlines_[i].name, wcs, wl * sizeof(wchar_t));
                wlines_[i].len = wl;
                sS0_[i]=stlstring(wlines_[i].name, wlines_[i].len);
            } else {
                wcs = u_strToWCS(ws, wcap, &wl, lines_[i].name, lines_[i].len-1, &err);
                memcpy(wlines_[i].name, wcs, wl*sizeof(wchar_t));
                wlines_[i].len = wl;
                sS0_[i]=stlstring(wlines_[i].name, wlines_[i].len+1);
            }

            if (U_FAILURE(err)) {
                return;
            }
        }

    }

    void prepareBulkForStd(void)
    {
        UErrorCode err=U_ZERO_ERROR;

        const UChar* uSrc = src_;
        int32_t uSrcLen = srcLen_;
        wchar_t* wDest = NULL;
        int32_t wDestLen = 0;
        int32_t reqLen= 0 ;

        if(uselen_) {
            /* pre-flight*/
            u_strToWCS(wDest,wDestLen,&reqLen,uSrc,uSrcLen,&err);

            if(err == U_BUFFER_OVERFLOW_ERROR){
                err=U_ZERO_ERROR;
                wDest =(wchar_t*) malloc(sizeof(wchar_t) * (reqLen));
                wDestLen = reqLen;
                u_strToWCS(wDest,wDestLen,&reqLen,uSrc,uSrcLen,&err);
            }

            if (U_SUCCESS(err)) {
                wsrc_ = wDest;
                wsrcLen_ = wDestLen;
                sbulk_=new stlstring(wsrc_,wsrcLen_);
            }

        } else {
            /* pre-flight*/
            u_strToWCS(wDest,wDestLen,&reqLen,uSrc,uSrcLen-1,&err);

            if(err == U_BUFFER_OVERFLOW_ERROR){
                err=U_ZERO_ERROR;
                wDest =(wchar_t*) malloc(sizeof(wchar_t) * (reqLen+1));
                wDestLen = reqLen+1;
                u_strToWCS(wDest,wDestLen,&reqLen,uSrc,uSrcLen-1,&err);
            }

            if (U_SUCCESS(err)) {
                wsrc_ = wDest;
                wsrcLen_ = wDestLen;
                sbulk_=new stlstring(wsrc_);
            }
        }

        //free(wDest);
    }


private:
    ICUStringPerfFn fn1_;
    StdStringPerfFn fn2_;

    ULine* lines_;
    WLine* wlines_;
    int32_t numLines_;

    UBool uselen_;
    UChar* src_;
    int32_t srcLen_;
    wchar_t* wsrc_;
    int32_t wsrcLen_;
    UBool line_mode_;

    //added for preparing testing data
    UnicodeString* uS0_;
    stlstring* sS0_;
    UnicodeString* ubulk_;
    stlstring* sbulk_;
    FnType fnType_;
};


class StringPerformanceTest : public UPerfTest
{
public:
    StringPerformanceTest(int32_t argc, const char *argv[], UErrorCode &status);
    ~StringPerformanceTest();
    virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec,
                                          const char *&name,
                                          char *par = NULL);
    UPerfFunction* TestCtor();
    UPerfFunction* TestCtor1();
    UPerfFunction* TestCtor2();
    UPerfFunction* TestCtor3();
    UPerfFunction* TestAssign();
    UPerfFunction* TestAssign1();
    UPerfFunction* TestAssign2();
    UPerfFunction* TestGetch();
    UPerfFunction* TestCatenate();
    UPerfFunction* TestScan();
    UPerfFunction* TestScan1();
    UPerfFunction* TestScan2();

    UPerfFunction* TestStdLibCtor();
    UPerfFunction* TestStdLibCtor1();
    UPerfFunction* TestStdLibCtor2();
    UPerfFunction* TestStdLibCtor3();
    UPerfFunction* TestStdLibAssign();
    UPerfFunction* TestStdLibAssign1();
    UPerfFunction* TestStdLibAssign2();
    UPerfFunction* TestStdLibGetch();
    UPerfFunction* TestStdLibCatenate();
    UPerfFunction* TestStdLibScan();
    UPerfFunction* TestStdLibScan1();
    UPerfFunction* TestStdLibScan2();

private:
    long COUNT_;
    ULine* filelines_;
    UChar* StrBuffer;
    int32_t StrBufferLen;

};


inline void ctor(const UChar* src,int32_t srcLen, UnicodeString s0)
{
    UnicodeString a;
}

inline void ctor1(const UChar* src,int32_t srcLen, UnicodeString s0)
{
    UnicodeString b(uTESTCHAR1);
}

inline void ctor2(const UChar* src,int32_t srcLen, UnicodeString s0)
{
    UnicodeString c(uEMPTY);
}

inline void ctor3(const UChar* src,int32_t srcLen, UnicodeString s0)
{
    UnicodeString d(src,srcLen);
}

inline UnicodeString icu_assign_helper(const UChar* src,int32_t srcLen)
{
    if (srcLen==-1) { return src;}
    else { return UnicodeString(src, srcLen);}
}

inline void assign(const UChar* src,int32_t srcLen, UnicodeString s0)
{
    unistr = icu_assign_helper(src,srcLen);
}

inline void assign1(const UChar* src,int32_t srcLen, UnicodeString s0)
{
    unistr.setTo(src, srcLen);
}

inline void assign2(const UChar* src,int32_t srcLen, UnicodeString s0)
{
    unistr = s0;
}

inline void getch(const UChar* src,int32_t srcLen, UnicodeString s0)
{
    s0.charAt(0);
}


inline void catenate(const UChar* src,int32_t srcLen, UnicodeString s0)
{
    UTimer mystart, mystop;
    utimer_getTime(&mystart);

    *catICU += s0;

    utimer_getTime(&mystop);
    double mytime = utimer_getDeltaSeconds(&mystart,&mystop);
    printf("\nmytime=%f \n", mytime);

    *catICU += uCatenate_STR;
}

volatile int scan_idx;
U_STRING_DECL(SCAN1, "123", 3);

inline void scan(const UChar* src,int32_t srcLen, UnicodeString s0)
{
    UChar c='.';
    scan_idx = uScan_STRING.indexOf(c);
}

inline void scan1(const UChar* src,int32_t srcLen, UnicodeString s0)
{
    scan_idx = uScan_STRING.indexOf(SCAN1,3);
}

inline void scan2(const UChar* src,int32_t srcLen, UnicodeString s0)
{
    UChar c1='s';
    UChar c2='m';
    scan_idx = uScan_STRING.indexOf(c1);
    scan_idx = uScan_STRING.indexOf(c2);
}


inline void StdLibCtor(const wchar_t* src,int32_t srcLen, stlstring s0)
{
    stlstring a;
}

inline void StdLibCtor1(const wchar_t* src,int32_t srcLen, stlstring s0)
{
    stlstring b(simulate);
}

inline void StdLibCtor2(const wchar_t* src,int32_t srcLen, stlstring s0)
{
    stlstring c(sEMPTY);
}

inline void StdLibCtor3(const wchar_t* src,int32_t srcLen, stlstring s0)
{
    if (srcLen==-1) {
        stlstring d(src);
    }else {
        stlstring d(src, srcLen);
    }
}

inline stlstring stl_assign_helper(const wchar_t* src,int32_t srcLen)
{
    if (srcLen==-1) { return src;}
    else { return stlstring(src, srcLen);}
}

inline void StdLibAssign(const wchar_t* src,int32_t srcLen, stlstring s0)
{
    stlstr = stl_assign_helper(src,srcLen);
}

inline void StdLibAssign1(const wchar_t* src,int32_t srcLen, stlstring s0)
{
    if (srcLen==-1) { stlstr=src;}
    else { stlstr.assign(src, srcLen);}
}

inline void StdLibAssign2(const wchar_t* src,int32_t srcLen, stlstring s0)
{
    stlstr=s0;
}

inline void StdLibGetch(const wchar_t* src,int32_t srcLen, stlstring s0)
{
    s0.at(0);
}

inline void StdLibCatenate(const wchar_t* src,int32_t srcLen, stlstring s0)
{
    UTimer mystart, mystop;
    utimer_getTime(&mystart);

    *catStd += s0;
    *catStd += sCatenate_STR;

    utimer_getTime(&mystop);
    double mytime = utimer_getDeltaSeconds(&mystart,&mystop);
    printf("\nmytime=%f \n", mytime);

}

inline void StdLibScan(const wchar_t* src,int32_t srcLen, stlstring s0)
{
    scan_idx = (int) sScan_STRING.find('.');	
}

inline void StdLibScan1(const wchar_t* src,int32_t srcLen, stlstring s0)
{
    scan_idx = (int) sScan_STRING.find(L"123");
}

inline void StdLibScan2(const wchar_t* src,int32_t srcLen, stlstring s0)
{	
    scan_idx = (int) sScan_STRING.find_first_of(L"sm");
}

#endif // STRINGPERF_H

