/*
***********************************************************************
* © 2016 and later: Unicode, Inc. and others.
* License & terms of use: http://www.unicode.org/copyright.html#License
***********************************************************************
***********************************************************************
* Copyright (c) 2002-2016,International Business Machines
* Corporation and others.  All Rights Reserved.
***********************************************************************
***********************************************************************
*/

#ifndef _DATEFMTPERF_H
#define _DATEFMTPERF_H

#include "cmemory.h"
#include "unicode/stringpiece.h"
#include "unicode/unistr.h"
#include "unicode/uperf.h"

#include "unicode/dtitvfmt.h"
#include "unicode/utypes.h"
#include "unicode/datefmt.h"
#include "unicode/calendar.h"
#include "unicode/uclean.h"
#include "unicode/brkiter.h"
#include "unicode/numfmt.h"
#include "unicode/coll.h"
#include "util.h"

#include "datedata.h"
#include "breakdata.h"
#include "collationdata.h"

#include <stdlib.h>
#include <string.h>

#include <fstream>

#include <iostream>
using namespace std;

//  Stubs for Windows API functions when building on UNIXes.
//
#if U_PLATFORM_USES_ONLY_WIN32_API
// do nothing
#else
#define _UNICODE
typedef int DWORD;
inline int FoldStringW(DWORD dwMapFlags, const UChar* lpSrcStr,int cchSrc, UChar* lpDestStr,int cchDest);
#endif

class BreakItFunction : public UPerfFunction
{
private:
	int num;
	bool wordIteration;

public:

	BreakItFunction(){num = -1;}
	BreakItFunction(int a, bool b){num = a; wordIteration = b;}

	virtual void call(UErrorCode * status)
	{		
		BreakIterator* boundary;

		if(wordIteration)
		{
			for(int i = 0; i < num; i++)
			{
				boundary = BreakIterator::createWordInstance("en", *status);
				boundary->setText(str);

				int32_t start = boundary->first();
				for (int32_t end = boundary->next();
					 end != BreakIterator::DONE;
					 start = end, end = boundary->next())
				{
					printTextRange( *boundary, start, end );
				}
			}
		}

		else // character iteration
		{
			for(int i = 0; i < num; i++)
            {
				boundary = BreakIterator::createCharacterInstance(Locale::getUS(), *status);
				boundary->setText(str);

				int32_t start = boundary->first();
				for (int32_t end = boundary->next();
					 end != BreakIterator::DONE;
					 start = end, end = boundary->next())
				{
					printTextRange( *boundary, start, end );
				}
			}
		}


	}

	virtual long getOperationsPerIteration()
	{
		if(wordIteration) return 125*num;
		else return 355*num;
	}

	void printUnicodeString(const UnicodeString &s) {
		char charBuf[1000];
		s.extract(0, s.length(), charBuf, sizeof(charBuf)-1, 0);   
		charBuf[sizeof(charBuf)-1] = 0;          
		printf("%s", charBuf);
	}


	void printTextRange( BreakIterator& iterator, 
						int32_t start, int32_t end )
	{
		CharacterIterator *strIter = iterator.getText().clone();
		UnicodeString  s;
		strIter->getText(s);
		//printUnicodeString(UnicodeString(s, start, end-start));
		//puts("");
		delete strIter;
	}

	// Print the given string to stdout (for debugging purposes)
	void uprintf(const UnicodeString &str) {
		char *buf = 0;
		int32_t len = str.length();
		int32_t bufLen = len + 16;
		int32_t actualLen;
		buf = new char[bufLen + 1];
		actualLen = str.extract(0, len, buf/*, bufLen*/); // Default codepage conversion
		buf[actualLen] = 0;
		printf("%s", buf);
		delete[] buf;
	}

};

class DateFmtFunction : public UPerfFunction
{

private:
	int num;
    char locale[25];
public:
	
	DateFmtFunction()
	{
		num = -1;
	}

	DateFmtFunction(int a, const char* loc)
	{
		num = a;
        strcpy(locale, loc);
	}

	virtual void call(UErrorCode* status)
	{

		UErrorCode status2 = U_ZERO_ERROR;		
		Calendar *cal;
		TimeZone *zone;
		UnicodeString str;
		UDate date;

		cal = Calendar::createInstance(status2);
		check(status2, "Calendar::createInstance");
		zone = TimeZone::createTimeZone("GMT"); // Create a GMT zone
		cal->adoptTimeZone(zone);
		
		Locale loc(locale);
		DateFormat *fmt;
		fmt = DateFormat::createDateTimeInstance(
								DateFormat::kShort, DateFormat::kFull, loc);

		
		// (dates are imported from datedata.h)
		for(int j = 0; j < num; j++)
			for(int i = 0; i < NUM_DATES; i++)
			{
				cal->clear();
				cal->set(years[i], months[i], days[i]);
				date = cal->getTime(status2);
				check(status2, "Calendar::getTime");

				fmt->setCalendar(*cal);

				// Format the date
				str.remove();
				fmt->format(date, str, status2);

				
				// Display the formatted date string
				//uprintf(str);
				//printf("\n");
				
			}
		
		delete fmt;
		delete cal;
		//u_cleanup();
	}

	virtual long getOperationsPerIteration()
	{
		return NUM_DATES * num;
	}

	// Print the given string to stdout (for debugging purposes)
	void uprintf(const UnicodeString &str) {
		char *buf = 0;
		int32_t len = str.length();
		int32_t bufLen = len + 16;
		int32_t actualLen;
		buf = new char[bufLen + 1];
		actualLen = str.extract(0, len, buf/*, bufLen*/); // Default codepage conversion
		buf[actualLen] = 0;
		printf("%s", buf);
		delete[] buf;
	}

	// Verify that a UErrorCode is successful; exit(1) if not
	void check(UErrorCode& status, const char* msg) {
		if (U_FAILURE(status)) {
			printf("ERROR: %s (%s)\n", u_errorName(status), msg);
			exit(1);
		}
	}

};

class DateFmtCreateFunction : public UPerfFunction
{

private:
        int num;
        char locale[25];
public:

        DateFmtCreateFunction(int a, const char* loc)
        {
                num = a;
                strcpy(locale, loc);
        }

        virtual void call(UErrorCode* /* status */)
        {

                Locale loc(locale);
                DateFormat *fmt;
                // (dates are imported from datedata.h)
                for(int j = 0; j < num; j++) {
                    fmt = DateFormat::createDateTimeInstance(
                            DateFormat::kShort, DateFormat::kFull, loc);
                    delete fmt;
                }
        }

        virtual long getOperationsPerIteration()
        {
                return num;
        }

};

class DateFmtCopyFunction : public UPerfFunction
{

private:
        int num;
    char locale[25];
public:

        DateFmtCopyFunction()
        {
                num = -1;
        }

        DateFmtCopyFunction(int a, const char* loc)
        {
                num = a;
        strcpy(locale, loc);
        }

        virtual void call(UErrorCode* /* status */)
        {
                Locale loc(locale);
                UErrorCode status2 = U_ZERO_ERROR;
                DateFormat *fmt = DateFormat::createDateTimeInstance(
                            DateFormat::kShort, DateFormat::kFull, loc);
                for(int j = 0; j < num; j++) {
                    Format *cp = fmt->clone();
                    delete cp;
                }
                delete fmt;
        }

        virtual long getOperationsPerIteration()
        {
                return num;
        }

        // Verify that a UErrorCode is successful; exit(1) if not
        void check(UErrorCode& status, const char* msg) {
                if (U_FAILURE(status)) {
                        printf("ERROR: %s (%s)\n", u_errorName(status), msg);
                        exit(1);
                }
        }

};

class DIFCreateFunction : public UPerfFunction
{

private:
	int num;
    char locale[25];
public:
	
	DIFCreateFunction()
	{
		num = -1;
	}

	DIFCreateFunction(int a, const char* loc)
	{
		num = a;
        strcpy(locale, loc);
	}

	virtual void call(UErrorCode* /* status */)
	{
		UErrorCode status2 = U_ZERO_ERROR;		
		Calendar *cal;
		TimeZone *zone;

		cal = Calendar::createInstance(status2);
		check(status2, "Calendar::createInstance");
		zone = TimeZone::createTimeZone("GMT"); // Create a GMT zone
		cal->adoptTimeZone(zone);
		
		Locale loc(locale);
                UnicodeString skeleton("yMMMMdHms");

		for(int j = 0; j < num; j++) {
                    DateIntervalFormat* fmt(DateIntervalFormat::createInstance(skeleton, loc, status2));
                    delete fmt;
                }
                delete cal;
	}

	virtual long getOperationsPerIteration()
	{
		return num;
	}

	// Verify that a UErrorCode is successful; exit(1) if not
	void check(UErrorCode& status, const char* msg) {
		if (U_FAILURE(status)) {
			printf("ERROR: %s (%s)\n", u_errorName(status), msg);
			exit(1);
		}
	}

};

class TimeZoneCreateFunction : public UPerfFunction
{

private:
	int num;
    char locale[25];
public:
	
	TimeZoneCreateFunction()
	{
		num = -1;
	}

	TimeZoneCreateFunction(int a, const char* loc)
	{
		num = a;
        strcpy(locale, loc);
	}

	virtual void call(UErrorCode* /* status */)
	{
		Locale loc(locale);
                UnicodeString tzname("UTC");
		for(int j = 0; j < num; j++) {
                    TimeZone* tz(TimeZone::createTimeZone(tzname));
                    delete tz;
                }
	}

	virtual long getOperationsPerIteration()
	{
		return num;
	}

	// Verify that a UErrorCode is successful; exit(1) if not
	void check(UErrorCode& status, const char* msg) {
		if (U_FAILURE(status)) {
			printf("ERROR: %s (%s)\n", u_errorName(status), msg);
			exit(1);
		}
	}

};

class DTPatternGeneratorCreateFunction : public UPerfFunction
{

private:
	int num;
    char locale[25];
public:
	
	DTPatternGeneratorCreateFunction()
	{
		num = -1;
	}

	DTPatternGeneratorCreateFunction(int a, const char* loc)
	{
		num = a;
        strcpy(locale, loc);
	}

	virtual void call(UErrorCode* /* status */)
	{
		UErrorCode status2 = U_ZERO_ERROR;		
		Locale loc(locale);

		for(int j = 0; j < num; j++) {
                    DateTimePatternGenerator* gen(DateTimePatternGenerator::createInstance(loc, status2));
                    delete gen;
                }
	}

	virtual long getOperationsPerIteration()
	{
		return num;
	}

	// Verify that a UErrorCode is successful; exit(1) if not
	void check(UErrorCode& status, const char* msg) {
		if (U_FAILURE(status)) {
			printf("ERROR: %s (%s)\n", u_errorName(status), msg);
			exit(1);
		}
	}

};

class DTPatternGeneratorCopyFunction : public UPerfFunction
{

private:
	int num;
    char locale[25];
public:
	
	DTPatternGeneratorCopyFunction()
	{
		num = -1;
	}

	DTPatternGeneratorCopyFunction(int a, const char* loc)
	{
		num = a;
        strcpy(locale, loc);
	}

	virtual void call(UErrorCode* /* status */)
	{
		UErrorCode status2 = U_ZERO_ERROR;		
		Locale loc(locale);
                DateTimePatternGenerator* gen(DateTimePatternGenerator::createInstance(loc, status2));

		for(int j = 0; j < num; j++) {
                    DateTimePatternGenerator *cl = gen->clone();
                    delete cl;
                }
                delete gen;
	}

	virtual long getOperationsPerIteration()
	{
		return num;
	}

	// Verify that a UErrorCode is successful; exit(1) if not
	void check(UErrorCode& status, const char* msg) {
		if (U_FAILURE(status)) {
			printf("ERROR: %s (%s)\n", u_errorName(status), msg);
			exit(1);
		}
	}

};

class DTPatternGeneratorBestValueFunction : public UPerfFunction
{

private:
	int num;
    char locale[25];
public:
	
	DTPatternGeneratorBestValueFunction()
	{
		num = -1;
	}

	DTPatternGeneratorBestValueFunction(int a, const char* loc)
	{
		num = a;
        strcpy(locale, loc);
	}

	virtual void call(UErrorCode* /* status */)
	{
		UErrorCode status2 = U_ZERO_ERROR;		
		Locale loc(locale);
                DateTimePatternGenerator* gen(DateTimePatternGenerator::createInstance(loc, status2));
                UnicodeString skeleton("yMMMMdHms");

		for(int j = 0; j < num; j++) {
                    gen->getBestPattern(skeleton, status2);
                }
                check(status2, "getBestPattern");
                delete gen;
	}

	virtual long getOperationsPerIteration()
	{
		return num;
	}

	// Verify that a UErrorCode is successful; exit(1) if not
	void check(UErrorCode& status, const char* msg) {
		if (U_FAILURE(status)) {
			printf("ERROR: %s (%s)\n", u_errorName(status), msg);
			exit(1);
		}
	}

};

class NumFmtFunction : public UPerfFunction
{

private:
	int num;
    char locale[25];
public:
	
	NumFmtFunction()
	{
		num = -1;
	}

	NumFmtFunction(int a, const char* loc)
	{
		num = a;
        strcpy(locale, loc);
	}

	virtual void call(UErrorCode* status2)
	{
        Locale loc(locale);
        UErrorCode status = U_ZERO_ERROR;
        
        // Create a number formatter for the locale
        NumberFormat *fmt = NumberFormat::createInstance(loc, status);

        // Parse a string.  The string uses the digits '0' through '9'
        // and the decimal separator '.', standard in the US locale
        
        for(int i = 0; i < num; i++)
        {
            UnicodeString str("9876543210.123");
            Formattable result;
            fmt->parse(str, result, status);

            //uprintf(formattableToString(result));
            //printf("\n");

            // Take the number parsed above, and use the formatter to
            // format it.
            str.remove(); // format() will APPEND to this string
            fmt->format(result, str, status);

            //uprintf(str);
            //printf("\n");
        }

        delete fmt; // Release the storage used by the formatter
    }

    enum {
        U_SPACE=0x20,
        U_DQUOTE=0x22,
        U_COMMA=0x2c,
        U_LEFT_SQUARE_BRACKET=0x5b,
        U_BACKSLASH=0x5c,
        U_RIGHT_SQUARE_BRACKET=0x5d,
        U_SMALL_U=0x75
    };

    // Create a display string for a formattable
    UnicodeString formattableToString(const Formattable& f) {
        switch (f.getType()) {
        case Formattable::kDate:
            // TODO: Finish implementing this
            return UNICODE_STRING_SIMPLE("Formattable_DATE_TBD");
        case Formattable::kDouble:
            {
                char buf[256];
                sprintf(buf, "%gD", f.getDouble());
                return UnicodeString(buf, "");
            }
        case Formattable::kLong:
        case Formattable::kInt64:
            {
                char buf[256];
                sprintf(buf, "%ldL", f.getLong());
                return UnicodeString(buf, "");
            }
        case Formattable::kString:
            return UnicodeString((UChar)U_DQUOTE).append(f.getString()).append((UChar)U_DQUOTE);
        case Formattable::kArray:
            {
                int32_t i, count;
                const Formattable* array = f.getArray(count);
                UnicodeString result((UChar)U_LEFT_SQUARE_BRACKET);
                for (i=0; i<count; ++i) {
                    if (i > 0) {
                        (result += (UChar)U_COMMA) += (UChar)U_SPACE;
                    }
                    result += formattableToString(array[i]);
                }
                result += (UChar)U_RIGHT_SQUARE_BRACKET;
                return result;
            }
        default:
            return UNICODE_STRING_SIMPLE("INVALID_Formattable");
        }
    }

	virtual long getOperationsPerIteration()
	{
		return num;
	}
    
    // Print the given string to stdout using the UTF-8 converter (for debugging purposes only)
    void uprintf(const UnicodeString &str) {
        char stackBuffer[100];
        char *buf = 0;

        int32_t bufLen = str.extract(0, 0x7fffffff, stackBuffer, sizeof(stackBuffer), "UTF-8");
        if(bufLen < sizeof(stackBuffer)) {
            buf = stackBuffer;
        } else {
            buf = new char[bufLen + 1];
            bufLen = str.extract(0, 0x7fffffff, buf, bufLen + 1, "UTF-8");
        }
        printf("%s", buf);
        if(buf != stackBuffer) {
            delete[] buf;
        }
    }
};



#define NUM_STRING "9876543210.123"
#define NUM_NUM 9876543210.123
class StdioNumFmtFunction : public UPerfFunction
{

 private:
  int num;
  char locale[25];
 public:
	
  StdioNumFmtFunction()
    {
      num = -1;
    }

  StdioNumFmtFunction(int a, const char* loc)
    {
      num = a;
      strcpy(locale, loc);
    }

  virtual void call(UErrorCode* status2)
  {
    Locale loc(locale);
    UErrorCode status = U_ZERO_ERROR;
        
    // Parse a string.  The string uses the digits '0' through '9'
    // and the decimal separator '.', standard in the US locale

    double result;
    char outbuf[500];
    const char *str = NUM_STRING;
        
    for(int i = 0; i < num; i++)
      {
        if(sscanf(str, "%lg", &result)!=1) {
          cout << "Failed Stdio: failed to sscanf" << endl;
          *status2 = U_PARSE_ERROR;
          return;
        }

        sprintf(outbuf, "%lg", result);
      }
    
    if(result!=NUM_NUM) {
      cout << "Failed Stdio: sscanf got wrong result, expected " << NUM_NUM << " got " << result << endl;
      *status2 = U_PARSE_ERROR;
    }
    if(strcmp(str,NUM_STRING)) {
      cout << "Failed Stdio: sprintf got wrong result, expected " << NUM_STRING << " got " << str << endl;
      *status2 = U_PARSE_ERROR;
    }
  }
 
  virtual long getOperationsPerIteration()
  {
    return num;
  }
    
};

class CollationFunction : public UPerfFunction
{

private:
	int num;
    char locale[25];
	UnicodeString *collation_strings;

	/**
	 * Unescape the strings
	 */
	void init() {
        uint32_t listSize = UPRV_LENGTHOF(collation_strings_escaped);
		collation_strings = new UnicodeString[listSize];
		for(uint32_t k=0;k<listSize;k++) {
			collation_strings[k] = collation_strings_escaped[k].unescape();
		}
		UnicodeString shorty((UChar32)0x12345);
	}
public:
	
	CollationFunction()
	{
		num = -1;

		init();
	}

	~CollationFunction() {
		delete [] collation_strings;
	}

	CollationFunction(int a, const char* loc)
	{
		num = a;
        strcpy(locale, loc);
		init();
	}

	virtual void call(UErrorCode* status2)
	{
        uint32_t listSize = UPRV_LENGTHOF(collation_strings_escaped);
        UErrorCode status = U_ZERO_ERROR; 
        Collator *coll = Collator::createInstance(Locale(locale), status);
        
        for(int k = 0; k < num; k++)
        {
            uint32_t i, j;
            for(i=listSize-1; i>=1; i--) {
                for(j=0; j<i; j++) {
                    if(coll->compare(collation_strings[j], collation_strings[j+1]) == UCOL_LESS) {
                    //cout << "Success!" << endl;
                     }
                }
            }
         }
        delete coll; 
    }

	virtual long getOperationsPerIteration()
	{
		return num;
	}
};

class DateFormatPerfTest : public UPerfTest
{
private:

public:

	DateFormatPerfTest(int32_t argc, const char* argv[], UErrorCode& status);
	~DateFormatPerfTest();
	virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec,const char* &name, char* par);

	UPerfFunction* DateFmt250();
	UPerfFunction* DateFmt10000();
	UPerfFunction* DateFmt100000();
	UPerfFunction* DateFmtCreate250();
	UPerfFunction* DateFmtCreate10000();
	UPerfFunction* DateFmtCopy250();
	UPerfFunction* DateFmtCopy10000();
	UPerfFunction* BreakItWord250();
	UPerfFunction* BreakItWord10000();
	UPerfFunction* BreakItChar250();
	UPerfFunction* BreakItChar10000();
    UPerfFunction* NumFmt10000();
    UPerfFunction* NumFmt100000();
    UPerfFunction* Collation10000();
    UPerfFunction* Collation100000();
    UPerfFunction* DIFCreate250();
    UPerfFunction* DIFCreate10000();
    UPerfFunction* TimeZoneCreate250();
    UPerfFunction* TimeZoneCreate10000();
    UPerfFunction* DTPatternGeneratorCreate250();
    UPerfFunction* DTPatternGeneratorCreate10000();
    UPerfFunction* DTPatternGeneratorCopy250();
    UPerfFunction* DTPatternGeneratorCopy10000();
    UPerfFunction* DTPatternGeneratorBestValue250();
    UPerfFunction* DTPatternGeneratorBestValue10000();
};

#endif // DateFmtPerf
