/*
 * Copyright (c) 2000, 2006, 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.
 */

package build.tools.javazic;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
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;

        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 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 this is the last zone record, take the last rule info.
            if (!zrec.hasUntil()) {
                tz.setRawOffset(gmtOffset, fromTime);
                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(tz.X_DST);
                        } else {
                            tz.setDSTType(tz.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(tz.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 {
                                        int save = rrec.getSave();
                                        tz.addTransition(fromTime,
                                                         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(tz.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(tz.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() == tz.UNDEF_DST) {
            tz.setDSTType(tz.DST);
        }
        tz.optimize();
        tz.checksum();
        return tz;
    }

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