/********************************************************************
 * COPYRIGHT:
 * Copyright (c) 2002-2007, 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);

    // 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;
    resolvedFileName = NULL;
    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;
    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;
            }
            if (testFunction->getOperationsPerIteration() < 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;
            }

            for(int32_t ps =0; ps < passes; ps++){
                long events = -1;
                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;
                }
                events = testFunction->getEventsPerIteration();
                //print info only in verbose mode
                if(verbose==TRUE){
/*
                    if(events == -1){
                        fprintf(stdout,"= %s end %f %i %i\n",name , t , loops, testFunction->getOperationsPerIteration());
                    }else{
                        fprintf(stdout,"= %s end %f %i %i %i\n",name , t , loops, testFunction->getOperationsPerIteration(), events);
                    }
*/
                    if(events == -1){
                        fprintf(stdout, "= %s end: %f loops: %i operations: %li \n", name, t, (int)loops, testFunction->getOperationsPerIteration());
                    }else{
                        fprintf(stdout, "= %s end: %f loops: %i operations: %li events: %li\n", name, t, (int)loops, testFunction->getOperationsPerIteration(), events);
                    }
                }else{
/*
                    if(events == -1){
                        fprintf(stdout,"= %f %i %i \n", t , loops, testFunction->getOperationsPerIteration());
                    }else{
                        fprintf(stdout,"= %f %i %i %i\n", t , loops, testFunction->getOperationsPerIteration(), events);
                    }
*/
                    if(events == -1){
                        fprintf(stdout,"= %s end %f %i %li\n", name, t, (int)loops, testFunction->getOperationsPerIteration());
                    }else{
                        fprintf(stdout,"= %s end %f %i %li %li\n", name, t, (int)loops, testFunction->getOperationsPerIteration(), 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
