/*
**********************************************************************
* Copyright (c) 2010-2016,International Business Machines
* Corporation and others.  All Rights Reserved.
**********************************************************************
**********************************************************************
*/

#ifndef _DTFMTRTPERF_H
#define _DTFMTRTPERF_H

#include "unicode/utypes.h"
#include "unicode/uperf.h"
#include "unicode/timezone.h"
#include "unicode/simpletz.h"
#include "unicode/calendar.h"
#include "unicode/strenum.h"
#include "unicode/smpdtfmt.h"
#include "unicode/uchar.h"
#include "unicode/basictz.h"
#include "cmemory.h"
#include "cstring.h"

#include "unicode/uperf.h"
#include "unicode/unistr.h"
#include "unicode/datefmt.h"
#include "unicode/calendar.h"
#include "unicode/uclean.h"
#include "unicode/brkiter.h"
#include "util.h"

static const char* PATTERNS[] = {"z", "zzzz", "Z", "ZZZZ", "v", "vvvv", "V", "VVVV"};
static const int NUM_PATTERNS = UPRV_LENGTHOF(PATTERNS);

#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <string>
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 DateTimeRoundTripFunction : public UPerfFunction
{
private:
	int nLocales;
public:
	
	DateTimeRoundTripFunction()
	{
		nLocales = 0;
	}

	DateTimeRoundTripFunction(int locs)
	{
		nLocales = locs;
	}

	virtual void call(UErrorCode* status)
	{
        *status = U_ZERO_ERROR;

        SimpleTimeZone unknownZone(-31415, (UnicodeString)"Etc/Unknown");
        int32_t badDstOffset = -1234;
        int32_t badZoneOffset = -2345;

        int32_t testDateData[][3] = {
            {2007, 1, 15},
            {2007, 6, 15},
            {1990, 1, 15},
            {1990, 6, 15},
            {1960, 1, 15},
            {1960, 6, 15},
        };

        Calendar *cal = Calendar::createInstance(*status);
        if (U_FAILURE(*status)) {
            //dataerrln("Calendar::createInstance failed: %s", u_errorName(*status));
            return;
        }

        // Set up rule equivalency test range
        UDate low, high;
        cal->set(1900, UCAL_JANUARY, 1);
        low = cal->getTime(*status);
        cal->set(2040, UCAL_JANUARY, 1);
        high = cal->getTime(*status);
        if (U_FAILURE(*status)) {
            //errln("getTime failed");
            return;
        }

        // Set up test dates
        UDate DATES[UPRV_LENGTHOF(testDateData)/3];
        const int32_t nDates = UPRV_LENGTHOF(testDateData)/3;
        cal->clear();
        for (int32_t i = 0; i < nDates; i++) {
            cal->set(testDateData[i][0], testDateData[i][1], testDateData[i][2]);
            DATES[i] = cal->getTime(*status);
            if (U_FAILURE(*status)) {
                //errln("getTime failed");
                return;
            }
        }

        // Set up test locales
        const Locale testLocales[] = {
            Locale("en"),
            Locale("en_US"),
            Locale("en_AU"),
            Locale("de_DE"),
            Locale("fr"),
            Locale("ja_JP"),
            Locale("ko"),
            Locale("pt"),
            Locale("th_TH"),
            Locale("zh_Hans"),

            Locale("it"),

            Locale("en"),
            Locale("en_US"),
            Locale("en_AU"),
            Locale("de_DE"),
            Locale("fr"),
            Locale("ja_JP"),
            Locale("ko"),
            Locale("pt"),
            Locale("th_TH"),
            Locale("zh_Hans"),
        };

        const Locale *LOCALES;
        LOCALES = testLocales;

        StringEnumeration *tzids = TimeZone::createEnumeration();
        if (U_FAILURE(*status)) {
            //errln("tzids->count failed");
            return;
        }

        // Run the roundtrip test
        for (int32_t locidx = 0; locidx < nLocales; locidx++) {
            for (int32_t patidx = 0; patidx < NUM_PATTERNS; patidx++) {
                SimpleDateFormat *sdf = new SimpleDateFormat((UnicodeString)PATTERNS[patidx], LOCALES[locidx], *status);
                if (U_FAILURE(*status)) {
                    //errcheckln(*status, (UnicodeString)"new SimpleDateFormat failed for pattern " +
                    //    PATTERNS[patidx] + " for locale " + LOCALES[locidx].getName() + " - " + u_errorName(*status));
                    *status = U_ZERO_ERROR;
                    continue;
                }

                tzids->reset(*status);
                const UnicodeString *tzid;
                while ((tzid = tzids->snext(*status))) {
                    TimeZone *tz = TimeZone::createTimeZone(*tzid);

                    for (int32_t datidx = 0; datidx < nDates; datidx++) {
                        UnicodeString tzstr;
                        FieldPosition fpos(0);

                        // Format
                        sdf->setTimeZone(*tz);
                        sdf->format(DATES[datidx], tzstr, fpos);

                        // Before parse, set unknown zone to SimpleDateFormat instance
                        // just for making sure that it does not depends on the time zone
                        // originally set.
                        sdf->setTimeZone(unknownZone);

                        // Parse
                        ParsePosition pos(0);
                        Calendar *outcal = Calendar::createInstance(unknownZone, *status);
                        if (U_FAILURE(*status)) {
                            //errln("Failed to create an instance of calendar for receiving parse result.");
                            *status = U_ZERO_ERROR;
                            continue;
                        }
                        outcal->set(UCAL_DST_OFFSET, badDstOffset);
                        outcal->set(UCAL_ZONE_OFFSET, badZoneOffset);
                        sdf->parse(tzstr, *outcal, pos);

                        // clean loop
                        delete outcal;

                    }
                    delete tz;
                    // break  time zone loop
                    break;

                }
                delete sdf;
            }
        }
        delete cal;
        delete tzids;

	}

	virtual long getOperationsPerIteration()
	{
		return NUM_PATTERNS * nLocales * 6;
	}
};


class DateTimeRoundTripPerfTest : public UPerfTest
{
private:

public:

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

	UPerfFunction* RoundTripLocale1();
	UPerfFunction* RoundTripLocale10();
	UPerfFunction* RoundTripLocale11();
	UPerfFunction* RoundTripLocale21();
};


#endif // DateTimeRoundTripPerfTest
