/********************************************************************
 * COPYRIGHT:
 * Copyright (c) 2002-2008, International Business Machines Corporation and
 * others. All Rights Reserved.
 ********************************************************************/

/* z/OS needs this definition for timeval */
#if !defined(_XOPEN_SOURCE_EXTENDED)
#define _XOPEN_SOURCE_EXTENDED 1
#endif

#include "unicode/uperf.h"
#include "uoptions.h"
#include "cmemory.h"
#include <stdio.h>
#include <stdlib.h>

#if !UCONFIG_NO_CONVERSION
static const char delim = '/';
static int32_t execCount = 0;
UPerfTest* UPerfTest::gTest = NULL;
static const int MAXLINES = 40000;
const char UPerfTest::gUsageString[] =
    "Usage: %s [OPTIONS] [FILES]\n"
    "\tReads the input file and prints out time taken in seconds\n"
    "Options:\n"
    "\t-h or -? or --help   this usage text\n"
    "\t-v or --verbose      print extra information when processing files\n"
    "\t-s or --sourcedir    source directory for files followed by path\n"
    "\t                     followed by path\n"
    "\t-e or --encoding     encoding of source files\n"
    "\t-u or --uselen       perform timing analysis on non-null terminated buffer using length\n"
    "\t-f or --file-name    file to be used as input data\n"
    "\t-p or --passes       Number of passes to be performed. Requires Numeric argument.\n"
    "\t                     Cannot be used with --time\n"
    "\t-i or --iterations   Number of iterations to be performed. Requires Numeric argument\n"
    "\t-t or --time         Threshold time for looping until in seconds. Requires Numeric argument.\n"
    "\t                     Cannot be used with --iterations\n"
    "\t-l or --line-mode    The data file should be processed in line mode\n"
    "\t-b or --bulk-mode    The data file should be processed in file based.\n"
    "\t                     Cannot be used with --line-mode\n"
    "\t-L or --locale       Locale for the test\n";

enum
{
    HELP1,
    HELP2,
    VERBOSE,
    SOURCEDIR,
    ENCODING,
    USELEN,
    FILE_NAME,
    PASSES,
    ITERATIONS,
    TIME,
    LINE_MODE,
    BULK_MODE,
    LOCALE,
    OPTIONS_COUNT
};


static UOption options[OPTIONS_COUNT+20]={
    UOPTION_HELP_H,
    UOPTION_HELP_QUESTION_MARK,
    UOPTION_VERBOSE,
    UOPTION_SOURCEDIR,
    UOPTION_ENCODING,
    UOPTION_DEF( "uselen",        'u', UOPT_NO_ARG),
    UOPTION_DEF( "file-name",     'f', UOPT_REQUIRES_ARG),
    UOPTION_DEF( "passes",        'p', UOPT_REQUIRES_ARG),
    UOPTION_DEF( "iterations",    'i', UOPT_REQUIRES_ARG),
    UOPTION_DEF( "time",          't', UOPT_REQUIRES_ARG),
    UOPTION_DEF( "line-mode",     'l', UOPT_NO_ARG),
    UOPTION_DEF( "bulk-mode",     'b', UOPT_NO_ARG),
    UOPTION_DEF( "locale",        'L', UOPT_REQUIRES_ARG)
};

UPerfTest::UPerfTest(int32_t argc, const char* argv[], UErrorCode& status)
        : _argc(argc), _argv(argv), _addUsage(NULL),
          ucharBuf(NULL), encoding(""),
          uselen(FALSE),
          fileName(NULL), sourceDir("."),
          lines(NULL), numLines(0), line_mode(TRUE),
          buffer(NULL), bufferLen(0),
          verbose(FALSE), bulk_mode(FALSE),
          passes(1), iterations(0), time(0),
          locale(NULL) {
    init(NULL, 0, status);
}

UPerfTest::UPerfTest(int32_t argc, const char* argv[],
                     UOption addOptions[], int32_t addOptionsCount,
                     const char *addUsage,
                     UErrorCode& status)
        : _argc(argc), _argv(argv), _addUsage(addUsage),
          ucharBuf(NULL), encoding(""),
          uselen(FALSE),
          fileName(NULL), sourceDir("."),
          lines(NULL), numLines(0), line_mode(TRUE),
          buffer(NULL), bufferLen(0),
          verbose(FALSE), bulk_mode(FALSE),
          passes(1), iterations(0), time(0),
          locale(NULL) {
    init(addOptions, addOptionsCount, status);
}

void UPerfTest::init(UOption addOptions[], int32_t addOptionsCount,
                     UErrorCode& status) {
    //initialize the argument list
    U_MAIN_INIT_ARGS(_argc, _argv);

    resolvedFileName = NULL;

    // add specific options
    int32_t optionsCount = OPTIONS_COUNT;
    if (addOptionsCount > 0) {
        memcpy(options+optionsCount, addOptions, addOptionsCount*sizeof(UOption));
        optionsCount += addOptionsCount;
    }

    //parse the arguments
    _remainingArgc = u_parseArgs(_argc, (char**)_argv, optionsCount, options);

    // copy back values for additional options
    if (addOptionsCount > 0) {
        memcpy(addOptions, options+OPTIONS_COUNT, addOptionsCount*sizeof(UOption));
    }

    // Now setup the arguments
    if(_argc==1 || options[HELP1].doesOccur || options[HELP2].doesOccur) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }

    if(options[VERBOSE].doesOccur) {
        verbose = TRUE;
    }

    if(options[SOURCEDIR].doesOccur) {
        sourceDir = options[SOURCEDIR].value;
    }

    if(options[ENCODING].doesOccur) {
        encoding = options[ENCODING].value;
    }

    if(options[USELEN].doesOccur) {
        uselen = TRUE;
    }

    if(options[FILE_NAME].doesOccur){
        fileName = options[FILE_NAME].value;
    }

    if(options[PASSES].doesOccur) {
        passes = atoi(options[PASSES].value);
    }
    if(options[ITERATIONS].doesOccur) {
        iterations = atoi(options[ITERATIONS].value);
        if(options[TIME].doesOccur) {
            status = U_ILLEGAL_ARGUMENT_ERROR;
            return;
        }
    } else if(options[TIME].doesOccur) {
        time = atoi(options[TIME].value);
    } else {
        iterations = 1000; // some default
    }

    if(options[LINE_MODE].doesOccur) {
        line_mode = TRUE;
        bulk_mode = FALSE;
    }

    if(options[BULK_MODE].doesOccur) {
        bulk_mode = TRUE;
        line_mode = FALSE;
    }
    
    if(options[LOCALE].doesOccur) {
        locale = options[LOCALE].value;
    }

    int32_t len = 0;
    if(fileName!=NULL){
        //pre-flight
        ucbuf_resolveFileName(sourceDir, fileName, NULL, &len, &status);
        resolvedFileName = (char*) uprv_malloc(len);
        if(resolvedFileName==NULL){
            status= U_MEMORY_ALLOCATION_ERROR;
            return;
        }
        if(status == U_BUFFER_OVERFLOW_ERROR){
            status = U_ZERO_ERROR;
        }
        ucbuf_resolveFileName(sourceDir, fileName, resolvedFileName, &len, &status);
        ucharBuf = ucbuf_open(resolvedFileName,&encoding,TRUE,FALSE,&status);

        if(U_FAILURE(status)){
            printf("Could not open the input file %s. Error: %s\n", fileName, u_errorName(status));
            return;
        }
    }
}

ULine* UPerfTest::getLines(UErrorCode& status){
    lines     = new ULine[MAXLINES];
    int maxLines = MAXLINES;
    numLines=0;
    const UChar* line=NULL;
    int32_t len =0;
    for (;;) {
        line = ucbuf_readline(ucharBuf,&len,&status);
        if(line == NULL || U_FAILURE(status)){
            break;
        }
        lines[numLines].name  = new UChar[len];
        lines[numLines].len   = len;
        memcpy(lines[numLines].name, line, len * U_SIZEOF_UCHAR);

        numLines++;
        len = 0;
        if (numLines >= maxLines) {
            maxLines += MAXLINES;
            ULine *newLines = new ULine[maxLines];
            if(newLines == NULL) {
                fprintf(stderr, "Out of memory reading line %d.\n", (int)numLines);
                status= U_MEMORY_ALLOCATION_ERROR;
                delete []lines;
                return NULL;
            }

            memcpy(newLines, lines, numLines*sizeof(ULine));
            delete []lines;
            lines = newLines;
        }
    }
    return lines;
}
const UChar* UPerfTest::getBuffer(int32_t& len, UErrorCode& status){
    if (U_FAILURE(status)) {
        return NULL;
    }
    len = ucbuf_size(ucharBuf);
    buffer =  (UChar*) uprv_malloc(U_SIZEOF_UCHAR * (len+1));
    u_strncpy(buffer,ucbuf_getBuffer(ucharBuf,&bufferLen,&status),len);
    buffer[len]=0;
    len = bufferLen;
    return buffer;
}
UBool UPerfTest::run(){
    if(_remainingArgc==1){
        // Testing all methods
        return runTest();
    }
    UBool res=FALSE;
    // Test only the specified fucntion
    for (int i = 1; i < _remainingArgc; ++i) {
        if (_argv[i][0] != '-') {
            char* name = (char*) _argv[i];
            if(verbose==TRUE){
                //fprintf(stdout, "\n=== Handling test: %s: ===\n", name);
                //fprintf(stdout, "\n%s:\n", name);
            }
            char* parameter = strchr( name, '@' );
            if (parameter) {
                *parameter = 0;
                parameter += 1;
            }
            execCount = 0;
            res = runTest( name, parameter );
            if (!res || (execCount <= 0)) {
                fprintf(stdout, "\n---ERROR: Test doesn't exist: %s!\n", name);
                return FALSE;
            }
        }
    }
    return res;
}
UBool UPerfTest::runTest(char* name, char* par ){
    UBool rval;
    char* pos = NULL;

    if (name)
        pos = strchr( name, delim ); // check if name contains path (by looking for '/')
    if (pos) {
        path = pos+1;   // store subpath for calling subtest
        *pos = 0;       // split into two strings
    }else{
        path = NULL;
    }

    if (!name || (name[0] == 0) || (strcmp(name, "*") == 0)) {
        rval = runTestLoop( NULL, NULL );

    }else if (strcmp( name, "LIST" ) == 0) {
        this->usage();
        rval = TRUE;

    }else{
        rval = runTestLoop( name, par );
    }

    if (pos)
        *pos = delim;  // restore original value at pos
    return rval;
}


void UPerfTest::setPath( char* pathVal )
{
    this->path = pathVal;
}

// call individual tests, to be overriden to call implementations
UPerfFunction* UPerfTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* par )
{
    // to be overriden by a method like:
    /*
    switch (index) {
        case 0: name = "First Test"; if (exec) FirstTest( par ); break;
        case 1: name = "Second Test"; if (exec) SecondTest( par ); break;
        default: name = ""; break;
    }
    */
    fprintf(stderr,"*** runIndexedTest needs to be overriden! ***");
    name = ""; exec = exec; index = index; par = par;
    return NULL;
}


UBool UPerfTest::runTestLoop( char* testname, char* par )
{
    int32_t    index = 0;
    const char*   name;
    UBool  run_this_test;
    UBool  rval = FALSE;
    UErrorCode status = U_ZERO_ERROR;
    UPerfTest* saveTest = gTest;
    gTest = this;
    int32_t loops = 0;
    double t=0;
    int32_t n = 1;
    long ops;
    do {
        this->runIndexedTest( index, FALSE, name );
        if (!name || (name[0] == 0))
            break;
        if (!testname) {
            run_this_test = TRUE;
        }else{
            run_this_test = (UBool) (strcmp( name, testname ) == 0);
        }
        if (run_this_test) {
            UPerfFunction* testFunction = this->runIndexedTest( index, TRUE, name, par );
            execCount++;
            rval=TRUE;
            if(testFunction==NULL){
                fprintf(stderr,"%s function returned NULL", name);
                return FALSE;
            }
            ops = testFunction->getOperationsPerIteration();
            if (ops < 1) {
                fprintf(stderr, "%s returned an illegal operations/iteration()\n", name);
                return FALSE;
            }
            if(iterations == 0) {
                n = time;
                // Run for specified duration in seconds
                if(verbose==TRUE){
                    fprintf(stdout,"= %s calibrating %i seconds \n", name, (int)n);
                }

                //n *=  1000; // s => ms
                //System.out.println("# " + meth.getName() + " " + n + " sec");
                int32_t failsafe = 1; // last resort for very fast methods
                t = 0;
                while (t < (int)(n * 0.9)) { // 90% is close enough
                    if (loops == 0 || t == 0) {
                        loops = failsafe;
                        failsafe *= 10;
                    } else {
                        //System.out.println("# " + meth.getName() + " x " + loops + " = " + t);                            
                        loops = (int)((double)n / t * loops + 0.5);
                        if (loops == 0) {
                            fprintf(stderr,"Unable to converge on desired duration");
                            return FALSE;
                        }
                    }
                    //System.out.println("# " + meth.getName() + " x " + loops);
                    t = testFunction->time(loops,&status);
                    if(U_FAILURE(status)){
                        printf("Performance test failed with error: %s \n", u_errorName(status));
                        break;
                    }
                }
            } else {
                loops = iterations;
            }

            double min_t=1000000.0, sum_t=0.0;
            long events = -1;

            for(int32_t ps =0; ps < passes; ps++){
                fprintf(stdout,"= %s begin " ,name);
                if(verbose==TRUE){
                    if(iterations > 0) {
                        fprintf(stdout, "%i\n", (int)loops);
                    } else {
                        fprintf(stdout, "%i\n", (int)n);
                    }
                } else {
                    fprintf(stdout, "\n");
                }
                t = testFunction->time(loops, &status);
                if(U_FAILURE(status)){
                    printf("Performance test failed with error: %s \n", u_errorName(status));
                    break;
                }
                sum_t+=t;
                if(t<min_t) {
                    min_t=t;
                }
                events = testFunction->getEventsPerIteration();
                //print info only in verbose mode
                if(verbose==TRUE){
                    if(events == -1){
                        fprintf(stdout, "= %s end: %f loops: %i operations: %li \n", name, t, (int)loops, ops);
                    }else{
                        fprintf(stdout, "= %s end: %f loops: %i operations: %li events: %li\n", name, t, (int)loops, ops, events);
                    }
                }else{
                    if(events == -1){
                        fprintf(stdout,"= %s end %f %i %li\n", name, t, (int)loops, ops);
                    }else{
                        fprintf(stdout,"= %s end %f %i %li %li\n", name, t, (int)loops, ops, events);
                    }
                }
            }
            if(verbose && U_SUCCESS(status)) {
                double avg_t = sum_t/passes;
                if (loops == 0 || ops == 0) {
                    fprintf(stderr, "%s did not run\n", name);
                }
                else if(events == -1) {
                    fprintf(stdout, "%%= %s avg: %.4g loops: %i avg/op: %.4g ns\n",
                            name, avg_t, (int)loops, (avg_t*1E9)/(loops*ops));
                    fprintf(stdout, "_= %s min: %.4g loops: %i min/op: %.4g ns\n",
                            name, min_t, (int)loops, (min_t*1E9)/(loops*ops));
                }
                else {
                    fprintf(stdout, "%%= %s avg: %.4g loops: %i avg/op: %.4g ns avg/event: %.4g ns\n",
                            name, avg_t, (int)loops, (avg_t*1E9)/(loops*ops), (avg_t*1E9)/(loops*events));
                    fprintf(stdout, "_= %s min: %.4g loops: %i min/op: %.4g ns min/event: %.4g ns\n",
                            name, min_t, (int)loops, (min_t*1E9)/(loops*ops), (min_t*1E9)/(loops*events));
                }
            }
            delete testFunction;
        }
        index++;
    }while(name);

    gTest = saveTest;
    return rval;
}

/**
* Print a usage message for this test class.
*/
void UPerfTest::usage( void )
{
    puts(gUsageString);
    if (_addUsage != NULL) {
        puts(_addUsage);
    }

    UBool save_verbose = verbose;
    verbose = TRUE;
    fprintf(stdout,"Test names:\n");
    fprintf(stdout,"-----------\n");

    int32_t index = 0;
    const char* name = NULL;
    do{
        this->runIndexedTest( index, FALSE, name );
        if (!name)
            break;
        fprintf(stdout,name);
        fprintf(stdout,"\n");
        index++;
    }while (name && (name[0] != 0));
    verbose = save_verbose;
}




void UPerfTest::setCaller( UPerfTest* callingTest )
{
    caller = callingTest;
    if (caller) {
        verbose = caller->verbose;
    }
}

UBool UPerfTest::callTest( UPerfTest& testToBeCalled, char* par )
{
    execCount--; // correct a previously assumed test-exec, as this only calls a subtest
    testToBeCalled.setCaller( this );
    return testToBeCalled.runTest( path, par );
}

UPerfTest::~UPerfTest(){
    if(lines!=NULL){
        delete[] lines;
    }
    if(buffer!=NULL){
        uprv_free(buffer);
    }
    if(resolvedFileName!=NULL){
        uprv_free(resolvedFileName);
    }
    ucbuf_close(ucharBuf);
}

#endif
