/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  The Android Open Source
 * Project designates this particular file as subject to the "Classpath"
 * exception as provided by The Android Open Source Project in the LICENSE
 * file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 */

package java.time.zone;

import android.icu.util.AnnualTimeZoneRule;
import android.icu.util.BasicTimeZone;
import android.icu.util.DateTimeRule;
import android.icu.util.InitialTimeZoneRule;
import android.icu.util.TimeZone;
import android.icu.util.TimeZoneRule;
import android.icu.util.TimeZoneTransition;
import java.time.DayOfWeek;
import java.time.LocalTime;
import java.time.Month;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.NavigableMap;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
import libcore.util.BasicLruCache;

/**
 * A ZoneRulesProvider that generates rules from ICU4J TimeZones.
 * This provider ensures that classes in {@link java.time} use the same time zone information
 * as ICU4J.
 */
public class IcuZoneRulesProvider extends ZoneRulesProvider {

    // Arbitrary upper limit to number of transitions including the final rules.
    private static final int MAX_TRANSITIONS = 10000;

    private static final int SECONDS_IN_DAY = 24 * 60 * 60;

    private final BasicLruCache<String, ZoneRules> cache = new ZoneRulesCache(8);

    @Override
    protected Set<String> provideZoneIds() {
        Set<String> zoneIds = TimeZone.getAvailableIDs(TimeZone.SystemTimeZoneType.ANY, null, null);
        zoneIds = new HashSet<>(zoneIds);
        // java.time assumes ZoneId that start with "GMT" fit the pattern "GMT+HH:mm:ss" which these
        // do not. Since they are equivalent to GMT, just remove these aliases.
        zoneIds.remove("GMT+0");
        zoneIds.remove("GMT-0");
        return zoneIds;
    }

    @Override
    protected ZoneRules provideRules(String zoneId, boolean forCaching) {
        // Ignore forCaching, as this is a static provider.
        return cache.get(zoneId);
    }

    @Override
    protected NavigableMap<String, ZoneRules> provideVersions(String zoneId) {
        return new TreeMap<>(
                Collections.singletonMap(TimeZone.getTZDataVersion(),
                        provideRules(zoneId, /* forCaching */ false)));
    }

    /*
     * This implementation is only tested with BasicTimeZone objects and depends on
     * implementation details of that class:
     *
     * 0. TimeZone.getFrozenTimeZone() always returns a BasicTimeZone object.
     * 1. The first rule is always an InitialTimeZoneRule (guaranteed by spec).
     * 2. AnnualTimeZoneRules are only used as "final rules".
     * 3. The final rules are either 0 or 2 AnnualTimeZoneRules
     * 4. The final rules have endYear set to MAX_YEAR.
     * 5. Each transition generated by the rules changes either the raw offset, the total offset
     *    or both.
     * 6. There is a non-immense number of transitions for any rule before the final rules apply
     *    (enforced via the arbitrary limit defined in MAX_TRANSITIONS).
     *
     * Assumptions #5 and #6 are not strictly required for this code to work, but hold for the
     * the data and code at the time of implementation. If they were broken they would indicate
     * an incomplete understanding of how ICU TimeZoneRules are used which would probably mean that
     * this code needs to be updated.
     *
     * These assumptions are verified using the verify() method where appropriate.
     */
    static ZoneRules generateZoneRules(String zoneId) {
        TimeZone timeZone = TimeZone.getFrozenTimeZone(zoneId);
        // Assumption #0
        verify(timeZone instanceof BasicTimeZone, zoneId,
                "Unexpected time zone class " + timeZone.getClass());
        BasicTimeZone tz = (BasicTimeZone) timeZone;
        TimeZoneRule[] rules = tz.getTimeZoneRules();
        // Assumption #1
        InitialTimeZoneRule initial = (InitialTimeZoneRule) rules[0];

        ZoneOffset baseStandardOffset = millisToOffset(initial.getRawOffset());
        ZoneOffset baseWallOffset =
                millisToOffset((initial.getRawOffset() + initial.getDSTSavings()));

        List<ZoneOffsetTransition> standardOffsetTransitionList = new ArrayList<>();
        List<ZoneOffsetTransition> transitionList = new ArrayList<>();
        List<ZoneOffsetTransitionRule> lastRules = new ArrayList<>();

        int preLastDstSavings = 0;
        AnnualTimeZoneRule last1 = null;
        AnnualTimeZoneRule last2 = null;

        TimeZoneTransition transition = tz.getNextTransition(Long.MIN_VALUE, false);
        int transitionCount = 1;
        // This loop has two possible exit conditions (in normal operation):
        // 1. for zones that end with a static value and have no ongoing DST changes, it will exit
        //    via the normal condition (transition != null)
        // 2. for zones with ongoing DST changes (represented by a "final zone" in ICU4J, and by
        //    "last rules" in java.time) the "break transitionLoop" will be used to exit the loop.
        transitionLoop:
        while (transition != null) {
            TimeZoneRule from = transition.getFrom();
            TimeZoneRule to = transition.getTo();
            boolean hadEffect = false;
            if (from.getRawOffset() != to.getRawOffset()) {
                standardOffsetTransitionList.add(new ZoneOffsetTransition(
                        TimeUnit.MILLISECONDS.toSeconds(transition.getTime()),
                        millisToOffset(from.getRawOffset()),
                        millisToOffset(to.getRawOffset())));
                hadEffect = true;
            }
            int fromTotalOffset = from.getRawOffset() + from.getDSTSavings();
            int toTotalOffset = to.getRawOffset() + to.getDSTSavings();
            if (fromTotalOffset != toTotalOffset) {
                transitionList.add(new ZoneOffsetTransition(
                        TimeUnit.MILLISECONDS.toSeconds(transition.getTime()),
                        millisToOffset(fromTotalOffset),
                        millisToOffset(toTotalOffset)));
                hadEffect = true;
            }
            // Assumption #5
            verify(hadEffect, zoneId, "Transition changed neither total nor raw offset.");
            if (to instanceof AnnualTimeZoneRule) {
                // The presence of an AnnualTimeZoneRule is taken as an indication of a final rule.
                if (last1 == null) {
                    preLastDstSavings = from.getDSTSavings();
                    last1 = (AnnualTimeZoneRule) to;
                    // Assumption #4
                    verify(last1.getEndYear() == AnnualTimeZoneRule.MAX_YEAR, zoneId,
                            "AnnualTimeZoneRule is not permanent.");
                } else {
                    last2 = (AnnualTimeZoneRule) to;
                    // Assumption #4
                    verify(last2.getEndYear() == AnnualTimeZoneRule.MAX_YEAR, zoneId,
                            "AnnualTimeZoneRule is not permanent.");

                    // Assumption #3
                    transition = tz.getNextTransition(transition.getTime(), false);
                    verify(transition.getTo() == last1, zoneId,
                            "Unexpected rule after 2 AnnualTimeZoneRules.");
                    break transitionLoop;
                }
            } else {
                // Assumption #2
                verify(last1 == null, zoneId, "Unexpected rule after AnnualTimeZoneRule.");
            }
            verify(transitionCount <= MAX_TRANSITIONS, zoneId,
                    "More than " + MAX_TRANSITIONS + " transitions.");
            transition = tz.getNextTransition(transition.getTime(), false);
            transitionCount++;
        }
        if (last1 != null) {
            // Assumption #3
            verify(last2 != null, zoneId, "Only one AnnualTimeZoneRule.");
            lastRules.add(toZoneOffsetTransitionRule(last1, preLastDstSavings));
            lastRules.add(toZoneOffsetTransitionRule(last2, last1.getDSTSavings()));
        }

        return ZoneRules.of(baseStandardOffset, baseWallOffset, standardOffsetTransitionList,
                transitionList, lastRules);
    }

    /**
     * Verify an assumption about the zone rules.
     *
     * @param check
     *         {@code true} if the assumption holds, {@code false} otherwise.
     * @param zoneId
     *         Zone ID for which to check.
     * @param message
     *         Error description of a failed check.
     * @throws ZoneRulesException
     *         If and only if {@code check} is {@code false}.
     */
    private static void verify(boolean check, String zoneId, String message) {
        if (!check) {
            throw new ZoneRulesException(
                    String.format("Failed verification of zone %s: %s", zoneId, message));
        }
    }

    /**
     * Transform an {@link AnnualTimeZoneRule} into an equivalent {@link ZoneOffsetTransitionRule}.
     * This is only used for the "final rules".
     *
     * @param rule
     *         The rule to transform.
     * @param dstSavingMillisBefore
     *         The DST offset before the first transition in milliseconds.
     */
    private static ZoneOffsetTransitionRule toZoneOffsetTransitionRule(
            AnnualTimeZoneRule rule, int dstSavingMillisBefore) {
        DateTimeRule dateTimeRule = rule.getRule();
        // Calendar.JANUARY is 0, transform it into a proper Month.
        Month month = Month.JANUARY.plus(dateTimeRule.getRuleMonth());
        int dayOfMonthIndicator;
        // Calendar.SUNDAY is 1, transform it into a proper DayOfWeek.
        DayOfWeek dayOfWeek = DayOfWeek.SATURDAY.plus(dateTimeRule.getRuleDayOfWeek());
        switch (dateTimeRule.getDateRuleType()) {
            case DateTimeRule.DOM:
                // Transition always on a specific day of the month.
                dayOfMonthIndicator = dateTimeRule.getRuleDayOfMonth();
                dayOfWeek = null;
                break;
            case DateTimeRule.DOW_GEQ_DOM:
                // ICU representation matches java.time representation.
                dayOfMonthIndicator = dateTimeRule.getRuleDayOfMonth();
                break;
            case DateTimeRule.DOW_LEQ_DOM:
                // java.time uses a negative dayOfMonthIndicator to represent "Sun<=X" or "lastSun"
                // rules. ICU uses this constant and the normal day. So "lastSun" in January would
                // ruleDayOfMonth = 31 in ICU and dayOfMonthIndicator = -1 in java.time.
                dayOfMonthIndicator = -month.maxLength() + dateTimeRule.getRuleDayOfMonth() - 1;
                break;
            case DateTimeRule.DOW:
                // DOW is unspecified in the documentation and seems to never be used.
                throw new ZoneRulesException("Date rule type DOW is unsupported");
            default:
                throw new ZoneRulesException(
                        "Unexpected date rule type: " + dateTimeRule.getDateRuleType());
        }
        // Cast to int is save, as input is int.
        int secondOfDay = (int) TimeUnit.MILLISECONDS.toSeconds(dateTimeRule.getRuleMillisInDay());
        LocalTime time;
        boolean timeEndOfDay;
        if (secondOfDay == SECONDS_IN_DAY) {
            time = LocalTime.MIDNIGHT;
            timeEndOfDay = true;
        } else {
            time = LocalTime.ofSecondOfDay(secondOfDay);
            timeEndOfDay = false;
        }
        ZoneOffsetTransitionRule.TimeDefinition timeDefinition;
        switch (dateTimeRule.getTimeRuleType()) {
            case DateTimeRule.WALL_TIME:
                timeDefinition = ZoneOffsetTransitionRule.TimeDefinition.WALL;
                break;
            case DateTimeRule.STANDARD_TIME:
                timeDefinition = ZoneOffsetTransitionRule.TimeDefinition.STANDARD;
                break;
            case DateTimeRule.UTC_TIME:
                timeDefinition = ZoneOffsetTransitionRule.TimeDefinition.UTC;
                break;
            default:
                throw new ZoneRulesException(
                        "Unexpected time rule type " + dateTimeRule.getTimeRuleType());
        }
        ZoneOffset standardOffset = millisToOffset(rule.getRawOffset());
        ZoneOffset offsetBefore = millisToOffset(rule.getRawOffset() + dstSavingMillisBefore);
        ZoneOffset offsetAfter = millisToOffset(
                rule.getRawOffset() + rule.getDSTSavings());
        return ZoneOffsetTransitionRule.of(
                month, dayOfMonthIndicator, dayOfWeek, time, timeEndOfDay, timeDefinition,
                standardOffset, offsetBefore, offsetAfter);
    }

    private static ZoneOffset millisToOffset(int offset) {
        // Cast to int is save, as input is int.
        return ZoneOffset.ofTotalSeconds((int) TimeUnit.MILLISECONDS.toSeconds(offset));
    }

    private static class ZoneRulesCache extends BasicLruCache<String, ZoneRules> {

        ZoneRulesCache(int maxSize) {
            super(maxSize);
        }

        @Override
        protected ZoneRules create(String zoneId) {
            String canonicalId = TimeZone.getCanonicalID(zoneId);
            if (!canonicalId.equals(zoneId)) {
                // Return the same object as the canonical one, to avoid wasting space, but cache
                // it under the non-cannonical name as well, to avoid future getCanonicalID calls.
                return get(canonicalId);
            }
            return generateZoneRules(zoneId);
        }
    }
}
