/*
 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * Zoneinfo provides javazic compiler front-end functionality.
 * @since 1.4
 */
class Zoneinfo {

    private static final int minYear = 1900;
    private static final int maxYear = 2037;
    private static final long minTime = Time.getLocalTime(minYear, Month.JANUARY, 1, 0);
    private static int startYear = minYear;
    private static int endYear = maxYear;

    /**
     * True if javazic should generate a list of SimpleTimeZone
     * instances for the SimpleTimeZone-based time zone support.
     */
    static boolean isYearForTimeZoneDataSpecified = false;

    /**
     * Zone name to Zone mappings
     */
    private Map<String,Zone> zones;

    /**
     * Rule name to Rule mappings
     */
    private Map<String,Rule> rules;

    /**
     * Alias name to real name mappings
     */
    private Map<String,String> aliases;

    /**
     * Constracts a Zoneinfo.
     */
    Zoneinfo() {
        zones = new HashMap<String,Zone>();
        rules = new HashMap<String,Rule>();
        aliases = new HashMap<String,String>();
    }

    /**
     * Adds the given zone to the list of Zones.
     * @param zone Zone to be added to the list.
     */
    void add(Zone zone) {
        String name = zone.getName();
        zones.put(name, zone);
    }

    /**
     * Adds the given rule to the list of Rules.
     * @param rule Rule to be added to the list.
     */
    void add(Rule rule) {
        String name = rule.getName();
        rules.put(name, rule);
    }

    /**
     * Puts the specifid name pair to the alias table.
     * @param name1 an alias time zone name
     * @param name2 the real time zone of the alias name
     */
    void putAlias(String name1, String name2) {
        aliases.put(name1, name2);
    }

    /**
     * Sets the given year for SimpleTimeZone list output.
     * This method is called when the -S option is specified.
     * @param year the year for which SimpleTimeZone list should be generated
     */
    static void setYear(int year) {
        setStartYear(year);
        setEndYear(year);
        isYearForTimeZoneDataSpecified = true;
    }

    /**
     * Sets the start year.
     * @param year the start year value
     * @throws IllegalArgumentException if the specified year value is
     * smaller than the minimum year or greater than the end year.
     */
    static void setStartYear(int year) {
        if (year < minYear || year > endYear) {
            throw new IllegalArgumentException("invalid start year specified: " + year);
        }
        startYear = year;
    }

    /**
     * @return the start year value
     */
    static int getStartYear() {
        return startYear;
    }

    /**
     * Sets the end year.
     * @param year the end year value
     * @throws IllegalArgumentException if the specified year value is
     * smaller than the start year or greater than the maximum year.
     */
    static void setEndYear(int year) {
        if (year < startYear || year > maxYear) {
            throw new IllegalArgumentException();
        }
        endYear = year;
    }

    /**
     * @return the end year value
     */
    static int getEndYear() {
        return endYear;
    }

    /**
     * @return the minimum year value
     */
    static int getMinYear() {
        return minYear;
    }

    /**
     * @return the maximum year value
     */
    static int getMaxYear() {
        return maxYear;
    }

    /**
     * @return the alias table
     */
    Map<String,String> getAliases() {
        return aliases;
    }

    /**
     * @return the Zone list
     */
    Map<String,Zone> getZones() {
        return zones;
    }

    /**
     * @return a Zone specified by name.
     * @param name a zone name
     */
    Zone getZone(String name) {
        return zones.get(name);
    }

    /**
     * @return a Rule specified by name.
     * @param name a rule name
     */
    Rule getRule(String name) {
        return rules.get(name);
    }

    private static String line;

    private static int lineNum;

    /**
     * Parses the specified time zone data file and creates a Zoneinfo
     * that has all Rules, Zones and Links (aliases) information.
     * @param fname the time zone data file name
     * @return a Zoneinfo object
     */
    static Zoneinfo parse(String fname) {
        BufferedReader in = null;
        try {
            FileReader fr = new FileReader(fname);
            in = new BufferedReader(fr);
        } catch (FileNotFoundException e) {
            panic("can't open file: "+fname);
        }
        Zoneinfo zi = new Zoneinfo();
        boolean continued = false;
        Zone zone = null;
        String l;
        lineNum = 0;

        try {
            while ((line = in.readLine()) != null) {
                lineNum++;
                // skip blank and comment lines
                if (line.length() == 0 || line.charAt(0) == '#') {
                    continue;
                }

                // trim trailing comments
                int rindex = line.lastIndexOf('#');
                if (rindex != -1) {
                    // take the data part of the line
                    l = line.substring(0, rindex);
                } else {
                    l = line;
                }

                StringTokenizer tokens = new StringTokenizer(l);
                if (!tokens.hasMoreTokens()) {
                    continue;
                }
                String token = tokens.nextToken();

                if (continued || "Zone".equals(token)) {
                    if (zone == null) {
                        if (!tokens.hasMoreTokens()) {
                            panic("syntax error: zone no more token");
                        }
                        token = tokens.nextToken();
                        // if the zone name is in "GMT+hh" or "GMT-hh"
                        // format, ignore it due to spec conflict.
                        if (token.startsWith("GMT+") || token.startsWith("GMT-")) {
                            continue;
                        }
                        zone = new Zone(token);
                    } else {
                        // no way to push the current token back...
                        tokens = new StringTokenizer(l);
                    }

                    ZoneRec zrec = ZoneRec.parse(tokens);
                    zrec.setLine(line);
                    zone.add(zrec);
                    if ((continued = zrec.hasUntil()) == false) {
                        if (Zone.isTargetZone(zone.getName())) {
                            // zone.resolve(zi);
                            zi.add(zone);
                        }
                        zone = null;
                    }
                } else if ("Rule".equals(token)) {
                    if (!tokens.hasMoreTokens()) {
                        panic("syntax error: rule no more token");
                    }
                    token = tokens.nextToken();
                    Rule rule = zi.getRule(token);
                    if (rule == null) {
                        rule = new Rule(token);
                        zi.add(rule);
                    }
                    RuleRec rrec = RuleRec.parse(tokens);
                    rrec.setLine(line);
                    rule.add(rrec);
                } else if ("Link".equals(token)) {
                    // Link <newname> <oldname>
                    try {
                        String name1 = tokens.nextToken();
                        String name2 = tokens.nextToken();

                        // if the zone name is in "GMT+hh" or "GMT-hh"
                        // format, ignore it due to spec conflict with
                        // custom time zones. Also, ignore "ROC" for
                        // PC-ness.
                        if (name2.startsWith("GMT+") || name2.startsWith("GMT-")
                            || "ROC".equals(name2)) {
                            continue;
                        }
                        zi.putAlias(name2, name1);
                    } catch (Exception e) {
                        panic("syntax error: no more token for Link");
                    }
                }
            }
            in.close();
        } catch (IOException ex) {
            panic("IO error: " + ex.getMessage());
        }

        return zi;
    }

    /**
     * Interprets a zone and constructs a Timezone object that
     * contains enough information on GMT offsets and DST schedules to
     * generate a zone info database.
     *
     * @param zoneName the zone name for which a Timezone object is
     * constructed.
     *
     * @return a Timezone object that contains all GMT offsets and DST
     * rules information.
     */
    Timezone phase2(String zoneName) {
        Timezone tz = new Timezone(zoneName);
        Zone zone = getZone(zoneName);
        zone.resolve(this);

        // TODO: merge phase2's for the regular and SimpleTimeZone ones.
        if (isYearForTimeZoneDataSpecified) {
            ZoneRec zrec = zone.get(zone.size()-1);
            tz.setLastZoneRec(zrec);
            tz.setRawOffset(zrec.getGmtOffset());
            if (zrec.hasRuleReference()) {
                /*
                 * This part assumes that the specified year is covered by
                 * the rules referred to by the last zone record.
                 */
                List<RuleRec> rrecs = zrec.getRuleRef().getRules(startYear);

                if (rrecs.size() == 2) {
                    // make sure that one is a start rule and the other is
                    // an end rule.
                    RuleRec r0 = rrecs.get(0);
                    RuleRec r1 = rrecs.get(1);
                    if (r0.getSave() == 0 && r1.getSave() > 0) {
                        rrecs.set(0, r1);
                        rrecs.set(1, r0);
                    } else if (!(r0.getSave() > 0 && r1.getSave() == 0)) {
                        rrecs = null;
                        Main.error(zoneName + ": rules for " +  startYear + " not found.");
                    }
                } else {
                    rrecs = null;
                }
                if (rrecs != null) {
                    tz.setLastRules(rrecs);
                }
            }
            return tz;
        }

        int gmtOffset;
        int year = minYear;
        int fromYear = year;
        long fromTime = Time.getLocalTime(startYear,
                                          Month.JANUARY,
                                          1, 0);

        // take the index 0 for the GMT offset of the last zone record
        ZoneRec zrec = zone.get(zone.size()-1);
        tz.getOffsetIndex(zrec.getGmtOffset());

        int lastGmtOffsetValue = -1;
        int currentSave = 0;
        boolean usedZone;
        for (int zindex = 0; zindex < zone.size(); zindex++) {
            zrec = zone.get(zindex);
            usedZone = false;
            gmtOffset = zrec.getGmtOffset();
            int stdOffset = zrec.getDirectSave();

            if (gmtOffset != lastGmtOffsetValue) {
                tz.setRawOffset(gmtOffset, fromTime);
                lastGmtOffsetValue = gmtOffset;
            }
            // If this is the last zone record, take the last rule info.
            if (!zrec.hasUntil()) {
                if (zrec.hasRuleReference()) {
                    tz.setLastRules(zrec.getRuleRef().getLastRules());
                } else if (stdOffset != 0) {
                    // in case the last rule is all year round DST-only
                    // (Asia/Amman once announced this rule.)
                    tz.setLastDSTSaving(stdOffset);
                }
            }
            if (!zrec.hasRuleReference()) {
                if (!zrec.hasUntil() || zrec.getUntilTime(stdOffset) >= fromTime) {
                    tz.addTransition(fromTime,
                                     tz.getOffsetIndex(gmtOffset+stdOffset),
                                     tz.getDstOffsetIndex(stdOffset));
                    usedZone = true;
                }
                currentSave = stdOffset;
                // optimization in case the last rule is fixed.
                if (!zrec.hasUntil()) {
                    if (tz.getNTransitions() > 0) {
                        if (stdOffset == 0) {
                            tz.setDSTType(Timezone.X_DST);
                        } else {
                            tz.setDSTType(Timezone.LAST_DST);
                        }
                        long time = Time.getLocalTime(maxYear,
                                                      Month.JANUARY, 1, 0);
                        time -= zrec.getGmtOffset();
                        tz.addTransition(time,
                                         tz.getOffsetIndex(gmtOffset+stdOffset),
                                         tz.getDstOffsetIndex(stdOffset));
                        tz.addUsedRec(zrec);
                    } else {
                        tz.setDSTType(Timezone.NO_DST);
                    }
                    break;
                }
            } else {
                Rule rule = zrec.getRuleRef();
                boolean fromTimeUsed = false;
                currentSave = 0;
            year_loop:
                for (year = getMinYear(); year <= endYear; year++) {
                    if (zrec.hasUntil() && year > zrec.getUntilYear()) {
                        break;
                    }
                    List<RuleRec> rules = rule.getRules(year);
                    if (rules.size() > 0) {
                        for (int i = 0; i < rules.size(); i++) {
                            RuleRec rrec = rules.get(i);
                            long transition = rrec.getTransitionTime(year,
                                                                     gmtOffset,
                                                                     currentSave);
                            if (zrec.hasUntil()) {
                                if (transition >= zrec.getUntilTime(currentSave)) {
                                    break year_loop;
                                }
                            }

                            if (fromTimeUsed == false) {
                                if (fromTime <= transition) {
                                    fromTimeUsed = true;

                                    if (fromTime != minTime) {
                                        int prevsave;

                                        ZoneRec prevzrec = zone.get(zindex - 1);

                                        // See if until time in the previous
                                        // ZoneRec is the same thing as the
                                        // local time in the next rule.
                                        // (examples are Asia/Ashkhabad in 1991,
                                        // Europe/Riga in 1989)

                                        if (i > 0) {
                                            prevsave = rules.get(i-1).getSave();
                                        } else {
                                            List<RuleRec> prevrules = rule.getRules(year-1);

                                            if (prevrules.size() > 0) {
                                                prevsave = prevrules.get(prevrules.size()-1).getSave();
                                            } else {
                                                prevsave = 0;
                                            }
                                        }

                                        if (rrec.isSameTransition(prevzrec, prevsave, gmtOffset)) {
                                            currentSave = rrec.getSave();
                                            tz.addTransition(fromTime,
                                                         tz.getOffsetIndex(gmtOffset+currentSave),
                                                         tz.getDstOffsetIndex(currentSave));
                                            tz.addUsedRec(rrec);
                                            usedZone = true;
                                            continue;
                                        }
                                        if (!prevzrec.hasRuleReference()
                                            || rule != prevzrec.getRuleRef()
                                            || (rule == prevzrec.getRuleRef()
                                                && gmtOffset != prevzrec.getGmtOffset())) {
                                            int save = (fromTime == transition) ? rrec.getSave() : currentSave;
                                            tz.addTransition(fromTime,
                                                         tz.getOffsetIndex(gmtOffset+save),
                                                         tz.getDstOffsetIndex(save));
                                            tz.addUsedRec(rrec);
                                            usedZone = true;
                                        }
                                    } else {  // fromTime == minTime
                                        int save = rrec.getSave();
                                        tz.addTransition(minTime,
                                                         tz.getOffsetIndex(gmtOffset),
                                                         tz.getDstOffsetIndex(0));

                                        tz.addTransition(transition,
                                                         tz.getOffsetIndex(gmtOffset+save),
                                                         tz.getDstOffsetIndex(save));

                                        tz.addUsedRec(rrec);
                                        usedZone = true;
                                    }
                                } else if (year == fromYear && i == rules.size()-1) {
                                    int save = rrec.getSave();
                                    tz.addTransition(fromTime,
                                                     tz.getOffsetIndex(gmtOffset+save),
                                                     tz.getDstOffsetIndex(save));
                                }
                            }

                            currentSave = rrec.getSave();
                            if (fromTime < transition) {
                                tz.addTransition(transition,
                                                 tz.getOffsetIndex(gmtOffset+currentSave),
                                                 tz.getDstOffsetIndex(currentSave));
                                tz.addUsedRec(rrec);
                                usedZone = true;
                            }
                        }
                    } else {
                        if (year == fromYear) {
                            tz.addTransition(fromTime,
                                             tz.getOffsetIndex(gmtOffset+currentSave),
                                             tz.getDstOffsetIndex(currentSave));
                            fromTimeUsed = true;
                        }
                        if (year == endYear && !zrec.hasUntil()) {
                            if (tz.getNTransitions() > 0) {
                                // Assume that this Zone stopped DST
                                tz.setDSTType(Timezone.X_DST);
                                long time = Time.getLocalTime(maxYear, Month.JANUARY,
                                                              1, 0);
                                time -= zrec.getGmtOffset();
                                tz.addTransition(time,
                                                 tz.getOffsetIndex(gmtOffset),
                                                 tz.getDstOffsetIndex(0));
                                usedZone = true;
                            } else {
                                tz.setDSTType(Timezone.NO_DST);
                            }
                        }
                    }
                }
            }
            if (usedZone) {
                tz.addUsedRec(zrec);
            }
            if (zrec.hasUntil() && zrec.getUntilTime(currentSave) > fromTime) {
                fromTime = zrec.getUntilTime(currentSave);
                fromYear = zrec.getUntilYear();
                year = zrec.getUntilYear();
            }
        }

        if (tz.getDSTType() == Timezone.UNDEF_DST) {
            tz.setDSTType(Timezone.DST);
        }
        tz.optimize();
        tz.checksum();
        return tz;
    }

    private static void panic(String msg) {
        Main.panic(msg);
    }
}
