/*
 * Copyright (C) 2017 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 com.android.libcore.timezone.tzlookup;

import com.android.libcore.timezone.tzlookup.proto.CountryZonesFile;
import com.android.libcore.timezone.tzlookup.zonetree.CountryZoneTree;
import com.android.libcore.timezone.tzlookup.zonetree.CountryZoneUsage;
import com.android.libcore.timezone.util.Errors;
import com.android.libcore.timezone.util.Errors.HaltExecutionException;
import com.ibm.icu.util.BasicTimeZone;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.GregorianCalendar;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.TimeZoneRule;

import java.io.IOException;
import java.text.ParseException;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.xml.stream.XMLStreamException;

/**
 * Generates the tzlookup.xml file using the information from countryzones.txt and zones.tab.
 *
 * See {@link #main(String[])} for commandline information.
 */
public final class TzLookupGenerator {

    /**
     * The start time (inclusive) for calculating country zone rules. 19700101 00:00:00 UTC. Chosen
     * because this is the point in time for which the tzdb zone.tab data is supposed to be correct.
     */
    public static final Instant ZONE_USAGE_CALCS_START = Instant.EPOCH;

    /**
     * The end time (exclusive) for generating country zone usage. 20380119 03:14:07 UTC. Any times
     * after this will be considered "infinity" for the "notAfter" value and not included. Chosen
     * because this is a "nice round number" and has historical significance for people that deal
     * with computer time. There is no particular reason to choose this over another time; any
     * future time after the last time we expect the code to reasonably encounter will do.
     */
    public static final Instant ZONE_USAGE_NOT_AFTER_CUT_OFF =
            Instant.ofEpochSecond(Integer.MAX_VALUE);

    /**
     * The end time (exclusive) for calculating country zone usage. The time zone periods are
     * calculated to this point. The main requirement is that it's after
     * {@link #ZONE_USAGE_NOT_AFTER_CUT_OFF} by an amount larger than the usual daylight savings
     * period; here we use 2 years.
     */
    public static final Instant ZONE_USAGE_CALCS_END =
            ZONE_USAGE_NOT_AFTER_CUT_OFF.plus(2 * 365, ChronoUnit.DAYS);

    private final String countryZonesFile;
    private final String zoneTabFile;
    private final String backwardFile;
    private final String outputFile;

    /**
     * Executes the generator.
     */
    public static void main(String[] args) throws Exception {
        if (args.length != 4) {
            System.err.println(
                    "usage: java com.android.libcore.timezone.tzlookup.TzLookupGenerator"
                            + " <input proto file> <zone.tab file> <backward file>"
                            + " <output xml file>");
            System.exit(0);
        }
        boolean success = new TzLookupGenerator(args[0], args[1], args[2], args[3]).execute();
        System.exit(success ? 0 : 1);
    }

    TzLookupGenerator(String countryZonesFile, String zoneTabFile, String backwardFile,
            String outputFile) {
        this.countryZonesFile = countryZonesFile;
        this.zoneTabFile = zoneTabFile;
        this.backwardFile = backwardFile;
        this.outputFile = outputFile;
    }

    boolean execute() {
        Errors errors = new Errors();
        try {
            // Parse the countryzones input file.
            CountryZonesFile.CountryZones countryZonesIn =
                    parseAndValidateCountryZones(countryZonesFile, errors);

            // Check the countryzones.txt rules version matches the version that ICU is using.
            String icuTzDataVersion = TimeZone.getTZDataVersion();
            String inputIanaVersion = countryZonesIn.getIanaVersion();
            if (!icuTzDataVersion.equals(inputIanaVersion)) {
                throw errors.addFatalAndHalt("Input data (countryzones.txt) is for "
                        + inputIanaVersion + " but the ICU you have is for " + icuTzDataVersion);
            }


            // Pull out information we want to validate against from zone.tab (which we have to
            // assume matches the ICU version since it doesn't contain its own version info).
            Map<String, List<String>> zoneTabMapping = parseZoneTabFile(zoneTabFile, errors);

            List<CountryZonesFile.Country> countriesIn = countryZonesIn.getCountriesList();
            List<String> countriesInIsos = CountryZonesFileSupport.extractIsoCodes(countriesIn);

            // Sanity check the countryzones file only contains lower-case country codes. The output
            // file uses them and the on-device code assumes lower case.
            if (!Utils.allLowerCaseAscii(countriesInIsos)) {
                throw errors.addFatalAndHalt(
                        "Non-lowercase country ISO codes found in: " + countriesInIsos);
            }
            // Sanity check the countryzones file doesn't contain duplicate country entries.
            if (!Utils.allUnique(countriesInIsos)) {
                throw errors.addFatalAndHalt(
                        "Duplicate input country entries found: " + countriesInIsos);
            }

            // Validate the country iso codes found in the countryzones.txt against those in
            // zone.tab. zone.tab uses upper case, countryzones uses lower case.
            List<String> upperCaseCountriesInIsos = Utils.toUpperCase(countriesInIsos);
            Set<String> timezonesCountryIsos = new HashSet<>(upperCaseCountriesInIsos);
            Set<String> zoneTabCountryIsos = zoneTabMapping.keySet();
            if (!zoneTabCountryIsos.equals(timezonesCountryIsos)) {
                throw errors.addFatalAndHalt(zoneTabFile + " contains "
                        + Utils.subtract(zoneTabCountryIsos, timezonesCountryIsos)
                        + " not present in countryzones, "
                        + countryZonesFile + " contains "
                        + Utils.subtract(timezonesCountryIsos, zoneTabCountryIsos)
                        + " not present in zonetab.");
            }

            // Obtain and validate a mapping from old IDs to new IDs.
            Map<String, String> zoneIdLinks = parseAndValidateBackwardFile(backwardFile, errors);
            errors.throwIfError("Errors accumulated");

            TzLookupFile.TimeZones timeZonesOut = createOutputTimeZones(
                    inputIanaVersion, zoneTabMapping, countriesIn, zoneIdLinks, errors);
            errors.throwIfError("Errors accumulated");

            // Write the output structure if there wasn't an error.
            logInfo("Writing " + outputFile);
            try {
                TzLookupFile.write(timeZonesOut, outputFile);
            } catch (XMLStreamException e) {
                throw errors.addFatalAndHalt("Unable to write output file", e);
            }
            return true;
        } catch (HaltExecutionException | IOException e) {
            logError("Stopping due to fatal condition", e);
            return false;
        } finally {
            // Report all warnings / errors
            if (!errors.isEmpty()) {
                logInfo("Issues:\n" + errors.asString());
            }
        }
    }

    private Map<String, List<String>> parseZoneTabFile(String zoneTabFile, Errors errors)
            throws HaltExecutionException {
        errors.pushScope("Parsing " + zoneTabFile);
        try {
            ZoneTabFile zoneTabIn;
            zoneTabIn = ZoneTabFile.parse(zoneTabFile);
            return ZoneTabFile.createCountryToOlsonIdsMap(zoneTabIn);
        } catch (ParseException | IOException e) {
            throw errors.addFatalAndHalt("Unable to parse " + zoneTabFile, e);
        } finally {
            errors.popScope();
        }
    }

    /**
     * Load the backward file and return the links contained within. This is used as the source of
     * equivalent time zone IDs.
     */
    private static Map<String, String> parseAndValidateBackwardFile(
            String backwardFile, Errors errors) {
        errors.pushScope("Parsing " + backwardFile);
        try {
            BackwardFile backwardIn = BackwardFile.parse(backwardFile);

            // Validate the links.
            Map<String, String> zoneIdLinks = backwardIn.getDirectLinks();
            zoneIdLinks.forEach(
                    (k, v) -> {
                        if (invalidTimeZoneId(k)) {
                            errors.addError("Bad 'from' link: " + k + "->" + v);
                        }
                        if (invalidTimeZoneId(v)) {
                            errors.addError("Bad 'to' link: " + k + "->" + v);
                        }
                    });
            return zoneIdLinks;
        } catch (ParseException | IOException e) {
            errors.addError("Unable to parse " + backwardFile, e);
            return null;
        } finally {
            errors.popScope();
        }
    }

    private static CountryZonesFile.CountryZones parseAndValidateCountryZones(
            String countryZonesFile, Errors errors) throws HaltExecutionException {
        errors.pushScope("Parsing " + countryZonesFile);
        try {
            CountryZonesFile.CountryZones countryZonesIn;
            countryZonesIn = CountryZonesFileSupport.parseCountryZonesTextFile(countryZonesFile);
            return countryZonesIn;
        } catch (ParseException | IOException e) {
            throw errors.addFatalAndHalt("Unable to parse " + countryZonesFile, e);
        } finally {
            errors.popScope();
        }
    }

    private static TzLookupFile.TimeZones createOutputTimeZones(String inputIanaVersion,
            Map<String, List<String>> zoneTabMapping, List<CountryZonesFile.Country> countriesIn,
            Map<String, String> zoneIdLinks, Errors errors)
            throws HaltExecutionException {

        // Start constructing the output structure.
        TzLookupFile.TimeZones timeZonesOut = new TzLookupFile.TimeZones(inputIanaVersion);
        TzLookupFile.CountryZones countryZonesOut = new TzLookupFile.CountryZones();
        timeZonesOut.setCountryZones(countryZonesOut);

        // The time use when sampling the offsets for a zone.
        final long offsetSampleTimeMillis = getSampleOffsetTimeMillisForData(inputIanaVersion);

        // The start time to use when working out whether a zone has used UTC.
        // We don't care about historical use of UTC (e.g. parts of Europe like France prior
        // to WW2) so we start looking at the beginning of "this year".
        long everUseUtcStartTimeMillis = getYearStartTimeMillisForData(inputIanaVersion);

        // Process each Country.
        for (CountryZonesFile.Country countryIn : countriesIn) {
            String isoCode = countryIn.getIsoCode();
            List<String> zoneTabCountryTimeZoneIds = zoneTabMapping.get(isoCode.toUpperCase());
            if (zoneTabCountryTimeZoneIds == null) {
                errors.addError("Country=" + isoCode + " missing from zone.tab");
                // No point in continuing.
                continue;
            }

            TzLookupFile.Country countryOut = processCountry(
                    offsetSampleTimeMillis, everUseUtcStartTimeMillis, countryIn,
                    zoneTabCountryTimeZoneIds, zoneIdLinks, errors);
            if (countryOut == null) {
                // Continue processing countries if there are only errors.
                continue;
            }
            countryZonesOut.addCountry(countryOut);
        }
        errors.throwIfError("One or more countries failed");
        return timeZonesOut;
    }

    private static TzLookupFile.Country processCountry(long offsetSampleTimeMillis,
            long everUseUtcStartTimeMillis, CountryZonesFile.Country countryIn,
            List<String> zoneTabCountryTimeZoneIds, Map<String, String> zoneIdLinks,
            Errors errors) {
        String isoCode = countryIn.getIsoCode();
        errors.pushScope("country=" + isoCode);
        try {
            // Each Country must have >= 1 time zone.
            List<CountryZonesFile.TimeZoneMapping> timeZonesIn =
                    countryIn.getTimeZoneMappingsList();
            if (timeZonesIn.isEmpty()) {
                errors.addError("No time zones");
                // No point in continuing.
                return null;
            }

            List<String> countryTimeZoneIds = CountryZonesFileSupport.extractIds(timeZonesIn);

            // Look for duplicate time zone IDs.
            if (!Utils.allUnique(countryTimeZoneIds)) {
                errors.addError("country's zones=" + countryTimeZoneIds + " contains duplicates");
                // No point in continuing.
                return null;
            }

            // Each Country needs a default time zone ID (but we can guess in some cases).
            String defaultTimeZoneId = determineCountryDefaultZoneId(countryIn, errors);
            if (defaultTimeZoneId == null) {
                // No point in continuing.
                return null;
            }
            boolean defaultTimeZoneBoost =
                    determineCountryDefaultTimeZoneBoost(countryIn, errors);

            // Validate the default.
            if (!countryTimeZoneIds.contains(defaultTimeZoneId)) {
                errors.addError("defaultTimeZoneId=" + defaultTimeZoneId
                        + " is not one of the country's zones=" + countryTimeZoneIds);
                // No point in continuing.
                return null;
            }

            // Validate the other zone IDs.
            try {
                errors.pushScope("validate country zone ids");
                for (String countryTimeZoneId : countryTimeZoneIds) {
                    if (invalidTimeZoneId(countryTimeZoneId)) {
                        errors.addError("countryTimeZoneId=" + countryTimeZoneId
                                + " is not a valid zone ID");
                    }
                }
                if (errors.hasError()) {
                    // No point in continuing.
                    return null;
                }
            } finally {
                errors.popScope();
            }

            // Work out the hint for whether the country uses a zero offset from UTC.
            boolean everUsesUtc = anyZonesUseUtc(countryTimeZoneIds, everUseUtcStartTimeMillis);

            // Validate the country information against the equivalent information in zone.tab.
            errors.pushScope("zone.tab comparison");
            try {
                // Look for unexpected duplicate time zone IDs in zone.tab
                if (!Utils.allUnique(zoneTabCountryTimeZoneIds)) {
                    errors.addError("Duplicate time zone IDs found:" + zoneTabCountryTimeZoneIds);
                    // No point in continuing.
                    return null;
                }

                // Validate the IDs being used against the IANA data for the country. If it fails
                // the countryzones.txt needs to be updated with new IDs (or an alias can be added
                // if there's some reason to keep using the old ID).
                validateCountryZonesTzIdsAgainstIana(isoCode, zoneTabCountryTimeZoneIds,
                        timeZonesIn, zoneIdLinks, errors);
                if (errors.hasError()) {
                    // No point in continuing.
                    return null;
                }
            } finally {
                errors.popScope();
            }

            // Calculate countryZoneUsage.
            CountryZoneUsage countryZoneUsage = calculateCountryZoneUsage(countryIn, errors);
            if (countryZoneUsage == null) {
                // No point in continuing with this country.
                return null;
            }

            // Add the country to the output structure.
            TzLookupFile.Country countryOut = new TzLookupFile.Country(
                    isoCode, defaultTimeZoneId, defaultTimeZoneBoost, everUsesUtc);

            // Process each input time zone.
            for (CountryZonesFile.TimeZoneMapping timeZoneIn : timeZonesIn) {
                errors.pushScope(
                        "id=" + timeZoneIn.getId() + ", offset=" + timeZoneIn.getUtcOffset()
                                + ", shownInPicker=" + timeZoneIn.getShownInPicker());
                try {
                    // Validate the offset information in countryIn.
                    validateNonDstOffset(offsetSampleTimeMillis, countryIn, timeZoneIn, errors);

                    String timeZoneInId = timeZoneIn.getId();
                    boolean shownInPicker = timeZoneIn.getShownInPicker();
                    if (!countryZoneUsage.hasEntry(timeZoneInId)) {
                        // This implies a programming error.
                        errors.addError("No entry in CountryZoneUsage for " + timeZoneInId);
                        return null;
                    }

                    // The notUsedAfterInstant can be null if the zone is used until at least
                    // ZONE_CALCS_END_INSTANT. That's what we want.
                    Instant notUsedAfterInstant =
                            countryZoneUsage.getNotUsedAfterInstant(timeZoneInId);

                    // Add the id mapping and associated metadata.
                    TzLookupFile.TimeZoneMapping timeZoneIdOut =
                            new TzLookupFile.TimeZoneMapping(
                                    timeZoneInId, shownInPicker, notUsedAfterInstant);
                    countryOut.addTimeZoneIdentifier(timeZoneIdOut);
                } finally {
                    errors.popScope();
                }
            }
            return countryOut;
        } finally{
            // End of country processing.
            errors.popScope();
        }
    }

    private static void validateCountryZonesTzIdsAgainstIana(String isoCode,
            List<String> zoneTabCountryTimeZoneIds,
            List<CountryZonesFile.TimeZoneMapping> timeZoneMappings,
            Map<String, String> zoneIdLinks, Errors errors) {

        List<String> expectedIanaTimeZoneIds = new ArrayList<>();
        for (CountryZonesFile.TimeZoneMapping mapping : timeZoneMappings) {
            String timeZoneId = mapping.getId();
            String expectedIanaTimeZoneId;
            if (!mapping.hasAliasId()) {
                expectedIanaTimeZoneId = timeZoneId;
            } else {
                String aliasTimeZoneId = mapping.getAliasId();

                // Confirm the alias is valid.
                if (!aliasTimeZoneId.equals(zoneIdLinks.get(timeZoneId))) {
                    errors.addError(timeZoneId + " does not link to " + aliasTimeZoneId);
                    return;
                }
                expectedIanaTimeZoneId = aliasTimeZoneId;
            }
            expectedIanaTimeZoneIds.add(expectedIanaTimeZoneId);
        }

        if (!Utils.setEquals(zoneTabCountryTimeZoneIds, expectedIanaTimeZoneIds)) {
            errors.addError("IANA lists " + isoCode
                    + " as having zones: " + zoneTabCountryTimeZoneIds
                    + ", but countryzones has " + expectedIanaTimeZoneIds);
        }
    }

    /**
     * Determines the default zone ID for the country.
     */
    private static String determineCountryDefaultZoneId(
            CountryZonesFile.Country countryIn, Errors errors) {
        List<CountryZonesFile.TimeZoneMapping> timeZonesIn = countryIn.getTimeZoneMappingsList();
        String defaultTimeZoneId;
        if (countryIn.hasDefaultTimeZoneId()) {
            defaultTimeZoneId = countryIn.getDefaultTimeZoneId();
            if (invalidTimeZoneId(defaultTimeZoneId)) {
                errors.addError(
                        "Default time zone ID " + defaultTimeZoneId + " is not valid");
                // No point in continuing.
                return null;
            }
        } else {
            if (timeZonesIn.size() > 1) {
                errors.addError(
                        "To pick a default time zone there must be a single offset group");
                // No point in continuing.
                return null;
            }
            defaultTimeZoneId = timeZonesIn.get(0).getId();
        }
        return defaultTimeZoneId;
    }

    /**
     * Determines the defaultTimeZoneBoost value for the country.
     */
    private static boolean determineCountryDefaultTimeZoneBoost(
            CountryZonesFile.Country countryIn, Errors errors) {
        if (!countryIn.hasDefaultTimeZoneBoost()) {
            return false;
        }

        boolean defaultTimeZoneBoost = countryIn.getDefaultTimeZoneBoost();
        if (!countryIn.hasDefaultTimeZoneId() && defaultTimeZoneBoost) {
            errors.addError(
                    "defaultTimeZoneBoost is specified but defaultTimeZoneId is not explicit");
        }

        return defaultTimeZoneBoost;
    }

    /**
     * Returns true if any of the zones use UTC after the time specified.
     */
    private static boolean anyZonesUseUtc(List<String> timeZoneIds, long startTimeMillis) {
        for (String timeZoneId : timeZoneIds) {
            BasicTimeZone timeZone = (BasicTimeZone) TimeZone.getTimeZone(timeZoneId);
            TimeZoneRule[] rules = timeZone.getTimeZoneRules(startTimeMillis);
            for (TimeZoneRule rule : rules) {
                int utcOffset = rule.getRawOffset() + rule.getDSTSavings();
                if (utcOffset == 0) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Returns a sample time related to the IANA version to enable any offset validation to be
     * repeatable (rather than depending on the current time when the tool is run).
     */
    private static long getSampleOffsetTimeMillisForData(String inputIanaVersion) {
        // Uses <year>/07/02 12:00:00 UTC, where year is taken from the IANA version + 1.
        // This is fairly arbitrary, but reflects the fact that we want a point in the future
        // WRT to the data, and once a year has been picked then half-way through seems about right.
        Calendar calendar = getYearStartForData(inputIanaVersion);
        calendar.set(calendar.get(Calendar.YEAR) + 1, Calendar.JULY, 2, 12, 0, 0);
        return calendar.getTimeInMillis();
    }

    /**
     * Returns the 1st Jan 00:00:00 UTC time on the year the IANA version relates to. Therefore
     * guaranteed to be before the data is ever used and can be treated as "the beginning of time"
     * (assuming derived information won't be used for historical calculations).
     */
    private static long getYearStartTimeMillisForData(String inputIanaVersion) {
        return getYearStartForData(inputIanaVersion).getTimeInMillis();
    }

    private static Calendar getYearStartForData(String inputIanaVersion) {
        String yearString = inputIanaVersion.substring(0, inputIanaVersion.length() - 1);
        int year = Integer.parseInt(yearString);
        Calendar calendar = new GregorianCalendar(TimeZone.GMT_ZONE);
        calendar.clear();
        calendar.set(year, Calendar.JANUARY, 1, 0, 0, 0);
        return calendar;
    }

    private static boolean invalidTimeZoneId(String timeZoneId) {
        TimeZone zone = TimeZone.getTimeZone(timeZoneId);
        return !(zone instanceof BasicTimeZone) || zone.getID().equals(TimeZone.UNKNOWN_ZONE_ID);
    }

    private static void validateNonDstOffset(long offsetSampleTimeMillis,
            CountryZonesFile.Country country, CountryZonesFile.TimeZoneMapping timeZoneIn,
            Errors errors) {
        String utcOffsetString = timeZoneIn.getUtcOffset();
        long utcOffsetMillis;
        try {
            utcOffsetMillis = Utils.parseUtcOffsetToMillis(utcOffsetString);
        } catch (ParseException e) {
            errors.addError("Bad offset string: " + utcOffsetString);
            return;
        }

        final long minimumGranularity = TimeUnit.MINUTES.toMillis(15);
        if (utcOffsetMillis % minimumGranularity != 0) {
            errors.addWarning(
                    "Unexpected granularity: not a multiple of 15 minutes: " + utcOffsetString);
        }

        String timeZoneIdIn = timeZoneIn.getId();
        if (invalidTimeZoneId(timeZoneIdIn)) {
            errors.addError("Time zone ID=" + timeZoneIdIn + " is not valid");
            return;
        }

        // Check the offset Android has matches what ICU thinks.
        TimeZone timeZone = TimeZone.getTimeZone(timeZoneIdIn);
        int[] offsets = new int[2];
        timeZone.getOffset(offsetSampleTimeMillis, false /* local */, offsets);
        int actualOffsetMillis = offsets[0];
        if (actualOffsetMillis != utcOffsetMillis) {
            errors.addError("Offset mismatch: You will want to confirm the ordering for "
                    + country.getIsoCode() + " still makes sense. Raw offset for "
                    + timeZoneIdIn + " is " + Utils.toUtcOffsetString(actualOffsetMillis)
                    + " and not " + Utils.toUtcOffsetString(utcOffsetMillis)
                    + " at " + Utils.formatUtc(offsetSampleTimeMillis));
        }
    }

    private static CountryZoneUsage calculateCountryZoneUsage(
            CountryZonesFile.Country countryIn, Errors errors) {
        errors.pushScope("Building zone tree");
        try {
            CountryZoneTree countryZoneTree = CountryZoneTree.create(
                    countryIn, ZONE_USAGE_CALCS_START, ZONE_USAGE_CALCS_END);
            List<String> countryIssues = countryZoneTree.validateNoPriorityClashes();
            if (!countryIssues.isEmpty()) {
                errors.addError("Issues validating country zone trees. Adjust priorities:");
                countryIssues.forEach(errors::addError);
                return null;
            }
            return countryZoneTree.calculateCountryZoneUsage(ZONE_USAGE_NOT_AFTER_CUT_OFF);
        } finally {
            errors.popScope();
        }
    }

    private static void logError(String msg) {
        System.err.println("E: " + msg);
    }

    private static void logError(String s, Throwable e) {
        logError(s);
        e.printStackTrace(System.err);
    }

    private static void logInfo(String msg) {
        System.err.println("I: " + msg);
    }
}
