// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
 /*
  *******************************************************************************
  * Copyright (C) 2005-2016, International Business Machines Corporation and
  * others. All Rights Reserved.
  *******************************************************************************
  */
package com.ibm.icu.impl;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.MissingResourceException;

import com.ibm.icu.util.AnnualTimeZoneRule;
import com.ibm.icu.util.BasicTimeZone;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.DateTimeRule;
import com.ibm.icu.util.GregorianCalendar;
import com.ibm.icu.util.InitialTimeZoneRule;
import com.ibm.icu.util.SimpleTimeZone;
import com.ibm.icu.util.TimeArrayTimeZoneRule;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.TimeZoneRule;
import com.ibm.icu.util.TimeZoneTransition;
import com.ibm.icu.util.UResourceBundle;

/**
 * A time zone based on the Olson tz database.  Olson time zones change
 * behavior over time.  The raw offset, rules, presence or absence of
 * daylight savings time, and even the daylight savings amount can all
 * vary.
 *
 * This class uses a resource bundle named "zoneinfo".  Zoneinfo is a
 * table containing different kinds of resources.  In several places,
 * zones are referred to using integers.  A zone's integer is a number
 * from 0..n-1, where n is the number of zones, with the zones sorted
 * in lexicographic order.
 *
 * 1. Zones.  These have keys corresponding to the Olson IDs, e.g.,
 * "Asia/Shanghai".  Each resource describes the behavior of the given
 * zone.  Zones come in two different formats.
 *
 *   a. Zone (table).  A zone is a table resource contains several
 *   type of resources below:
 *
 *   - typeOffsets:intvector (Required)
 *
 *   Sets of UTC raw/dst offset pairs in seconds.  Entries at
 *   2n represents raw offset and 2n+1 represents dst offset
 *   paired with the raw offset at 2n.  The very first pair represents
 *   the initial zone offset (before the first transition) always.
 *
 *   - trans:intvector (Optional)
 *
 *   List of transition times represented by 32bit seconds from the
 *   epoch (1970-01-01T00:00Z) in ascending order.
 *
 *   - transPre32/transPost32:intvector (Optional)
 *
 *   List of transition times before/after 32bit minimum seconds.
 *   Each time is represented by a pair of 32bit integer.
 *
 *   - typeMap:bin (Optional)
 *
 *   Array of bytes representing the mapping between each transition
 *   time (transPre32/trans/transPost32) and its corresponding offset
 *   data (typeOffsets).
 *
 *   - finalRule:string (Optional)
 *
 *   If a recurrent transition rule is applicable to a zone forever
 *   after the final transition time, finalRule represents the rule
 *   in Rules data.
 *
 *   - finalRaw:int (Optional)
 *
 *   When finalRule is available, finalRaw is required and specifies
 *   the raw (base) offset of the rule.
 *
 *   - finalYear:int (Optional)
 *
 *   When finalRule is available, finalYear is required and specifies
 *   the start year of the rule.
 *
 *   - links:intvector (Optional)
 *
 *   When this zone data is shared with other zones, links specifies
 *   all zones including the zone itself.  Each zone is referenced by
 *   integer index.
 *
 *  b. Link (int, length 1).  A link zone is an int resource.  The
 *  integer is the zone number of the target zone.  The key of this
 *  resource is an alternate name for the target zone.  This data
 *  is corresponding to Link data in the tz database.
 *
 *
 * 2. Rules.  These have keys corresponding to the Olson rule IDs,
 * with an underscore prepended, e.g., "_EU".  Each resource describes
 * the behavior of the given rule using an intvector, containing the
 * onset list, the cessation list, and the DST savings.  The onset and
 * cessation lists consist of the month, dowim, dow, time, and time
 * mode.  The end result is that the 11 integers describing the rule
 * can be passed directly into the SimpleTimeZone 13-argument
 * constructor (the other two arguments will be the raw offset, taken
 * from the complex zone element 5, and the ID string, which is not
 * used), with the times and the DST savings multiplied by 1000 to
 * scale from seconds to milliseconds.
 *
 * 3. Regions.  An array specifies mapping between zones and regions.
 * Each item is either a 2-letter ISO country code or "001"
 * (UN M.49 - World).  This data is generated from "zone.tab"
 * in the tz database.
 */
public class OlsonTimeZone extends BasicTimeZone {

    // Generated by serialver from JDK 1.4.1_01
    static final long serialVersionUID = -6281977362477515376L;

    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#getOffset(int, int, int, int, int, int)
     */
    @Override
    public int getOffset(int era, int year, int month, int day, int dayOfWeek, int milliseconds) {
        if (month < Calendar.JANUARY || month > Calendar.DECEMBER) {
            throw new IllegalArgumentException("Month is not in the legal range: " +month);
        } else {
            return getOffset(era, year, month, day, dayOfWeek, milliseconds, Grego.monthLength(year, month));
        }
    }

    /**
     * TimeZone API.
     */
    public int getOffset(int era, int year, int month,int dom, int dow, int millis, int monthLength){

        if ((era != GregorianCalendar.AD && era != GregorianCalendar.BC)
            || month < Calendar.JANUARY
            || month > Calendar.DECEMBER
            || dom < 1
            || dom > monthLength
            || dow < Calendar.SUNDAY
            || dow > Calendar.SATURDAY
            || millis < 0
            || millis >= Grego.MILLIS_PER_DAY
            || monthLength < 28
            || monthLength > 31) {
            throw new IllegalArgumentException();
        }

        if (era == GregorianCalendar.BC) {
            year = -year;
        }

        if (finalZone != null && year >= finalStartYear) {
            return finalZone.getOffset(era, year, month, dom, dow, millis);
        }

        // Compute local epoch millis from input fields
        long time = Grego.fieldsToDay(year, month, dom) * Grego.MILLIS_PER_DAY + millis;

        int[] offsets = new int[2];
        getHistoricalOffset(time, true, LOCAL_DST, LOCAL_STD, offsets);
        return offsets[0] + offsets[1];
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#setRawOffset(int)
     */
    @Override
    public void setRawOffset(int offsetMillis) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify a frozen OlsonTimeZone instance.");
        }

        if (getRawOffset() == offsetMillis) {
            return;
        }
        long current = System.currentTimeMillis();

        if (current < finalStartMillis) {
            SimpleTimeZone stz = new SimpleTimeZone(offsetMillis, getID());

            boolean bDst = useDaylightTime();
            if (bDst) {
                TimeZoneRule[] currentRules = getSimpleTimeZoneRulesNear(current);
                if (currentRules.length != 3) {
                    // DST was observed at the beginning of this year, so useDaylightTime
                    // returned true.  getSimpleTimeZoneRulesNear requires at least one
                    // future transition for making a pair of rules.  This implementation
                    // rolls back the time before the latest offset transition.
                    TimeZoneTransition tzt = getPreviousTransition(current, false);
                    if (tzt != null) {
                        currentRules = getSimpleTimeZoneRulesNear(tzt.getTime() - 1);
                    }
                }
                if (currentRules.length == 3
                        && (currentRules[1] instanceof AnnualTimeZoneRule)
                        && (currentRules[2] instanceof AnnualTimeZoneRule)) {
                    // A pair of AnnualTimeZoneRule
                    AnnualTimeZoneRule r1 = (AnnualTimeZoneRule)currentRules[1];
                    AnnualTimeZoneRule r2 = (AnnualTimeZoneRule)currentRules[2];
                    DateTimeRule start, end;
                    int offset1 = r1.getRawOffset() + r1.getDSTSavings();
                    int offset2 = r2.getRawOffset() + r2.getDSTSavings();
                    int sav;
                    if (offset1 > offset2) {
                        start = r1.getRule();
                        end = r2.getRule();
                        sav = offset1 - offset2;
                    } else {
                        start = r2.getRule();
                        end = r1.getRule();
                        sav = offset2 - offset1;
                    }
                    // getSimpleTimeZoneRulesNear always return rules using DOW / WALL_TIME
                    stz.setStartRule(start.getRuleMonth(), start.getRuleWeekInMonth(), start.getRuleDayOfWeek(),
                                            start.getRuleMillisInDay());
                    stz.setEndRule(end.getRuleMonth(), end.getRuleWeekInMonth(), end.getRuleDayOfWeek(),
                                            end.getRuleMillisInDay());
                    // set DST saving amount and start year
                    stz.setDSTSavings(sav);
                } else {
                    // This could only happen if last rule is DST
                    // and the rule used forever.  For example, Asia/Dhaka
                    // in tzdata2009i stays in DST forever.

                    // Hack - set DST starting at midnight on Jan 1st,
                    // ending 23:59:59.999 on Dec 31st
                    stz.setStartRule(0, 1, 0);
                    stz.setEndRule(11, 31, Grego.MILLIS_PER_DAY - 1);
                }
            }

            int[] fields = Grego.timeToFields(current, null);

            finalStartYear = fields[0];
            finalStartMillis = Grego.fieldsToDay(fields[0], 0, 1);

            if (bDst) {
                // we probably do not need to set start year of final rule
                // to finalzone itself, but we always do this for now.
                stz.setStartYear(finalStartYear);
            }

            finalZone = stz;

        } else {
            finalZone.setRawOffset(offsetMillis);
        }

        transitionRulesInitialized = false;
    }

    @Override
    public Object clone() {
        if (isFrozen()) {
            return this;
        }
        return cloneAsThawed();
    }

    /**
     * TimeZone API.
     */
    @Override
    public void getOffset(long date, boolean local, int[] offsets)  {
        if (finalZone != null && date >= finalStartMillis) {
            finalZone.getOffset(date, local, offsets);
        } else {
            getHistoricalOffset(date, local,
                    LOCAL_FORMER, LOCAL_LATTER, offsets);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void getOffsetFromLocal(long date,
            int nonExistingTimeOpt, int duplicatedTimeOpt, int[] offsets) {
        if (finalZone != null && date >= finalStartMillis) {
            finalZone.getOffsetFromLocal(date, nonExistingTimeOpt, duplicatedTimeOpt, offsets);
        } else {
            getHistoricalOffset(date, true, nonExistingTimeOpt, duplicatedTimeOpt, offsets);
        }
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#getRawOffset()
     */
    @Override
    public int getRawOffset() {
        int[] ret = new int[2];
        getOffset(System.currentTimeMillis(), false, ret);
        return ret[0];
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#useDaylightTime()
     */
    @Override
    public boolean useDaylightTime() {
        // If DST was observed in 1942 (for example) but has never been
        // observed from 1943 to the present, most clients will expect
        // this method to return FALSE.  This method determines whether
        // DST is in use in the current year (at any point in the year)
        // and returns TRUE if so.
        long current = System.currentTimeMillis();

        if (finalZone != null && current >= finalStartMillis) {
            return (finalZone != null && finalZone.useDaylightTime());
        }

        int[] fields = Grego.timeToFields(current, null);

        // Find start of this year, and start of next year
        long start = Grego.fieldsToDay(fields[0], 0, 1) * SECONDS_PER_DAY;
        long limit = Grego.fieldsToDay(fields[0] + 1, 0, 1) * SECONDS_PER_DAY;

        // Return TRUE if DST is observed at any time during the current
        // year.
        for (int i = 0; i < transitionCount; ++i) {
            if (transitionTimes64[i] >= limit) {
                break;
            }
            if ((transitionTimes64[i] >= start && dstOffsetAt(i) != 0)
                    || (transitionTimes64[i] > start && i > 0 && dstOffsetAt(i - 1) != 0)) {
                return true;
            }
        }
        return false;
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#observesDaylightTime()
     */
    @Override
    public boolean observesDaylightTime() {
        long current = System.currentTimeMillis();

        if (finalZone != null) {
            if (finalZone.useDaylightTime()) {
                return true;
            } else if (current >= finalStartMillis) {
                return false;
            }
        }

        // Return TRUE if DST is observed at any future time
        long currentSec = Grego.floorDivide(current, Grego.MILLIS_PER_SECOND);
        int trsIdx = transitionCount - 1;
        if (dstOffsetAt(trsIdx) != 0) {
            return true;
        }
        while (trsIdx >= 0) {
            if (transitionTimes64[trsIdx] <= currentSec) {
                break;
            }
            if (dstOffsetAt(trsIdx - 1) != 0) {
                return true;
            }
            trsIdx--;
        }
        return false;
    }
    /**
     * TimeZone API
     * Returns the amount of time to be added to local standard time
     * to get local wall clock time.
     */
    @Override
    public int getDSTSavings() {
        if (finalZone != null){
            return finalZone.getDSTSavings();
        }
        return super.getDSTSavings();
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#inDaylightTime(java.util.Date)
     */
    @Override
    public boolean inDaylightTime(Date date) {
        int[] temp = new int[2];
        getOffset(date.getTime(), false, temp);
        return temp[1] != 0;
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#hasSameRules(com.ibm.icu.util.TimeZone)
     */
    @Override
    public boolean hasSameRules(TimeZone other) {
        if (this == other) {
            return true;
        }
        // The super class implementation only check raw offset and
        // use of daylight saving time.
        if (!super.hasSameRules(other)) {
            return false;
        }

        if (!(other instanceof OlsonTimeZone)) {
            // We cannot reasonably compare rules in different types
            return false;
        }

        // Check final zone
        OlsonTimeZone o = (OlsonTimeZone)other;
        if (finalZone == null) {
            if (o.finalZone != null) {
                return false;
            }
        } else {
            if (o.finalZone == null
                    || finalStartYear != o.finalStartYear
                    || !(finalZone.hasSameRules(o.finalZone))) {
                return false;
            }
        }
        // Check transitions
        // Note: The code below actually fails to compare two equivalent rules in
        // different representation properly.
        if (transitionCount != o.transitionCount ||
                !Arrays.equals(transitionTimes64, o.transitionTimes64) ||
                typeCount != o.typeCount ||
                !Arrays.equals(typeMapData, o.typeMapData) ||
                !Arrays.equals(typeOffsets, o.typeOffsets)){
            return false;
        }
        return true;
    }

    /**
     * Returns the canonical ID of this system time zone
     */
    public String getCanonicalID() {
        if (canonicalID == null) {
            synchronized(this) {
                if (canonicalID == null) {
                    canonicalID = getCanonicalID(getID());

                    assert(canonicalID != null);
                    if (canonicalID == null) {
                        // This should never happen...
                        canonicalID = getID();
                    }
                }
            }
        }
        return canonicalID;
    }

    /**
     * Construct a GMT+0 zone with no transitions.  This is done when a
     * constructor fails so the resultant object is well-behaved.
     */
    private void constructEmpty(){
        transitionCount = 0;
        transitionTimes64 = null;
        typeMapData =  null;

        typeCount = 1;
        typeOffsets = new int[]{0,0};
        finalZone = null;
        finalStartYear = Integer.MAX_VALUE;
        finalStartMillis = Double.MAX_VALUE;

        transitionRulesInitialized = false;
    }

    /**
     * Construct from a resource bundle
     * @param top the top-level zoneinfo resource bundle.  This is used
     * to lookup the rule that `res' may refer to, if there is one.
     * @param res the resource bundle of the zone to be constructed
     * @param id time zone ID
     */
    public OlsonTimeZone(UResourceBundle top, UResourceBundle res, String id){
        super(id);
        construct(top, res, id);
    }

    private void construct(UResourceBundle top, UResourceBundle res, String id){

        if ((top == null || res == null)) {
            throw new IllegalArgumentException();
        }
        if(DEBUG) System.out.println("OlsonTimeZone(" + res.getKey() +")");

        UResourceBundle r;
        int[] transPre32, trans32, transPost32;
        transPre32 = trans32 = transPost32 = null;

        transitionCount = 0;

        // Pre-32bit second transitions
        try {
            r = res.get("transPre32");
            transPre32 = r.getIntVector();
            if (transPre32.length % 2 != 0) {
                // elements in the pre-32bit must be an even number
                throw new IllegalArgumentException("Invalid Format");
            }
            transitionCount += transPre32.length / 2;
        } catch (MissingResourceException e) {
            // Pre-32bit transition data is optional
        }

        // 32bit second transitions
        try {
            r = res.get("trans");
            trans32 = r.getIntVector();
            transitionCount += trans32.length;
        } catch (MissingResourceException e) {
            // 32bit transition data is optional
        }

        // Post-32bit second transitions
        try {
            r = res.get("transPost32");
            transPost32 = r.getIntVector();
            if (transPost32.length % 2 != 0) {
                // elements in the post-32bit must be an even number
                throw new IllegalArgumentException("Invalid Format");
            }
            transitionCount += transPost32.length / 2;
        } catch (MissingResourceException e) {
            // Post-32bit transition data is optional
        }

        if (transitionCount > 0) {
            transitionTimes64 = new long[transitionCount];
            int idx = 0;
            if (transPre32 != null) {
                for (int i = 0; i < transPre32.length / 2; i++, idx++) {
                    transitionTimes64[idx] =
                        ((transPre32[i * 2]) & 0x00000000FFFFFFFFL) << 32
                        | ((transPre32[i * 2 + 1]) & 0x00000000FFFFFFFFL);
                }
            }
            if (trans32 != null) {
                for (int i = 0; i < trans32.length; i++, idx++) {
                    transitionTimes64[idx] = trans32[i];
                }
            }
            if (transPost32 != null) {
                for (int i = 0; i < transPost32.length / 2; i++, idx++) {
                    transitionTimes64[idx] =
                        ((transPost32[i * 2]) & 0x00000000FFFFFFFFL) << 32
                        | ((transPost32[i * 2 + 1]) & 0x00000000FFFFFFFFL);
                }
            }
        } else {
            transitionTimes64 = null;
        }

        // Type offsets list must be of even size, with size >= 2
        r = res.get("typeOffsets");
        typeOffsets = r.getIntVector();
        if ((typeOffsets.length < 2 || typeOffsets.length > 0x7FFE || typeOffsets.length % 2 != 0)) {
            throw new IllegalArgumentException("Invalid Format");
        }
        typeCount = typeOffsets.length / 2;

        // Type map data must be of the same size as the transition count
        if (transitionCount > 0) {
            r = res.get("typeMap");
            typeMapData = r.getBinary(null);
            if (typeMapData == null || typeMapData.length != transitionCount) {
                throw new IllegalArgumentException("Invalid Format");
            }
        } else {
            typeMapData = null;
        }

        // Process final rule and data, if any
        finalZone = null;
        finalStartYear = Integer.MAX_VALUE;
        finalStartMillis = Double.MAX_VALUE;

        String ruleID = null;
        try {
            ruleID = res.getString("finalRule");

            r = res.get("finalRaw");
            int ruleRaw = r.getInt() * Grego.MILLIS_PER_SECOND;
            r = loadRule(top, ruleID);
            int[] ruleData = r.getIntVector();

            if (ruleData == null || ruleData.length != 11) {
                throw new IllegalArgumentException("Invalid Format");
            }
            finalZone = new SimpleTimeZone(ruleRaw, id,
                    ruleData[0], ruleData[1], ruleData[2],
                    ruleData[3] * Grego.MILLIS_PER_SECOND,
                    ruleData[4],
                    ruleData[5], ruleData[6], ruleData[7],
                    ruleData[8] * Grego.MILLIS_PER_SECOND,
                    ruleData[9],
                    ruleData[10] * Grego.MILLIS_PER_SECOND);

            r = res.get("finalYear");
            finalStartYear = r.getInt();

            // Note: Setting finalStartYear to the finalZone is problematic.  When a date is around
            // year boundary, SimpleTimeZone may return false result when DST is observed at the
            // beginning of year.  We could apply safe margin (day or two), but when one of recurrent
            // rules falls around year boundary, it could return false result.  Without setting the
            // start year, finalZone works fine around the year boundary of the start year.

            // finalZone.setStartYear(finalStartYear);

            // Compute the millis for Jan 1, 0:00 GMT of the finalYear

            // Note: finalStartMillis is used for detecting either if
            // historic transition data or finalZone to be used.  In an
            // extreme edge case - for example, two transitions fall into
            // small windows of time around the year boundary, this may
            // result incorrect offset computation.  But I think it will
            // never happen practically.  Yoshito - Feb 20, 2010
            finalStartMillis = Grego.fieldsToDay(finalStartYear, 0, 1) * Grego.MILLIS_PER_DAY;
        } catch (MissingResourceException e) {
            if (ruleID != null) {
                // ruleID is found, but missing other data required for
                // creating finalZone
                throw new IllegalArgumentException("Invalid Format");
            }
        }
    }

    // This constructor is used for testing purpose only
    public OlsonTimeZone(String id){
        super(id);
        UResourceBundle top = UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME,
                ZONEINFORES, ICUResourceBundle.ICU_DATA_CLASS_LOADER);
        UResourceBundle res = ZoneMeta.openOlsonResource(top, id);
        construct(top, res, id);
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#setID(java.lang.String)
     */
    @Override
    public void setID(String id){
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify a frozen OlsonTimeZone instance.");
        }

        // Before updating the ID, preserve the original ID's canonical ID.
        if (canonicalID == null) {
            canonicalID = getCanonicalID(getID());
            assert(canonicalID != null);
            if (canonicalID == null) {
                // This should never happen...
                canonicalID = getID();
            }
        }

        if (finalZone != null){
            finalZone.setID(id);
        }
        super.setID(id);
        transitionRulesInitialized = false;
    }

    // Maximum absolute offset in seconds = 1 day.
    // getHistoricalOffset uses this constant as safety margin of
    // quick zone transition checking.
    private static final int MAX_OFFSET_SECONDS = 86400; // 60 * 60 * 24;

    private void getHistoricalOffset(long date, boolean local,
            int NonExistingTimeOpt, int DuplicatedTimeOpt, int[] offsets) {
        if (transitionCount != 0) {
            long sec = Grego.floorDivide(date, Grego.MILLIS_PER_SECOND);
            if (!local && sec < transitionTimes64[0]) {
                // Before the first transition time
                offsets[0] = initialRawOffset() * Grego.MILLIS_PER_SECOND;
                offsets[1] = initialDstOffset() * Grego.MILLIS_PER_SECOND;
            } else {
                // Linear search from the end is the fastest approach, since
                // most lookups will happen at/near the end.
                int transIdx;
                for (transIdx = transitionCount - 1; transIdx >= 0; transIdx--) {
                    long transition = transitionTimes64[transIdx];
                    if (local && (sec >= (transition - MAX_OFFSET_SECONDS))) {
                        int offsetBefore = zoneOffsetAt(transIdx - 1);
                        boolean dstBefore = dstOffsetAt(transIdx - 1) != 0;

                        int offsetAfter = zoneOffsetAt(transIdx);
                        boolean dstAfter = dstOffsetAt(transIdx) != 0;

                        boolean dstToStd = dstBefore && !dstAfter;
                        boolean stdToDst = !dstBefore && dstAfter;

                        if (offsetAfter - offsetBefore >= 0) {
                            // Positive transition, which makes a non-existing local time range
                            if (((NonExistingTimeOpt & STD_DST_MASK) == LOCAL_STD && dstToStd)
                                    || ((NonExistingTimeOpt & STD_DST_MASK) == LOCAL_DST && stdToDst)) {
                                transition += offsetBefore;
                            } else if (((NonExistingTimeOpt & STD_DST_MASK) == LOCAL_STD && stdToDst)
                                    || ((NonExistingTimeOpt & STD_DST_MASK) == LOCAL_DST && dstToStd)) {
                                transition += offsetAfter;
                            } else if ((NonExistingTimeOpt & FORMER_LATTER_MASK) == LOCAL_LATTER) {
                                transition += offsetBefore;
                            } else {
                                // Interprets the time with rule before the transition,
                                // default for non-existing time range
                                transition += offsetAfter;
                            }
                        } else {
                            // Negative transition, which makes a duplicated local time range
                            if (((DuplicatedTimeOpt & STD_DST_MASK) == LOCAL_STD && dstToStd)
                                    || ((DuplicatedTimeOpt & STD_DST_MASK) == LOCAL_DST && stdToDst)) {
                                transition += offsetAfter;
                            } else if (((DuplicatedTimeOpt & STD_DST_MASK) == LOCAL_STD && stdToDst)
                                    || ((DuplicatedTimeOpt & STD_DST_MASK) == LOCAL_DST && dstToStd)) {
                                transition += offsetBefore;
                            } else if ((DuplicatedTimeOpt & FORMER_LATTER_MASK) == LOCAL_FORMER) {
                                transition += offsetBefore;
                            } else {
                                // Interprets the time with rule after the transition,
                                // default for duplicated local time range
                                transition += offsetAfter;
                            }
                        }
                    }
                    if (sec >= transition) {
                        break;
                    }
                }
                // transIdx could be -1 when local=true
                offsets[0] = rawOffsetAt(transIdx) * Grego.MILLIS_PER_SECOND;
                offsets[1] = dstOffsetAt(transIdx) * Grego.MILLIS_PER_SECOND;
            }
        } else {
            // No transitions, single pair of offsets only
            offsets[0] = initialRawOffset() * Grego.MILLIS_PER_SECOND;
            offsets[1] = initialDstOffset() * Grego.MILLIS_PER_SECOND;
        }
    }

    private int getInt(byte val){
        return val & 0xFF;
    }

    /*
     * Following 3 methods return an offset at the given transition time index.
     * When the index is negative, return the initial offset.
     */
    private int zoneOffsetAt(int transIdx) {
        int typeIdx = transIdx >= 0 ? getInt(typeMapData[transIdx]) * 2 : 0;
        return typeOffsets[typeIdx] + typeOffsets[typeIdx + 1];
    }

    private int rawOffsetAt(int transIdx) {
        int typeIdx = transIdx >= 0 ? getInt(typeMapData[transIdx]) * 2 : 0;
        return typeOffsets[typeIdx];
    }

    private int dstOffsetAt(int transIdx) {
        int typeIdx = transIdx >= 0 ? getInt(typeMapData[transIdx]) * 2 : 0;
        return typeOffsets[typeIdx + 1];
    }

    private int initialRawOffset() {
        return typeOffsets[0];
    }

    private int initialDstOffset() {
        return typeOffsets[1];
    }

    // temp
    @Override
    public String toString() {
        StringBuilder buf = new StringBuilder();
        buf.append(super.toString());
        buf.append('[');
        buf.append("transitionCount=" + transitionCount);
        buf.append(",typeCount=" + typeCount);
        buf.append(",transitionTimes=");
        if (transitionTimes64 != null) {
            buf.append('[');
            for (int i = 0; i < transitionTimes64.length; ++i) {
                if (i > 0) {
                    buf.append(',');
                }
                buf.append(Long.toString(transitionTimes64[i]));
            }
            buf.append(']');
        } else {
            buf.append("null");
        }
        buf.append(",typeOffsets=");
        if (typeOffsets != null) {
            buf.append('[');
            for (int i = 0; i < typeOffsets.length; ++i) {
                if (i > 0) {
                    buf.append(',');
                }
                buf.append(Integer.toString(typeOffsets[i]));
            }
            buf.append(']');
        } else {
            buf.append("null");
        }
        buf.append(",typeMapData=");
        if (typeMapData != null) {
            buf.append('[');
            for (int i = 0; i < typeMapData.length; ++i) {
                if (i > 0) {
                    buf.append(',');
                }
                buf.append(Byte.toString(typeMapData[i]));
            }
        } else {
            buf.append("null");
        }
        buf.append(",finalStartYear=" + finalStartYear);
        buf.append(",finalStartMillis=" + finalStartMillis);
        buf.append(",finalZone=" + finalZone);
        buf.append(']');

        return buf.toString();
    }

    /**
     * Number of transitions, 0..~370
     */
    private int transitionCount;

    /**
     * Number of types, 1..255
     */
    private int typeCount;

    /**
     * Time of each transition in seconds from 1970 epoch.
     */
    private long[] transitionTimes64;

    /**
     * Offset from GMT in seconds for each type.
     * Length is equal to typeCount
     */
    private int[] typeOffsets;

    /**
     * Type description data, consisting of transitionCount uint8_t
     * type indices (from 0..typeCount-1).
     * Length is equal to transitionCount
     */
    private byte[] typeMapData;

    /**
     * For year >= finalStartYear, the finalZone will be used.
     */
    private int finalStartYear = Integer.MAX_VALUE;

    /**
     * For date >= finalStartMillis, the finalZone will be used.
     */
    private double finalStartMillis = Double.MAX_VALUE;

    /**
     * A SimpleTimeZone that governs the behavior for years >= finalYear.
     * If and only if finalYear == INT32_MAX then finalZone == 0.
     */
    private SimpleTimeZone finalZone = null; // owned, may be NULL

    /**
     * The canonical ID of this zone. Initialized when {@link #getCanonicalID()}
     * is invoked first time, or {@link #setID(String)} is called.
     */
    private volatile String canonicalID = null;

    private static final String ZONEINFORES = "zoneinfo64";

    private static final boolean DEBUG = ICUDebug.enabled("olson");
    private static final int SECONDS_PER_DAY = 24*60*60;

    private static UResourceBundle loadRule(UResourceBundle top, String ruleid) {
        UResourceBundle r = top.get("Rules");
        r = r.get(ruleid);
        return r;
    }

    @Override
    public boolean equals(Object obj){
        if (!super.equals(obj)) return false; // super does class check

        OlsonTimeZone z = (OlsonTimeZone) obj;

        return (Utility.arrayEquals(typeMapData, z.typeMapData) ||
                 // If the pointers are not equal, the zones may still
                 // be equal if their rules and transitions are equal
                 (finalStartYear == z.finalStartYear &&
                  // Don't compare finalMillis; if finalYear is ==, so is finalMillis
                  ((finalZone == null && z.finalZone == null) ||
                   (finalZone != null && z.finalZone != null &&
                    finalZone.equals(z.finalZone)) &&
                  transitionCount == z.transitionCount &&
                  typeCount == z.typeCount &&
                  Utility.arrayEquals(transitionTimes64, z.transitionTimes64) &&
                  Utility.arrayEquals(typeOffsets, z.typeOffsets) &&
                  Utility.arrayEquals(typeMapData, z.typeMapData)
                  )));

    }

    @Override
    public int hashCode(){
        int ret =   (int)  (finalStartYear ^ (finalStartYear>>>4) +
                   transitionCount ^ (transitionCount>>>6) +
                   typeCount ^ (typeCount>>>8) +
                   Double.doubleToLongBits(finalStartMillis)+
                   (finalZone == null ? 0 : finalZone.hashCode()) +
                   super.hashCode());
        if (transitionTimes64 != null) {
            for(int i=0; i<transitionTimes64.length; i++){
                ret+=transitionTimes64[i]^(transitionTimes64[i]>>>8);
            }
        }
        for(int i=0; i<typeOffsets.length; i++){
            ret+=typeOffsets[i]^(typeOffsets[i]>>>8);
        }
        if (typeMapData != null) {
            for(int i=0; i<typeMapData.length; i++){
                ret+=typeMapData[i] & 0xFF;
            }
        }
        return ret;
    }

    //
    // BasicTimeZone methods
    //

    /* (non-Javadoc)
     * @see com.ibm.icu.util.BasicTimeZone#getNextTransition(long, boolean)
     */
    @Override
    public TimeZoneTransition getNextTransition(long base, boolean inclusive) {
        initTransitionRules();

        if (finalZone != null) {
            if (inclusive && base == firstFinalTZTransition.getTime()) {
                return firstFinalTZTransition;
            } else if (base >= firstFinalTZTransition.getTime()) {
                if (finalZone.useDaylightTime()) {
                    //return finalZone.getNextTransition(base, inclusive);
                    return finalZoneWithStartYear.getNextTransition(base, inclusive);
                } else {
                    // No more transitions
                    return null;
                }
            }
        }
        if (historicRules != null) {
            // Find a historical transition
            int ttidx = transitionCount - 1;
            for (; ttidx >= firstTZTransitionIdx; ttidx--) {
                long t = transitionTimes64[ttidx] * Grego.MILLIS_PER_SECOND;
                if (base > t || (!inclusive && base == t)) {
                    break;
                }
            }
            if (ttidx == transitionCount - 1)  {
                return firstFinalTZTransition;
            } else if (ttidx < firstTZTransitionIdx) {
                return firstTZTransition;
            } else {
                // Create a TimeZoneTransition
                TimeZoneRule to = historicRules[getInt(typeMapData[ttidx + 1])];
                TimeZoneRule from = historicRules[getInt(typeMapData[ttidx])];
                long startTime = transitionTimes64[ttidx+1] * Grego.MILLIS_PER_SECOND;

                // The transitions loaded from zoneinfo.res may contain non-transition data
                if (from.getName().equals(to.getName()) && from.getRawOffset() == to.getRawOffset()
                        && from.getDSTSavings() == to.getDSTSavings()) {
                    return getNextTransition(startTime, false);
                }

                return new TimeZoneTransition(startTime, from, to);
            }
        }
        return null;
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.util.BasicTimeZone#getPreviousTransition(long, boolean)
     */
    @Override
    public TimeZoneTransition getPreviousTransition(long base, boolean inclusive) {
        initTransitionRules();

        if (finalZone != null) {
            if (inclusive && base == firstFinalTZTransition.getTime()) {
                return firstFinalTZTransition;
            } else if (base > firstFinalTZTransition.getTime()) {
                if (finalZone.useDaylightTime()) {
                    //return finalZone.getPreviousTransition(base, inclusive);
                    return finalZoneWithStartYear.getPreviousTransition(base, inclusive);
                } else {
                    return firstFinalTZTransition;
                }
            }
        }

        if (historicRules != null) {
            // Find a historical transition
            int ttidx = transitionCount - 1;
            for (; ttidx >= firstTZTransitionIdx; ttidx--) {
                long t = transitionTimes64[ttidx] * Grego.MILLIS_PER_SECOND;
                if (base > t || (inclusive && base == t)) {
                    break;
                }
            }
            if (ttidx < firstTZTransitionIdx) {
                // No more transitions
                return null;
            } else if (ttidx == firstTZTransitionIdx) {
                return firstTZTransition;
            } else {
                // Create a TimeZoneTransition
                TimeZoneRule to = historicRules[getInt(typeMapData[ttidx])];
                TimeZoneRule from = historicRules[getInt(typeMapData[ttidx-1])];
                long startTime = transitionTimes64[ttidx] * Grego.MILLIS_PER_SECOND;

                // The transitions loaded from zoneinfo.res may contain non-transition data
                if (from.getName().equals(to.getName()) && from.getRawOffset() == to.getRawOffset()
                        && from.getDSTSavings() == to.getDSTSavings()) {
                    return getPreviousTransition(startTime, false);
                }

                return new TimeZoneTransition(startTime, from, to);
            }
        }
        return null;
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.util.BasicTimeZone#getTimeZoneRules()
     */
    @Override
    public TimeZoneRule[] getTimeZoneRules() {
        initTransitionRules();
        int size = 1;
        if (historicRules != null) {
            // historicRules may contain null entries when original zoneinfo data
            // includes non transition data.
            for (int i = 0; i < historicRules.length; i++) {
                if (historicRules[i] != null) {
                    size++;
                }
            }
        }
        if (finalZone != null) {
            if (finalZone.useDaylightTime()) {
                size += 2;
            } else {
                size++;
            }
        }

        TimeZoneRule[] rules = new TimeZoneRule[size];
        int idx = 0;
        rules[idx++] = initialRule;

        if (historicRules != null) {
            for (int i = 0; i < historicRules.length; i++) {
                if (historicRules[i] != null) {
                    rules[idx++] = historicRules[i];
                }
            }
         }

        if (finalZone != null) {
            if (finalZone.useDaylightTime()) {
                TimeZoneRule[] stzr = finalZoneWithStartYear.getTimeZoneRules();
                // Adding only transition rules
                rules[idx++] = stzr[1];
                rules[idx++] = stzr[2];
            } else {
                // Create a TimeArrayTimeZoneRule at finalMillis
                rules[idx++] = new TimeArrayTimeZoneRule(getID() + "(STD)", finalZone.getRawOffset(), 0,
                        new long[] {(long)finalStartMillis}, DateTimeRule.UTC_TIME);
            }
        }
        return rules;
    }

    private transient InitialTimeZoneRule initialRule;
    private transient TimeZoneTransition firstTZTransition;
    private transient int firstTZTransitionIdx;
    private transient TimeZoneTransition firstFinalTZTransition;
    private transient TimeArrayTimeZoneRule[] historicRules;
    private transient SimpleTimeZone finalZoneWithStartYear; // hack

    private transient boolean transitionRulesInitialized;

    private synchronized void initTransitionRules() {
        if (transitionRulesInitialized) {
            return;
        }

        initialRule = null;
        firstTZTransition = null;
        firstFinalTZTransition = null;
        historicRules = null;
        firstTZTransitionIdx = 0;
        finalZoneWithStartYear = null;

        String stdName = getID() + "(STD)";
        String dstName = getID() + "(DST)";

        int raw, dst;

        // Create initial rule
        raw = initialRawOffset() * Grego.MILLIS_PER_SECOND;
        dst = initialDstOffset() * Grego.MILLIS_PER_SECOND;
        initialRule = new InitialTimeZoneRule((dst == 0 ? stdName : dstName), raw, dst);

        if (transitionCount > 0) {
            int transitionIdx, typeIdx;

            // We probably no longer need to check the first "real" transition
            // here, because the new tzcode remove such transitions already.
            // For now, keeping this code for just in case. Feb 19, 2010 Yoshito
            for (transitionIdx = 0; transitionIdx < transitionCount; transitionIdx++) {
                if (getInt(typeMapData[transitionIdx]) != 0) { // type 0 is the initial type
                    break;
                }
                firstTZTransitionIdx++;
            }
            if (transitionIdx == transitionCount) {
                // Actually no transitions...
            } else {
                // Build historic rule array
                long[] times = new long[transitionCount];
                for (typeIdx = 0; typeIdx < typeCount; typeIdx++) {
                    // Gather all start times for each pair of offsets
                    int nTimes = 0;
                    for (transitionIdx = firstTZTransitionIdx; transitionIdx < transitionCount; transitionIdx++) {
                        if (typeIdx == getInt(typeMapData[transitionIdx])) {
                            long tt = transitionTimes64[transitionIdx] * Grego.MILLIS_PER_SECOND;
                            if (tt < finalStartMillis) {
                                // Exclude transitions after finalMillis
                                times[nTimes++] = tt;
                            }
                        }
                    }
                    if (nTimes > 0) {
                        long[] startTimes = new long[nTimes];
                        System.arraycopy(times, 0, startTimes, 0, nTimes);
                        // Create a TimeArrayTimeZoneRule
                        raw = typeOffsets[typeIdx*2]*Grego.MILLIS_PER_SECOND;
                        dst = typeOffsets[typeIdx*2 + 1]*Grego.MILLIS_PER_SECOND;
                        if (historicRules == null) {
                            historicRules = new TimeArrayTimeZoneRule[typeCount];
                        }
                        historicRules[typeIdx] = new TimeArrayTimeZoneRule((dst == 0 ? stdName : dstName),
                                raw, dst, startTimes, DateTimeRule.UTC_TIME);
                    }
                }

                // Create initial transition
                typeIdx = getInt(typeMapData[firstTZTransitionIdx]);
                firstTZTransition = new TimeZoneTransition(transitionTimes64[firstTZTransitionIdx] * Grego.MILLIS_PER_SECOND,
                        initialRule, historicRules[typeIdx]);

            }
        }

        if (finalZone != null) {
            // Get the first occurrence of final rule starts
            long startTime = (long)finalStartMillis;
            TimeZoneRule firstFinalRule;
            if (finalZone.useDaylightTime()) {
                /*
                 * Note: When an OlsonTimeZone is constructed, we should set the final year
                 * as the start year of finalZone.  However, the boundary condition used for
                 * getting offset from finalZone has some problems.  So setting the start year
                 * in the finalZone will cause a problem.  For now, we do not set the valid
                 * start year when the construction time and create a clone and set the
                 * start year when extracting rules.
                 */
                finalZoneWithStartYear = (SimpleTimeZone)finalZone.clone();
                finalZoneWithStartYear.setStartYear(finalStartYear);

                TimeZoneTransition tzt = finalZoneWithStartYear.getNextTransition(startTime, false);
                firstFinalRule  = tzt.getTo();
                startTime = tzt.getTime();
            } else {
                finalZoneWithStartYear = finalZone;
                firstFinalRule = new TimeArrayTimeZoneRule(finalZone.getID(),
                        finalZone.getRawOffset(), 0, new long[] {startTime}, DateTimeRule.UTC_TIME);
            }
            TimeZoneRule prevRule = null;
            if (transitionCount > 0) {
                prevRule = historicRules[getInt(typeMapData[transitionCount - 1])];
            }
            if (prevRule == null) {
                // No historic transitions, but only finalZone available
                prevRule = initialRule;
            }
            firstFinalTZTransition = new TimeZoneTransition(startTime, prevRule, firstFinalRule);
        }

        transitionRulesInitialized = true;
    }

    // Note: This class does not support back level serialization compatibility
    // very well.  ICU 4.4 introduced the 64bit transition data.  It is probably
    // possible to implement this class to make old version of ICU to deserialize
    // object stream serialized by ICU 4.4+.  However, such implementation will
    // introduce unnecessary complexity other than serialization support.
    // I decided to provide minimum level of backward compatibility, which
    // only support ICU 4.4+ to create an instance of OlsonTimeZone by reloading
    // the zone rules from bundles.  ICU 4.2 or older version of ICU cannot
    // deserialize object stream created by ICU 4.4+.  Yoshito -Feb 22, 2010

    private static final int currentSerialVersion = 1;
    private int serialVersionOnStream = currentSerialVersion;

    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
        stream.defaultReadObject();

        if (serialVersionOnStream < 1) {
            // No version - 4.2 or older
            // Just reloading the rule from bundle
            boolean initialized = false;
            String tzid = getID();
            if (tzid != null) {
                try {
                    UResourceBundle top = UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME,
                            ZONEINFORES, ICUResourceBundle.ICU_DATA_CLASS_LOADER);
                    UResourceBundle res = ZoneMeta.openOlsonResource(top, tzid);
                    construct(top, res, tzid);
                    initialized = true;
                } catch (Exception ignored) {
                    // throw away
                }
            }
            if (!initialized) {
                // final resort
                constructEmpty();
            }
        }

        // need to rebuild transition rules when requested
        transitionRulesInitialized = false;
    }

    // Freezable stuffs
    private transient volatile boolean isFrozen = false;

    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#isFrozen()
     */
    @Override
    public boolean isFrozen() {
        return isFrozen;
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#freeze()
     */
    @Override
    public TimeZone freeze() {
        isFrozen = true;
        return this;
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#cloneAsThawed()
     */
    @Override
    public TimeZone cloneAsThawed() {
        OlsonTimeZone tz = (OlsonTimeZone)super.cloneAsThawed();
        if (finalZone != null) {
            tz.finalZone = (SimpleTimeZone) finalZone.clone();
        }

        // Following data are read-only and never changed.
        // Therefore, shallow copies should be sufficient.
        //
        // transitionTimes64
        // typeMapData
        // typeOffsets

        tz.isFrozen = false;
        return tz;
    }
}
