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

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

#include "unicode/uperf.h"

#include <string.h>
#include <stdio.h>
#include <stdlib.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

