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

                        // 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
