 /*
  *******************************************************************************
  * Copyright (C) 2005-2011, 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)
     */
    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)
     */
    public void setRawOffset(int offsetMillis) {
        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;
    }

    public Object clone() {
        OlsonTimeZone other = (OlsonTimeZone) super.clone();
        if(finalZone != null){
            finalZone.setID(getID());
            other.finalZone = (SimpleTimeZone)finalZone.clone();
        }

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

        /*
        if (transitionTimes64 != null) {
            other.transitionTimes64 = transitionTimes64.clone();
        }
        if (typeMapData != null) {
            other.typeMapData = typeMapData.clone();
        }
        other.typeOffsets = typeOffsets.clone();
        */

        return other;
    }

    /**
     * TimeZone API.
     */
    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}
     * @internal
     * @deprecated This API is ICU internal only.
     */
    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()
     */
    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()
     */
    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;
    }

    /**
     * TimeZone API
     * Returns the amount of time to be added to local standard time
     * to get local wall clock time.
     */
    public int getDSTSavings() {
        if (finalZone != null){
            return finalZone.getDSTSavings();
        }
        return super.getDSTSavings();
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#inDaylightTime(java.util.Date)
     */
    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)
     */
    public boolean hasSameRules(TimeZone other) {
        // 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
     */
    public OlsonTimeZone(UResourceBundle top, UResourceBundle res){
        construct(top, res);
    }

    private void construct(UResourceBundle top, UResourceBundle res){
        
        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] = 
                        (((long)transPre32[i * 2]) & 0x00000000FFFFFFFFL) << 32
                        | (((long)transPre32[i * 2 + 1]) & 0x00000000FFFFFFFFL);
                }
            }
            if (trans32 != null) {
                for (int i = 0; i < trans32.length; i++, idx++) {
                    transitionTimes64[idx] = (long)trans32[i];
                }
            }
            if (transPost32 != null) {
                for (int i = 0; i < transPost32.length / 2; i++, idx++) {
                    transitionTimes64[idx] = 
                        (((long)transPost32[i * 2]) & 0x00000000FFFFFFFFL) << 32
                        | (((long)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.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, "",
                    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){
        UResourceBundle top = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME,
                ZONEINFORES, ICUResourceBundle.ICU_DATA_CLASS_LOADER);
        UResourceBundle res = ZoneMeta.openOlsonResource(top, id);
        construct(top, res);
        if (finalZone != null){
            finalZone.setID(id);
        }
        super.setID(id);
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#setID(java.lang.String)
     */
    @Override
    public void setID(String id){
        // 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;
    }

    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) {
                        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
    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;
    }

    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)
                  )));

    }

    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)
     */
    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)
     */
    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()
     */
    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(ICUResourceBundle.ICU_BASE_NAME,
                            ZONEINFORES, ICUResourceBundle.ICU_DATA_CLASS_LOADER);
                    UResourceBundle res = ZoneMeta.openOlsonResource(top, tzid);
                    construct(top, res);
                    if (finalZone != null){
                        finalZone.setID(tzid);
                    }
                    initialized = true;
                } catch (Exception e) {
                    // throw away
                }
            }
            if (!initialized) {
                // final resort
                constructEmpty();
            }
        }

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