/*
 * Copyright (c) 2000, 2004, 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.util.ArrayList;
import java.util.List;

/**
 * Timezone represents all information of a single point of time to
 * generate its time zone database.
 *
 * @since 1.4
 */
class Timezone {
    /**
     * zone name of this time zone
     */
    private String name;

    /**
     * transition time values in UTC (millisecond)
     */
    private List<Long> transitions;

    /**
     * All offset values in millisecond
     * @see sun.util.calendar.ZoneInfo
     */
    private List<Integer> offsets;

    /**
     * Indices of GMT offset values (both raw and raw+saving)
     * at transitions
     */
    private List<Integer> gmtOffsets;

    /**
     * Indices of regular or "direct" saving time values
     * at transitions
     */
    private List<Integer> dstOffsets;

    /**
     * Zone records of this time zone
     */
    private List<ZoneRec> usedZoneRecs;

    /**
     * Rule records referred to by this time zone
     */
    private List<RuleRec> usedRuleRecs;

    /**
     * Type of DST rules in this time zone
     */
    private int dstType;
    static final int UNDEF_DST = 0;     // DST type not set yet
    static final int NO_DST = 1;        // never observed DST
    static final int LAST_DST = 2;      // last rule ends in DST (all year round DST-only)
    static final int X_DST = 3;         // used to observe DST
    static final int DST = 4;           // observing DST regularly

    /**
     * Raw GMT offset of this time zone in the last rule
     */
    private int rawOffset;

    /**
     * The CRC32 value of the transitions data
     */
    private int crc32;

    /**
     * The last ZoneRec
     */
    private ZoneRec lastZoneRec;

    /**
     * The last DST rules. lastRules[0] is the DST start
     * rule. lastRules[1] is the DST end rules.
     */
    private List<RuleRec> lastRules;

    /**
     * The amount of DST saving value (millisecond) in the last DST
     * rule.
     */
    private int lastSaving;

    /**
     * true if the raw offset will change in the future time.
     */
    private boolean willRawOffsetChange = false;


    /**
     * Constracts a Timezone object with the given zone name.
     * @param name the zone name
     */
    Timezone(String name) {
        this.name = name;
    }

    /**
     * @return the number of transitions
     */
    int getNTransitions() {
        if (transitions == null) {
            return 0;
        }
        return transitions.size();
    }

    /**
     * @return the zone name
     */
    String getName() {
        return name;
    }

    /**
     * Returns the list of all rule records that have been referred to
     * by this time zone.
     * @return the rule records list
     */
    List<RuleRec> getRules() {
        return usedRuleRecs;
    }

    /**
     * Returns the list of all zone records that have been referred to
     * by this time zone.
     * @return the zone records list
     */
    List<ZoneRec> getZones() {
        return usedZoneRecs;
    }

    /**
     * @return the transition table (list)
     */
    List<Long> getTransitions() {
        return transitions;
    }

    /**
     * @return the offsets list
     */
    List<Integer> getOffsets() {
        return offsets;
    }

    /**
     * @return the DST saving offsets list
     */
    List<Integer> getDstOffsets() {
        return dstOffsets;
    }

    /**
     * @return the GMT offsets list
     */
    List<Integer> getGmtOffsets() {
        return gmtOffsets;
    }

    /**
     * @return the checksum (crc32) value of the trasition table
     */
    int getCRC32() {
        return crc32;
    }

    /**
     * @return true if the GMT offset of this time zone would change
     * after the time zone database has been generated, false, otherwise.
     */
    boolean willGMTOffsetChange() {
        return willRawOffsetChange;
    }

    /**
     * @return the last known GMT offset value in milliseconds
     */
    int getRawOffset() {
        return rawOffset;
    }

    /**
     * Sets time zone's GMT offset to <code>offset</code>.
     * @param offset the GMT offset value in milliseconds
     */
    void setRawOffset(int offset) {
        rawOffset = offset;
    }

    /**
     * Sets time zone's GMT offset value to <code>offset</code>. If
     * <code>startTime</code> is future time, then the {@link
     * #willRawOffsetChange} value is set to true.
     * @param offset the GMT offset value in milliseconds
     * @param startTime the UTC time at which the GMT offset is in effective
     */
    void setRawOffset(int offset, long startTime) {
        // if this rawOffset is for the future time, let the run-time
        // look for the current GMT offset.
        if (startTime > Time.getCurrentTime()) {
            willRawOffsetChange = true;
        }
        setRawOffset(offset);
    }

    /**
     * Adds the specified transition information to the end of the transition table.
     * @param time the UTC time at which this transition happens
     * @param offset the total amount of the offset from GMT in milliseconds
     * @param dstOffset the amount of time in milliseconds saved at this transition
     */
    void addTransition(long time, int offset, int dstOffset) {
        if (transitions == null) {
            transitions = new ArrayList<Long>();
            offsets = new ArrayList<Integer>();
            dstOffsets = new ArrayList<Integer>();
        }
        transitions.add(time);
        offsets.add(offset);
        dstOffsets.add(dstOffset);
    }

    /**
     * Sets the type of historical daylight saving time
     * observation. For example, China used to observed daylight
     * saving time, but it no longer does. Then, X_DST is set to the
     * China time zone.
     * @param type the type of daylight saving time
     */
    void setDSTType(int type) {
        dstType = type;
    }

    /**
     * @return the type of historical daylight saving time
     * observation.
     */
    int getDSTType() {
        return dstType;
    }

    /**
     * Adds the specified zone record to the zone records list.
     * @param rec the zone record
     */
    void addUsedRec(ZoneRec rec) {
        if (usedZoneRecs == null) {
            usedZoneRecs = new ArrayList<ZoneRec>();
        }
        usedZoneRecs.add(rec);
    }

    /**
     * Adds the specified rule record to the rule records list.
     * @param rec the rule record
     */
    void addUsedRec(RuleRec rec) {
        if (usedRuleRecs == null) {
            usedRuleRecs = new ArrayList<RuleRec>();
        }
        // if the last used rec is the same as the given rec, avoid
        // putting the same rule.
        int n = usedRuleRecs.size();
        for (int i = 0; i < n; i++) {
            if (usedRuleRecs.get(i).equals(rec)) {
                return;
            }
        }
        usedRuleRecs.add(rec);
    }

    /**
     * Sets the last zone record for this time zone.
     * @param the last zone record
     */
    void setLastZoneRec(ZoneRec zrec) {
        lastZoneRec = zrec;
    }

    /**
     * @return the last zone record for this time zone.
     */
    ZoneRec getLastZoneRec() {
        return lastZoneRec;
    }

    /**
     * Sets the last rule records for this time zone. Those are used
     * for generating SimpleTimeZone parameters.
     * @param rules the last rule records
     */
    void setLastRules(List<RuleRec> rules) {
        int n = rules.size();
        if (n > 0) {
            lastRules = rules;
            RuleRec rec = rules.get(0);
            int offset = rec.getSave();
            if (offset > 0) {
                setLastDSTSaving(offset);
            } else {
                System.err.println("\t    No DST starting rule in the last rules.");
            }
        }
    }

    /**
     * @return the last rule records for this time zone.
     */
    List<RuleRec> getLastRules() {
        return lastRules;
    }

    /**
     * Sets the last daylight saving amount.
     * @param the daylight saving amount
     */
    void setLastDSTSaving(int offset) {
        lastSaving = offset;
    }

    /**
     * @return the last daylight saving amount.
     */
    int getLastDSTSaving() {
        return lastSaving;
    }

    /**
     * Calculates the CRC32 value from the transition table and sets
     * the value to <code>crc32</code>.
     */
    void checksum() {
        if (transitions == null) {
            crc32 = 0;
            return;
        }
        Checksum sum = new Checksum();
        for (int i = 0; i < transitions.size(); i++) {
            int offset = offsets.get(i);
            // adjust back to make the transition in local time
            sum.update(transitions.get(i) + offset);
            sum.update(offset);
            sum.update(dstOffsets.get(i));
        }
        crc32 = (int)sum.getValue();
    }

    /**
     * Removes unnecessary transitions for Java time zone support.
     */
    void optimize() {
        // if there is only one offset, delete all transitions. This
        // could happen if only time zone abbreviations changed.
        if (gmtOffsets.size() == 1) {
            transitions = null;
            usedRuleRecs =  null;
            setDSTType(NO_DST);
            return;
        }
        for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one
            if (transitions.get(i) == transitions.get(i+1)) {
                transitions.remove(i);
                offsets.remove(i);
                dstOffsets.remove(i);
                i--;
            }
        }

        for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one
            if (offsets.get(i) == offsets.get(i+1)
                && dstOffsets.get(i) == dstOffsets.get(i+1)) {
                transitions.remove(i+1);
                offsets.remove(i+1);
                dstOffsets.remove(i+1);
                i--;
            }
        }
    }

    /**
     * Stores the specified offset value from GMT in the GMT offsets
     * table and returns its index. The offset value includes the base
     * GMT offset and any additional daylight saving if applicable. If
     * the same value as the specified offset is already in the table,
     * its index is returned.
     * @param offset the offset value in milliseconds
     * @return the index to the offset value in the GMT offsets table.
     */
    int getOffsetIndex(int offset) {
        return getOffsetIndex(offset, 0);
    }

    /**
     * Stores the specified daylight saving value in the GMT offsets
     * table and returns its index. If the same value as the specified
     * offset is already in the table, its index is returned. If 0 is
     * specified, it's not stored in the table and -1 is returned.
     * @param offset the offset value in milliseconds
     * @return the index to the specified offset value in the GMT
     * offsets table, or -1 if 0 is specified.
     */
    int getDstOffsetIndex(int offset) {
        if (offset == 0) {
            return -1;
        }
        return getOffsetIndex(offset, 1);
    }

    private int getOffsetIndex(int offset, int index) {
        if (gmtOffsets == null) {
            gmtOffsets = new ArrayList<Integer>();
        }
        for (int i = index; i < gmtOffsets.size(); i++) {
            if (offset == gmtOffsets.get(i)) {
                return i;
            }
        }
        if (gmtOffsets.size() < index) {
            gmtOffsets.add(0);
        }
        gmtOffsets.add(offset);
        return gmtOffsets.size() - 1;
    }
}
