/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.tzdata.mts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import android.icu.text.TimeZoneNames;

import org.junit.Test;

import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;

/**
 * Tests relating to time zone rules that could be changed by the time zone data module. These are
 * intended to prove that a time zone data module update hasn't broken behavior. Since time zone
 * rule mutate over time this test could be quite brittle, so it is suggested that only a few
 * examples are tested.
 */
public class TimeZoneRulesTest {

    @Test
    public void preHistoricInDaylightTime() {
        // A zone that lacks an explicit transition at Integer.MIN_VALUE with zic 2019a and 2019a
        // data.
        TimeZone tz = TimeZone.getTimeZone("CET");

        long firstTransitionTimeMillis = -1693706400000L; // Apr 30, 1916 22:00:00 GMT
        assertEquals(7200000L, tz.getOffset(firstTransitionTimeMillis));
        assertTrue(tz.inDaylightTime(new Date(firstTransitionTimeMillis)));

        long beforeFirstTransitionTimeMillis = firstTransitionTimeMillis - 1;
        assertEquals(3600000L, tz.getOffset(beforeFirstTransitionTimeMillis));
        assertFalse(tz.inDaylightTime(new Date(beforeFirstTransitionTimeMillis)));
    }

    @Test
    public void getDisplayNameShort_nonHourOffsets() {
        TimeZone iranTz = TimeZone.getTimeZone("Asia/Tehran");
        assertEquals("GMT+03:30", iranTz.getDisplayName(false, TimeZone.SHORT, Locale.UK));
        assertEquals("GMT+04:30", iranTz.getDisplayName(true, TimeZone.SHORT, Locale.UK));
    }

    @Test
    public void minimalTransitionZones() throws Exception {
        // Zones with minimal transitions, historical or future, seem ideal for testing.
        // UTC is also included, although it may be implemented differently from the others.
        String[] ids = new String[] { "Africa/Bujumbura", "Indian/Cocos", "Pacific/Wake", "UTC" };
        for (String id : ids) {
            TimeZone tz = TimeZone.getTimeZone(id);
            assertFalse(tz.useDaylightTime());
            assertFalse(tz.inDaylightTime(new Date(Integer.MIN_VALUE)));
            assertFalse(tz.inDaylightTime(new Date(0)));
            assertFalse(tz.inDaylightTime(new Date(Integer.MAX_VALUE)));
            int currentOffset = tz.getOffset(new Date(0).getTime());
            assertEquals(currentOffset, tz.getOffset(new Date(Integer.MIN_VALUE).getTime()));
            assertEquals(currentOffset, tz.getOffset(new Date(Integer.MAX_VALUE).getTime()));
        }
    }

    @Test
    public void getDSTSavings() throws Exception {
      assertEquals(0, TimeZone.getTimeZone("UTC").getDSTSavings());
      assertEquals(3600000, TimeZone.getTimeZone("America/Los_Angeles").getDSTSavings());
      assertEquals(1800000, TimeZone.getTimeZone("Australia/Lord_Howe").getDSTSavings());
    }

    // http://b/7955614 and http://b/8026776.
    @Test
    public void displayNames() throws Exception {
        checkDisplayNames(Locale.US);
    }

    @Test
    public void displayNames_nonUS() throws Exception {
        // run checkDisplayNames with an arbitrary set of Locales.
        checkDisplayNames(Locale.CHINESE);
        checkDisplayNames(Locale.FRENCH);
        checkDisplayNames(Locale.forLanguageTag("bn-BD"));
    }

    private static void checkDisplayNames(Locale locale) throws Exception {
        // Check that there are no time zones that use DST but have the same display name for
        // both standard and daylight time.
        StringBuilder failures = new StringBuilder();
        for (String id : TimeZone.getAvailableIDs()) {
            TimeZone tz = TimeZone.getTimeZone(id);
            String longDst = tz.getDisplayName(true, TimeZone.LONG, locale);
            String longStd = tz.getDisplayName(false, TimeZone.LONG, locale);
            String shortDst = tz.getDisplayName(true, TimeZone.SHORT, locale);
            String shortStd = tz.getDisplayName(false, TimeZone.SHORT, locale);

            if (tz.useDaylightTime()) {
                // The long std and dst strings must differ!
                if (longDst.equals(longStd)) {
                    failures.append(String.format("\n%20s: LD='%s' LS='%s'!",
                                                  id, longDst, longStd));
                }
                // The short std and dst strings must differ!
                if (shortDst.equals(shortStd)) {
                    failures.append(String.format("\n%20s: SD='%s' SS='%s'!",
                                                  id, shortDst, shortStd));
                }

                // If the short std matches the long dst, or the long std matches the short dst,
                // it probably means we have a time zone that icu4c doesn't believe has ever
                // observed dst.
                if (shortStd.equals(longDst)) {
                    failures.append(String.format("\n%20s: SS='%s' LD='%s'!",
                                                  id, shortStd, longDst));
                }
                if (longStd.equals(shortDst)) {
                    failures.append(String.format("\n%20s: LS='%s' SD='%s'!",
                                                  id, longStd, shortDst));
                }

                // The long and short dst strings must differ!
                if (longDst.equals(shortDst) && !longDst.startsWith("GMT")) {
                  failures.append(String.format("\n%20s: LD='%s' SD='%s'!",
                                                id, longDst, shortDst));
                }
            }

            // Confidence check that whenever a display name is just a GMT string that it's the
            // right GMT string.
            String gmtDst = formatGmtString(tz, true);
            String gmtStd = formatGmtString(tz, false);
            if (isGmtString(longDst) && !longDst.equals(gmtDst)) {
                failures.append(String.format("\n%s: LD %s", id, longDst));
            }
            if (isGmtString(longStd) && !longStd.equals(gmtStd)) {
                failures.append(String.format("\n%s: LS %s", id, longStd));
            }
            if (isGmtString(shortDst) && !shortDst.equals(gmtDst)) {
                failures.append(String.format("\n%s: SD %s", id, shortDst));
            }
            if (isGmtString(shortStd) && !shortStd.equals(gmtStd)) {
                failures.append(String.format("\n%s: SS %s", id, shortStd));
            }
        }
        assertEquals("", failures.toString());
    }

    private static boolean isGmtString(String s) {
        return s.startsWith("GMT+") || s.startsWith("GMT-");
    }

    private static String formatGmtString(TimeZone tz, boolean daylight) {
        int offset = tz.getRawOffset();
        if (daylight) {
            offset += tz.getDSTSavings();
        }
        offset /= 60000;
        char sign = '+';
        if (offset < 0) {
            sign = '-';
            offset = -offset;
        }
        return String.format("GMT%c%02d:%02d", sign, offset / 60, offset % 60);
    }

    /**
     * This test is to catch issues with the rules update process that could let the
     * "negative DST" scheme enter the Android data set for either java.util.TimeZone or
     * android.icu.util.TimeZone.
     */
    @Test
    public void dstMeansSummer() {
        // Ireland was the original example that caused the default IANA upstream tzdata to contain
        // a zone where DST is in the Winter (since tzdata 2018e, though it was tried in 2018a
        // first). This change was made to historical and future transitions.
        //
        // The upstream reasoning went like this: "Irish *Standard* Time" is summer, so the other
        // time must be the DST. So, DST is considered to be in the winter and the associated DST
        // adjustment is negative from the standard time. In the old scheme "Irish Standard Time" /
        // summer was just modeled as the DST in common with all other global time zones.
        //
        // Unfortunately, various users of formatting APIs assume standard and DST times are
        // consistent and (effectively) that "DST" means "summer". We likely cannot adopt the
        // concept of a winter DST without risking app compat issues.
        //
        // For example, getDisplayName(boolean daylight) has always returned the winter time for
        // false, and the summer time for true. If we change this then it should be changed on a
        // major release boundary, with improved APIs (e.g. a version of getDisplayName() that takes
        // a millis), existing API behavior made dependent on target API version, and after fixing
        // any platform code that makes incorrect assumptions about DST meaning "1 hour forward".

        final String timeZoneId = "Europe/Dublin";
        final Locale locale = Locale.UK;
        // 26 Oct 2015 01:00:00 GMT - one day after the start of "Greenwich Mean Time" in
        // Europe/Dublin in 2015. An arbitrary historical example of winter in Ireland.
        final long winterTimeMillis = 1445821200000L;
        final String winterTimeName = "Greenwich Mean Time";
        final int winterOffsetRawMillis = 0;
        final int winterOffsetDstMillis = 0;

        // 30 Mar 2015 01:00:00 GMT - one day after the start of "Irish Standard Time" in
        // Europe/Dublin in 2015. An arbitrary historical example of summer in Ireland.
        final long summerTimeMillis = 1427677200000L;
        final String summerTimeName = "Irish Standard Time";
        final int summerOffsetRawMillis = 0;
        final int summerOffsetDstMillis = (int) TimeUnit.HOURS.toMillis(1);

        // There is no common interface between java.util.TimeZone and android.icu.util.TimeZone
        // so the tests are for each are effectively duplicated.

        // java.util.TimeZone
        {
            java.util.TimeZone timeZone = java.util.TimeZone.getTimeZone(timeZoneId);
            assertTrue(timeZone.useDaylightTime());

            assertFalse(timeZone.inDaylightTime(new Date(winterTimeMillis)));
            assertTrue(timeZone.inDaylightTime(new Date(summerTimeMillis)));

            assertEquals(winterOffsetRawMillis + winterOffsetDstMillis,
                    timeZone.getOffset(winterTimeMillis));
            assertEquals(summerOffsetRawMillis + summerOffsetDstMillis,
                    timeZone.getOffset(summerTimeMillis));
            assertEquals(winterTimeName,
                    timeZone.getDisplayName(false /* daylight */, java.util.TimeZone.LONG,
                            locale));
            assertEquals(summerTimeName,
                    timeZone.getDisplayName(true /* daylight */, java.util.TimeZone.LONG,
                            locale));
        }

        // android.icu.util.TimeZone
        {
            android.icu.util.TimeZone timeZone = android.icu.util.TimeZone.getTimeZone(timeZoneId);
            assertTrue(timeZone.useDaylightTime());

            assertFalse(timeZone.inDaylightTime(new Date(winterTimeMillis)));
            assertTrue(timeZone.inDaylightTime(new Date(summerTimeMillis)));

            assertEquals(winterOffsetRawMillis + winterOffsetDstMillis,
                    timeZone.getOffset(winterTimeMillis));
            assertEquals(summerOffsetRawMillis + summerOffsetDstMillis,
                    timeZone.getOffset(summerTimeMillis));

            // These methods show the trouble we'd have if callers were to take the output from
            // inDaylightTime() and pass it to getDisplayName().
            assertEquals(winterTimeName,
                    timeZone.getDisplayName(false /* daylight */, android.icu.util.TimeZone.LONG,
                            locale));
            assertEquals(summerTimeName,
                    timeZone.getDisplayName(true /* daylight */, android.icu.util.TimeZone.LONG,
                            locale));

            // APIs not identical to java.util.TimeZone tested below.
            int[] offsets = new int[2];
            timeZone.getOffset(winterTimeMillis, false /* local */, offsets);
            assertEquals(winterOffsetRawMillis, offsets[0]);
            assertEquals(winterOffsetDstMillis, offsets[1]);

            timeZone.getOffset(summerTimeMillis, false /* local */, offsets);
            assertEquals(summerOffsetRawMillis, offsets[0]);
            assertEquals(summerOffsetDstMillis, offsets[1]);
        }

        // icu TimeZoneNames
        TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale);
        // getDisplayName: date = winterTimeMillis
        assertEquals(winterTimeName, timeZoneNames.getDisplayName(
                timeZoneId, TimeZoneNames.NameType.LONG_STANDARD, winterTimeMillis));
        assertEquals(summerTimeName, timeZoneNames.getDisplayName(
                timeZoneId, TimeZoneNames.NameType.LONG_DAYLIGHT, winterTimeMillis));
        // getDisplayName: date = summerTimeMillis
        assertEquals(winterTimeName, timeZoneNames.getDisplayName(
                timeZoneId, TimeZoneNames.NameType.LONG_STANDARD, summerTimeMillis));
        assertEquals(summerTimeName, timeZoneNames.getDisplayName(
                timeZoneId, TimeZoneNames.NameType.LONG_DAYLIGHT, summerTimeMillis));
    }

    /**
     * ICU's time zone IDs may be a superset of IDs available via other APIs.
     */
    @Test
    public void timeZoneIdsKnown() {
        // java.util
        List<String> zoneInfoDbAvailableIds = Arrays.asList(java.util.TimeZone.getAvailableIDs());
        checkZoneIdsAreKnownToIcu(zoneInfoDbAvailableIds);

        // java.time
        checkZoneIdsAreKnownToIcu(ZoneId.getAvailableZoneIds());
    }

    private static void checkZoneIdsAreKnownToIcu(Collection<String> zoneInfoDbAvailableIds) {
        // ICU has a known set of IDs. We want ANY because we don't want to filter to ICU's
        // canonical IDs only.
        Set<String> icuAvailableIds = android.icu.util.TimeZone.getAvailableIDs(
                android.icu.util.TimeZone.SystemTimeZoneType.ANY, null /* region */,
                null /* rawOffset */);

        List<String> nonIcuAvailableIds = new ArrayList<>();
        List<String> creationFailureIds = new ArrayList<>();
        List<String> noCanonicalLookupIds = new ArrayList<>();
        List<String> nonSystemIds = new ArrayList<>();
        for (String zoneInfoDbId : zoneInfoDbAvailableIds) {
            if (!icuAvailableIds.contains(zoneInfoDbId)) {
                nonIcuAvailableIds.add(zoneInfoDbId);
            }

            boolean[] isSystemId = new boolean[1];
            String canonicalId = android.icu.util.TimeZone.getCanonicalID(zoneInfoDbId, isSystemId);
            if (canonicalId == null) {
                noCanonicalLookupIds.add(zoneInfoDbId);
            }
            if (!isSystemId[0]) {
                nonSystemIds.add(zoneInfoDbId);
            }

            android.icu.util.TimeZone icuTimeZone =
                    android.icu.util.TimeZone.getTimeZone(zoneInfoDbId);
            if (icuTimeZone.getID().equals(android.icu.util.TimeZone.UNKNOWN_ZONE_ID)) {
                creationFailureIds.add(zoneInfoDbId);
            }
        }
        assertTrue("Non-ICU available IDs: " + nonIcuAvailableIds
                        + ", creation failed IDs: " + creationFailureIds
                        + ", non-system IDs: " + nonSystemIds
                        + ", ids without canonical IDs: " + noCanonicalLookupIds,
                nonIcuAvailableIds.isEmpty()
                        && creationFailureIds.isEmpty()
                        && nonSystemIds.isEmpty()
                        && noCanonicalLookupIds.isEmpty());
    }
}
