/*
***********************************************************************
* © 2016 and later: Unicode, Inc. and others.
* License & terms of use: http://www.unicode.org/copyright.html
***********************************************************************
***********************************************************************
* 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
