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

#include "unicode/utypes.h"

#if U_PLATFORM_USES_ONLY_WIN32_API

#if !UCONFIG_NO_FORMATTING

#include "unicode/format.h"
#include "unicode/numfmt.h"
#include "unicode/locid.h"
#include "unicode/ustring.h"
#include "unicode/testlog.h"
#include "unicode/utmscale.h"

#include "windtfmt.h"
#include "winutil.h"
#include "windttst.h"

#include "dtfmttst.h"

#include "cmemory.h"
#include "cstring.h"
#include "locmap.h"
#include "wintzimpl.h"

#   define WIN32_LEAN_AND_MEAN
#   define VC_EXTRALEAN
#   define NOUSER
#   define NOSERVICE
#   define NOIME
#   define NOMCX
#   include <windows.h>

#include <algorithm>

static const char *getCalendarType(int32_t type)
{
    switch (type)
    {
    case 1:
    case 2:
        return "@calendar=gregorian";

    case 3:
        return "@calendar=japanese";

    case 6:
        return "@calendar=islamic";

    case 7:
        return "@calendar=buddhist";

    case 8:
        return "@calendar=hebrew";

    default:
        return "";
    }
}

void Win32DateTimeTest::testLocales(DateFormatTest *log)
{
    SYSTEMTIME winNow;
    UDate icuNow = 0;
    SYSTEMTIME st;
    FILETIME ft;
    UnicodeString zoneID;
    const TimeZone *tz = TimeZone::createDefault();
    TIME_ZONE_INFORMATION tzi;

    tz->getID(zoneID);
    if (! uprv_getWindowsTimeZoneInfo(&tzi, zoneID.getBuffer(), zoneID.length())) {
        UBool found = FALSE;
        int32_t ec = TimeZone::countEquivalentIDs(zoneID);

        for (int z = 0; z < ec; z += 1) {
            UnicodeString equiv = TimeZone::getEquivalentID(zoneID, z);

            found = uprv_getWindowsTimeZoneInfo(&tzi, equiv.getBuffer(), equiv.length());
            if (found) {
                break;
            }
        }

        if (! found) {
            GetTimeZoneInformation(&tzi);
        }
    }

    GetSystemTime(&st);
    SystemTimeToFileTime(&st, &ft);
    SystemTimeToTzSpecificLocalTime(&tzi, &st, &winNow);

    int64_t wftNow = ((int64_t) ft.dwHighDateTime << 32) + ft.dwLowDateTime;
    UErrorCode status = U_ZERO_ERROR;

    int64_t udtsNow = utmscale_fromInt64(wftNow, UDTS_WINDOWS_FILE_TIME, &status);

    icuNow = (UDate) utmscale_toInt64(udtsNow, UDTS_ICU4C_TIME, &status);

    int32_t lcidCount = 0;
    Win32Utilities::LCIDRecord *lcidRecords = Win32Utilities::getLocales(lcidCount);

    for(int i = 0; i < lcidCount; i += 1) {
        UErrorCode status = U_ZERO_ERROR;
        WCHAR longDateFormat[81], longTimeFormat[81], wdBuffer[256], wtBuffer[256];
        DWORD value = 0;
        int32_t calType = 0;

        // NULL localeID means ICU didn't recognize this locale
        if (lcidRecords[i].localeID == NULL) {
            continue;
        }

        // Some locales have had their names change over various OS releases; skip them in the test for now.
        int32_t failingLocaleLCIDs[] = {
            0x040a, /* es-ES_tradnl;es-ES-u-co-trad; */
            0x048c, /* fa-AF;prs-AF;prs-Arab-AF; */
            0x046b, /* qu-BO;quz-BO;quz-Latn-BO; */
            0x086b, /* qu-EC;quz-EC;quz-Latn-EC; */
            0x0c6b, /* qu-PE;quz-PE;quz-Latn-PE; */
            0x0492  /* ckb-IQ;ku-Arab-IQ; */
        };
        bool skip = (std::find(std::begin(failingLocaleLCIDs), std::end(failingLocaleLCIDs), lcidRecords[i].lcid) != std::end(failingLocaleLCIDs));
        if (skip && log->logKnownIssue("13119", "Windows '@compat=host' fails on down-level versions of the OS")) {
            log->logln("ticket:13119 - Skipping LCID = 0x%04x", lcidRecords[i].lcid);
            continue;
        }

        GetLocaleInfoW(lcidRecords[i].lcid, LOCALE_SLONGDATE,   longDateFormat, 81);
        GetLocaleInfoW(lcidRecords[i].lcid, LOCALE_STIMEFORMAT, longTimeFormat, 81);
        GetLocaleInfoW(lcidRecords[i].lcid, LOCALE_RETURN_NUMBER|LOCALE_ICALENDARTYPE, (LPWSTR)&value, sizeof(value)/sizeof(WCHAR));

        calType = value;
        char localeID[64];

        uprv_strcpy(localeID, lcidRecords[i].localeID);
        uprv_strcat(localeID, getCalendarType(calType));

        UnicodeString ubBuffer, udBuffer, utBuffer;
        Locale ulocale(localeID);
        int32_t wdLength, wtLength;

        wdLength = GetDateFormatW(lcidRecords[i].lcid, DATE_LONGDATE, &winNow, NULL, wdBuffer, UPRV_LENGTHOF(wdBuffer));
        wtLength = GetTimeFormatW(lcidRecords[i].lcid, 0, &winNow, NULL, wtBuffer, UPRV_LENGTHOF(wtBuffer));

        if (uprv_strchr(localeID, '@')) {
            uprv_strcat(localeID, ";");
        } else {
            uprv_strcat(localeID, "@");
        }

        uprv_strcat(localeID, "compat=host");

        Locale wlocale(localeID);
        DateFormat *wbf = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, wlocale);
        DateFormat *wdf = DateFormat::createDateInstance(DateFormat::kFull, wlocale);
        DateFormat *wtf = DateFormat::createTimeInstance(DateFormat::kFull, wlocale);

        wbf->format(icuNow, ubBuffer);
        wdf->format(icuNow, udBuffer);
        wtf->format(icuNow, utBuffer);

        if (ubBuffer.indexOf((const UChar *)wdBuffer, wdLength - 1, 0) < 0) {
            UnicodeString baseName(wlocale.getBaseName());
            UnicodeString expected((const UChar *)wdBuffer);

            log->errln("DateTime format error for locale " + baseName + ": expected date \"" + expected +
                       "\" got \"" + ubBuffer + "\"");
        }

        if (ubBuffer.indexOf((const UChar *)wtBuffer, wtLength - 1, 0) < 0) {
            UnicodeString baseName(wlocale.getBaseName());
            UnicodeString expected((const UChar *)wtBuffer);

            log->errln("DateTime format error for locale " + baseName + ": expected time \"" + expected +
                       "\" got \"" + ubBuffer + "\"");
        }

        if (udBuffer.compare((const UChar *)wdBuffer) != 0) {
            UnicodeString baseName(wlocale.getBaseName());
            UnicodeString expected((const UChar *)wdBuffer);

            log->errln("Date format error for locale " + baseName + ": expected \"" + expected +
                       "\" got \"" + udBuffer + "\"");
        }

        if (utBuffer.compare((const UChar *)wtBuffer) != 0) {
            UnicodeString baseName(wlocale.getBaseName());
            UnicodeString expected((const UChar *)wtBuffer);

            log->errln("Time format error for locale " + baseName + ": expected \"" + expected +
                       "\" got \"" + utBuffer + "\"");
        }
        delete wbf;
        delete wdf;
        delete wtf;
    }

    Win32Utilities::freeLocales(lcidRecords);
    delete tz;
}

#endif /* #if !UCONFIG_NO_FORMATTING */

#endif /* U_PLATFORM_USES_ONLY_WIN32_API */
