// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 *******************************************************************************
 * Copyright (C) 2008-2015, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.test.localespi;

import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.TimeZone;

import org.junit.Test;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.text.TimeZoneNames;
import com.ibm.icu.text.TimeZoneNames.NameType;
import com.ibm.icu.util.ULocale;

public class TimeZoneNameTest extends TestFmwk {

    private static final Set<String> ProblematicZones = new HashSet<String>();
    static {
        // Since tzdata2013e, Pacific/Johnston is defined as below:
        //
        //     Link Pacific/Honolulu Pacific/Johnston
        //
        // JDK TimeZone.getDisplayName no longer passes Pacific/Johnston to a
        // TimeZoneNameProvider implementation. As of CLDR 25M1, Pacific/Johnston
        // has a different set of names from Pacific/Honolulu. This test case
        // expects JRE calls a TimeZoneNameProvider without such normalization
        // (and I believe it's a JDK bug). For now, we ignore the test failure
        // caused by Pacific/Johnston with this the JDK problem.
        ProblematicZones.add("Pacific/Johnston");
    }

    @Test
    public void TestTimeZoneNames() {
        Locale[] locales = Locale.getAvailableLocales();
        String[] tzids = TimeZone.getAvailableIDs();

        for (Locale loc : locales) {
            boolean warningOnly = false;
            if (TestUtil.isExcluded(loc)) {
                warningOnly = true;
            }

            for (String tzid : tzids) {
                // Java has a problem when a provider does not supply all 4 names
                // for a zone. For this reason, ICU TimeZoneName provider does not return
                // localized names unless these 4 names are available. 

                String icuStdLong = getIcuDisplayName(tzid, false, TimeZone.LONG, loc);
                String icuDstLong = getIcuDisplayName(tzid, true, TimeZone.LONG, loc);
                String icuStdShort = getIcuDisplayName(tzid, false, TimeZone.SHORT, loc);
                String icuDstShort = getIcuDisplayName(tzid, true, TimeZone.SHORT, loc);

                if (icuStdLong != null && icuDstLong != null && icuStdShort != null && icuDstShort != null) {
                    checkDisplayNamePair(TimeZone.SHORT, tzid, loc, warningOnly || ProblematicZones.contains(tzid));
                    checkDisplayNamePair(TimeZone.LONG, tzid, loc, warningOnly || ProblematicZones.contains(tzid));
                } else {
                    logln("Localized long standard name is not available for "
                            + tzid + " in locale " + loc + " in ICU");
                }
            }
        }
    }

    private void checkDisplayNamePair(int style, String tzid, Locale loc, boolean warnOnly) {
        /* Note: There are two problems here.
         * 
         * It looks Java 6 requires a TimeZoneNameProvider to return both standard name and daylight name
         * for a zone.  If the provider implementation only returns either of them, Java 6 also ignore
         * the other.  In ICU, there are zones which do not have daylight names, especially zones which
         * do not use daylight time.  This test case does not check a standard name if its daylight name
         * is not available because of the Java 6 implementation problem.
         * 
         * Another problem is that ICU always use a standard name for a zone which does not use daylight
         * saving time even daylight name is requested.
         */

        String icuStdName = getIcuDisplayName(tzid, false, style, loc);
        String icuDstName = getIcuDisplayName(tzid, true, style, loc);
        if (icuStdName != null && icuDstName != null && !icuStdName.equals(icuDstName)) {
            checkDisplayName(false, style, tzid, loc, icuStdName, warnOnly);
            checkDisplayName(true, style, tzid, loc, icuDstName, warnOnly);
        }
    }

    private String getIcuDisplayName(String tzid, boolean daylight, int style, Locale loc) {
        String icuName = null;
        boolean[] isSystemID = new boolean[1];
        String canonicalID = com.ibm.icu.util.TimeZone.getCanonicalID(tzid, isSystemID);
        if (isSystemID[0]) {
            long date = System.currentTimeMillis();
            TimeZoneNames tznames = TimeZoneNames.getInstance(ULocale.forLocale(loc));
            switch (style) {
            case TimeZone.LONG:
                icuName = daylight ?
                        tznames.getDisplayName(canonicalID, NameType.LONG_DAYLIGHT, date) :
                        tznames.getDisplayName(canonicalID, NameType.LONG_STANDARD, date);
                break;
            case TimeZone.SHORT:
                icuName = daylight ?
                        tznames.getDisplayName(canonicalID, NameType.SHORT_DAYLIGHT, date) :
                        tznames.getDisplayName(canonicalID, NameType.SHORT_STANDARD, date);
                break;
            }
        }
        return icuName;
    }

    private void checkDisplayName(boolean daylight, int style,  String tzid, Locale loc, String icuname, boolean warnOnly) {
        String styleStr = (style == TimeZone.SHORT) ? "SHORT" : "LONG";
        TimeZone tz = TimeZone.getTimeZone(tzid);
        String name = tz.getDisplayName(daylight, style, loc);

        if (TestUtil.isICUExtendedLocale(loc)) {
            // The name should be taken from ICU
            if (!name.equals(icuname)) {
                if (warnOnly) {
                    logln("WARNING: TimeZone name by ICU is " + icuname + ", but got " + name
                            + " for time zone " + tz.getID() + " in locale " + loc
                            + " (daylight=" + daylight + ", style=" + styleStr + ")");
                    
                } else {
                    errln("FAIL: TimeZone name by ICU is " + icuname + ", but got " + name
                            + " for time zone " + tz.getID() + " in locale " + loc
                            + " (daylight=" + daylight + ", style=" + styleStr + ")");
                }
            }
        } else {
            if (!name.equals(icuname)) {
                logln("INFO: TimeZone name by ICU is " + icuname + ", but got " + name
                        + " for time zone " + tz.getID() + " in locale " + loc
                        + " (daylight=" + daylight + ", style=" + styleStr + ")");
            }
            // Try explicit ICU locale (xx_yy_ICU)
            Locale icuLoc = TestUtil.toICUExtendedLocale(loc);
            name = tz.getDisplayName(daylight, style, icuLoc);
            if (!name.equals(icuname)) {
                if (warnOnly) {
                    logln("WARNING: TimeZone name by ICU is " + icuname + ", but got " + name
                            + " for time zone " + tz.getID() + " in locale " + icuLoc
                            + " (daylight=" + daylight + ", style=" + styleStr + ")");
                } else {
                    errln("FAIL: TimeZone name by ICU is " + icuname + ", but got " + name
                            + " for time zone " + tz.getID() + " in locale " + icuLoc
                            + " (daylight=" + daylight + ", style=" + styleStr + ")");
                }
            }
        }
    }

    @Test
    public void testGetInstance_Locale() {
        TimeZoneNames uLocaleInstance = TimeZoneNames.getInstance(ULocale.CANADA);
        TimeZoneNames localeInstance = TimeZoneNames.getInstance(Locale.CANADA);

        Set<String> uLocaleAvailableIds = uLocaleInstance.getAvailableMetaZoneIDs();
        Set<String> localeAvailableIds = localeInstance.getAvailableMetaZoneIDs();
        assertEquals("Available ids", uLocaleAvailableIds, localeAvailableIds);

        for (String availableId : uLocaleAvailableIds) {
            long date = 1458385200000L;
            TimeZoneNames.NameType nameType = TimeZoneNames.NameType.SHORT_GENERIC;
            String uLocaleName = uLocaleInstance.getDisplayName(availableId, nameType, date);
            String localeName = localeInstance.getDisplayName(availableId, nameType, date);
            assertEquals("Id: " + availableId, uLocaleName, localeName);
        }
    }

    @Test
    public void testGetAvailableMetaZoneIDs() {
        TimeZoneNames japaneseNames = TimeZoneNames.getInstance(ULocale.JAPANESE);
        Set<String> allJapan = japaneseNames.getAvailableMetaZoneIDs();

        TimeZoneNames tzdbNames = TimeZoneNames.getTZDBInstance(ULocale.CHINESE);
        Set<String> tzdbAll = tzdbNames.getAvailableMetaZoneIDs();

        // The data is the same in the current implementation.
        assertEquals("MetaZone IDs different between locales", allJapan, tzdbAll);

        // Make sure that there is something.
        assertTrue("count of zone ids is less than 100", allJapan.size() >= 180);
    }

    @Test
    public void testGetAvailableMetaZoneIDs_String() {
        TimeZoneNames japaneseNames = TimeZoneNames.getInstance(ULocale.JAPANESE);
        assertEquals("Timezone name mismatch", Collections.singleton("America_Pacific"),
                japaneseNames.getAvailableMetaZoneIDs("America/Los_Angeles"));

        TimeZoneNames tzdbNames = TimeZoneNames.getTZDBInstance(ULocale.CHINESE);
        assertEquals("Timezone name mismatch", Collections.singleton("Taipei"),
                tzdbNames.getAvailableMetaZoneIDs("Asia/Taipei"));
    }

    @Test
    public void testGetMetaZoneDisplayName() {
        TimeZoneNames usNames = TimeZoneNames.getInstance(ULocale.US);

        String europeanCentralName = usNames.getMetaZoneDisplayName("Europe_Central",
                TimeZoneNames.NameType.LONG_STANDARD);
        assertEquals("Timezone name mismatch", "Central European Standard Time",
                europeanCentralName);

        TimeZoneNames tzdbNames = TimeZoneNames.getTZDBInstance(ULocale.CHINESE);
        String americaPacificName = tzdbNames.getMetaZoneDisplayName("America_Pacific",
                TimeZoneNames.NameType.SHORT_DAYLIGHT);
        assertEquals("Timezone name mismatch", "PDT", americaPacificName);
    }

    @Test
    public void testGetMetaZoneID() {
        TimeZoneNames usNames = TimeZoneNames.getInstance(ULocale.US);

        String europeanCentralName = usNames.getMetaZoneID("Europe/Paris", 0);
        assertEquals("Timezone name mismatch", "Europe_Central", europeanCentralName);

        TimeZoneNames tzdbNames = TimeZoneNames.getTZDBInstance(ULocale.KOREAN);
        String seoulName = tzdbNames.getMetaZoneID("Asia/Seoul", 0);
        assertEquals("Timezone name mismatch", "Korea", seoulName);

        // Now try Jan 1st 1945 GMT
        seoulName = tzdbNames.getMetaZoneID("Asia/Seoul", -786240000000L);
        assertNull("Timezone name mismatch", seoulName);
    }

    @Test
    public void testGetTimeZoneDisplayName() {
        TimeZoneNames frenchNames = TimeZoneNames.getInstance(ULocale.FRENCH);
        String dublinName = frenchNames.getTimeZoneDisplayName("Europe/Dublin",
                TimeZoneNames.NameType.LONG_DAYLIGHT);
        assertEquals("Timezone name mismatch", "heure d’été irlandaise", dublinName);

        String dublinLocation = frenchNames.getTimeZoneDisplayName("Europe/Dublin",
                TimeZoneNames.NameType.EXEMPLAR_LOCATION);
        assertEquals("Timezone name mismatch", "Dublin", dublinLocation);

        // All the names returned by this are null.
        TimeZoneNames tzdbNames = TimeZoneNames.getTZDBInstance(ULocale.KOREAN);
        for (String tzId : TimeZone.getAvailableIDs()) {
            for (TimeZoneNames.NameType nameType : TimeZoneNames.NameType.values()) {
                String name = tzdbNames.getTimeZoneDisplayName(tzId, nameType);
                assertNull("TZ:" + tzId + ", NameType: " + nameType + ", value: " + name, name);
            }
        }
    }
}
