/*
 *******************************************************************************
 * Copyright (C) 2007-2008, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.util;

import java.util.BitSet;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import com.ibm.icu.impl.Grego;

/**
 * <code>BasicTimeZone</code> is an abstract class extending <code>TimeZone</code>.
 * This class provides some additional methods to access time zone transitions
 * and rules.  All ICU <code>TimeZone</code> concrete subclasses extend this
 * class.
 * 
 * @see com.ibm.icu.util.TimeZoneRule
 * @see com.ibm.icu.util.TimeZoneTransition
 * 
 * @stable ICU 3.8
 */
public abstract class BasicTimeZone extends TimeZone {

    private static final long serialVersionUID = -3204278532246180932L;

    private static final long MILLIS_PER_YEAR = 365*24*60*60*1000L;

    /**
     * Gets the first time zone transition after the base time.
     * 
     * @param base      The base time.
     * @param inclusive Whether the base time is inclusive or not.
     *               
     * @return  A <code>Date</code> holding the first time zone transition time
     *          after the given base time, or null if no time zone transitions
     *          are available after the base time.
     * 
     * @stable ICU 3.8
     */
    public abstract TimeZoneTransition getNextTransition(long base, boolean inclusive);

    /**
     * Gets the last time zone transition before the base time.
     * 
     * @param base      The base time.
     * @param inclusive Whether the base time is inclusive or not.
     *               
     * @return  A <code>Date</code> holding the last time zone transition time
     *          before the given base time, or null if no time zone transitions
     *          are available before the base time.
     * 
     * @stable ICU 3.8
     */
    public abstract TimeZoneTransition getPreviousTransition(long base, boolean inclusive);

    /**
     * Checks if the time zone has equivalent transitions in the time range.
     * This method returns true when all of transition times, from/to standard
     * offsets and DST savings used by this time zone match the other in the
     * time range.
     * 
     * @param tz    The instance of <code>TimeZone</code>
     * @param start The start time of the evaluated time range (inclusive)
     * @param end   The end time of the evaluated time range (inclusive)
     * 
     * @return true if the other time zone has the equivalent transitions in the
     * time range.  When tz is not a <code>BasicTimeZone</code>, this method
     * returns false.
     * 
     * @stable ICU 3.8
     */
    public boolean hasEquivalentTransitions(TimeZone tz, long start, long end) {
        return hasEquivalentTransitions(tz, start, end, false);
    }

    /**
     * Checks if the time zone has equivalent transitions in the time range.
     * This method returns true when all of transition times, from/to standard
     * offsets and DST savings used by this time zone match the other in the
     * time range.
     * 
     * @param tz    The instance of <code>TimeZone</code>
     * @param start The start time of the evaluated time range (inclusive)
     * @param end   The end time of the evaluated time range (inclusive)
     * @param ignoreDstAmount
     *              When true, any transitions with only daylight saving amount
     *              changes will be ignored, except either of them is zero.
     *              For example, a transition from rawoffset 3:00/dstsavings 1:00
     *              to rawoffset 2:00/dstsavings 2:00 is excluded from the comparison,
     *              but a transtion from rawoffset 2:00/dstsavings 1:00 to
     *              rawoffset 3:00/dstsavings 0:00 is included.
     * 
     * @return true if the other time zone has the equivalent transitions in the
     * time range.  When tz is not a <code>BasicTimeZone</code>, this method
     * returns false.
     * 
     * @stable ICU 3.8
     */
    public boolean hasEquivalentTransitions(TimeZone tz, long start, long end, boolean ignoreDstAmount) {
        if (hasSameRules(tz)) {
            return true;
        }
        if (!(tz instanceof BasicTimeZone)) {
            return false;
        }

        // Check the offsets at the start time
        int[] offsets1 = new int[2];
        int[] offsets2 = new int[2];

        getOffset(start, false, offsets1);
        tz.getOffset(start, false, offsets2);

        if (ignoreDstAmount) {
            if ((offsets1[0] + offsets1[1] != offsets2[0] + offsets2[1])
                || (offsets1[1] != 0 && offsets2[1] == 0)
                || (offsets1[1] == 0 && offsets2[1] != 0)) {
                return false;
            }
        } else {
            if (offsets1[0] != offsets2[0] || offsets1[1] != offsets2[1]) {
                return false;
            }            
        }

        // Check transitions in the range
        long time = start;
        while (true) {
            TimeZoneTransition tr1 = getNextTransition(time, false);
            TimeZoneTransition tr2 = ((BasicTimeZone)tz).getNextTransition(time, false);

            if (ignoreDstAmount) {
                // Skip a transition which only differ the amount of DST savings
                if (tr1 != null
                        && (tr1.getFrom().getRawOffset() + tr1.getFrom().getDSTSavings()
                                == tr1.getTo().getRawOffset() + tr1.getTo().getDSTSavings())
                        && (tr1.getFrom().getDSTSavings() != 0 && tr1.getTo().getDSTSavings() != 0)) {
                    tr1 = getNextTransition(tr1.getTime(), false);
                }
                if (tr2 != null
                        && (tr2.getFrom().getRawOffset() + tr2.getFrom().getDSTSavings()
                                == tr2.getTo().getRawOffset() + tr2.getTo().getDSTSavings())
                        && (tr2.getFrom().getDSTSavings() != 0 && tr2.getTo().getDSTSavings() != 0)) {
                    tr2 = getNextTransition(tr2.getTime(), false);
                }
            }

            boolean inRange1 = false;
            boolean inRange2 = false;
            if (tr1 != null) {
                if (tr1.getTime() <= end) {
                    inRange1 = true;
                }
            }
            if (tr2 != null) {
                if (tr2.getTime() <= end) {
                    inRange2 = true;
                }
            }
            if (!inRange1 && !inRange2) {
                // No more transition in the range
                break;
            }
            if (!inRange1 || !inRange2) {
                return false;
            }
            if (tr1.getTime() != tr2.getTime()) {
                return false;
            }
            if (ignoreDstAmount) {
                if (tr1.getTo().getRawOffset() + tr1.getTo().getDSTSavings()
                            != tr2.getTo().getRawOffset() + tr2.getTo().getDSTSavings()
                        || tr1.getTo().getDSTSavings() != 0 &&  tr2.getTo().getDSTSavings() == 0
                        || tr1.getTo().getDSTSavings() == 0 &&  tr2.getTo().getDSTSavings() != 0) {
                    return false;
                }
            } else {
                if (tr1.getTo().getRawOffset() != tr2.getTo().getRawOffset() ||
                    tr1.getTo().getDSTSavings() != tr2.getTo().getDSTSavings()) {
                    return false;
                }
            }
            time = tr1.getTime();
        }
        return true;
    }

    /**
     * Gets the array of <code>TimeZoneRule</code> which represents the rule
     * of this time zone object.  The first element in the result array will
     * be the <code>InitialTimeZoneRule</code> instance for the initial rule.
     * The rest will be either <code>AnnualTimeZoneRule</code> or
     * <code>TimeArrayTimeZoneRule</code> instances representing transitions.
     * 
     * @return  The array of <code>TimeZoneRule</code> which represents this
     *          time zone.
     * 
     * @stable ICU 3.8
     */
    public abstract TimeZoneRule[] getTimeZoneRules();

    /**
     * Gets the array of <code>TimeZoneRule</code> which represents the rule
     * of this time zone object since the specified start time.  The first
     * element in the result array will be the <code>InitialTimeZoneRule</code>
     * instance for the initial rule.  The rest will be either
     * <code>AnnualTimeZoneRule</code> or <code>TimeArrayTimeZoneRule</code>
     * instances representing transitions.
     * 
     * @param start The start time (inclusive).
     * @return  The array of <code>TimeZoneRule</code> which represents this
     *          time zone since the start time.
     * 
     * @stable ICU 3.8
     */
    public TimeZoneRule[] getTimeZoneRules(long start) {
        TimeZoneRule[] all = getTimeZoneRules();
        TimeZoneTransition tzt = getPreviousTransition(start, true);
        if (tzt == null) {
            // No need to filter out rules only applicable to time before the start
            return all;
        }

        BitSet isProcessed = new BitSet(all.length);
        List filteredRules = new LinkedList();

        // Create initial rule
        TimeZoneRule initial = new InitialTimeZoneRule(tzt.getTo().getName(),
                tzt.getTo().getRawOffset(), tzt.getTo().getDSTSavings());
        filteredRules.add(initial);
        isProcessed.set(0);

        // Mark rules which does not need to be processed
        for (int i = 1; i < all.length; i++) {
            Date d = all[i].getNextStart(start, initial.getRawOffset(),
                    initial.getDSTSavings(), false);
            if (d == null) {
                isProcessed.set(i);
            }
        }

        long time = start;
        boolean bFinalStd = false, bFinalDst = false;
        while(!bFinalStd || !bFinalDst) {
            tzt = getNextTransition(time, false);
            if (tzt == null) {
                break;
            }
            time = tzt.getTime();

            TimeZoneRule toRule = tzt.getTo();
            int ruleIdx = 1;
            for (; ruleIdx < all.length; ruleIdx++) {
                if (all[ruleIdx].equals(toRule)) {
                    break;
                }
            }
            if (ruleIdx >= all.length) {
                throw new IllegalStateException("The rule was not found");
            }
            if (isProcessed.get(ruleIdx)) {
                continue;
            }
            if (toRule instanceof TimeArrayTimeZoneRule) {
                TimeArrayTimeZoneRule tar = (TimeArrayTimeZoneRule)toRule;

                // Get the previous raw offset and DST savings before the very first start time
                long t = start;
                while(true) {
                    tzt = getNextTransition(t, false);
                    if (tzt == null) {
                        break;
                    }
                    if (tzt.getTo().equals(tar)) {
                        break;
                    }
                    t = tzt.getTime();
                }
                if (tzt != null) {
                    // Check if the entire start times to be added
                    Date firstStart = tar.getFirstStart(tzt.getFrom().getRawOffset(),
                            tzt.getFrom().getDSTSavings());
                    if (firstStart.getTime() > start) {
                        // Just add the rule as is
                        filteredRules.add(tar);
                    } else {
                        // Collect transitions after the start time
                        long[] times = tar.getStartTimes();
                        int timeType = tar.getTimeType();
                        int idx;
                        for (idx = 0; idx < times.length; idx++) {
                            t = times[idx];
                            if (timeType == DateTimeRule.STANDARD_TIME) {
                                t -= tzt.getFrom().getRawOffset();
                            }
                            if (timeType == DateTimeRule.WALL_TIME) {
                                t -= tzt.getFrom().getDSTSavings();
                            }
                            if (t > start) {
                                break;
                            }
                        }
                        int asize = times.length - idx;
                        if (asize > 0) {
                            long[] newtimes = new long[asize];
                            System.arraycopy(times, idx, newtimes, 0, asize);
                            TimeArrayTimeZoneRule newtar = new TimeArrayTimeZoneRule(
                                    tar.getName(), tar.getRawOffset(), tar.getDSTSavings(),
                                    newtimes, tar.getTimeType());
                            filteredRules.add(newtar);
                        }
                    }
                }
            } else if (toRule instanceof AnnualTimeZoneRule) {
                AnnualTimeZoneRule ar = (AnnualTimeZoneRule)toRule;
                Date firstStart = ar.getFirstStart(tzt.getFrom().getRawOffset(),
                        tzt.getFrom().getDSTSavings());
                if (firstStart.getTime() == tzt.getTime()) {
                    // Just add the rule as is
                    filteredRules.add(ar);
                } else {
                    // Calculate the transition year
                    int[] dfields = new int[6];
                    Grego.timeToFields(tzt.getTime(), dfields);
                    // Recreate the rule
                    AnnualTimeZoneRule newar = new AnnualTimeZoneRule(ar.getName(),
                            ar.getRawOffset(), ar.getDSTSavings(),
                            ar.getRule(), dfields[0], ar.getEndYear());
                    filteredRules.add(newar);
                }
                // Check if this is a final rule
                if (ar.getEndYear() == AnnualTimeZoneRule.MAX_YEAR) {
                    // After both final standard and dst rule are processed,
                    // exit this while loop.
                    if (ar.getDSTSavings() == 0) {
                        bFinalStd = true;
                    } else {
                        bFinalDst = true;
                    }
                }
            }
            isProcessed.set(ruleIdx);
        }
        TimeZoneRule[] rules = new TimeZoneRule[filteredRules.size()];
        filteredRules.toArray(rules);
        return rules;
    }

    /**
     * Gets the array of <code>TimeZoneRule</code> which represents the rule of
     * this time zone object near the specified date.  Some applications are not
     * capable to handle historic time zone rule changes.  Also some applications
     * can only handle certain type of rule definitions.  This method returns
     * either a single <code>InitialTimeZoneRule</code> if this time zone does not
     * have any daylight saving time within 1 year from the specified time, or a
     * pair of <code>AnnualTimeZoneRule</code> whose rule type is
     * <code>DateTimeRule.DOW</code> for date and <code>DateTimeRule.WALL_TIME</code>
     * for time with a single <code>InitialTimeZoneRule</code> representing the
     * initial time, when this time zone observes daylight saving time near the
     * specified date.  Thus, the result may be only valid for dates around the
     * specified date.
     *
     * @param date The date to be used for <code>TimeZoneRule</code> extraction.
     * @return The array of <code>TimeZoneRule</code>, either a single
     * <code>InitialTimeZoneRule</code> object, or a pair of <code>AnnualTimeZoneRule</code>
     * with a single <code>InitialTimeZoneRule</code>.  The first element in the
     * array is always a <code>InitialTimeZoneRule</code>.
     * 
     * @stable ICU 3.8
     */
    public TimeZoneRule[] getSimpleTimeZoneRulesNear(long date) {
        AnnualTimeZoneRule[] annualRules = null;
        TimeZoneRule initialRule = null;
        // Get the next transition
        TimeZoneTransition tr = getNextTransition(date, false);
        if (tr != null) {
            String initialName = tr.getFrom().getName();
            int initialRaw = tr.getFrom().getRawOffset();
            int initialDst = tr.getFrom().getDSTSavings();

            // Check if the next transition is either DST->STD or STD->DST and
            // within roughly 1 year from the specified date
            long nextTransitionTime = tr.getTime();
            if (((tr.getFrom().getDSTSavings() == 0 && tr.getTo().getDSTSavings() != 0)
                    || (tr.getFrom().getDSTSavings() != 0 && tr.getTo().getDSTSavings() == 0))
                        && date + MILLIS_PER_YEAR > nextTransitionTime) {
                // Get the next next transition
                annualRules = new AnnualTimeZoneRule[2];
                // Get local wall time for the transition time
                int dtfields[] = Grego.timeToFields(nextTransitionTime
                        + tr.getFrom().getRawOffset() + tr.getFrom().getDSTSavings(), null);
                int weekInMonth = Grego.getDayOfWeekInMonth(dtfields[0], dtfields[1], dtfields[2]);
                // Create DOW rule
                DateTimeRule dtr = new DateTimeRule(dtfields[1], weekInMonth, dtfields[3],
                        dtfields[5], DateTimeRule.WALL_TIME);
                annualRules[0] = new AnnualTimeZoneRule(tr.getTo().getName(),
                        tr.getTo().getRawOffset(), tr.getTo().getDSTSavings(),
                        dtr, dtfields[0], AnnualTimeZoneRule.MAX_YEAR);

                tr = getNextTransition(nextTransitionTime, false);
                AnnualTimeZoneRule secondRule = null;
                if (tr != null) {
                    // Check if the next next transition is either DST->STD or STD->DST
                    // and within roughly 1 year from the next transition
                    if (((tr.getFrom().getDSTSavings() == 0 && tr.getTo().getDSTSavings() != 0)
                            || (tr.getFrom().getDSTSavings() != 0 && tr.getTo().getDSTSavings() == 0))
                                && nextTransitionTime + MILLIS_PER_YEAR > tr.getTime()) {
                        // Generate another DOW rule
                        dtfields = Grego.timeToFields(tr.getTime()
                                + tr.getFrom().getRawOffset() + tr.getFrom().getDSTSavings(), dtfields);
                        weekInMonth = Grego.getDayOfWeekInMonth(dtfields[0], dtfields[1], dtfields[2]);
                        dtr = new DateTimeRule(dtfields[1], weekInMonth, dtfields[3], dtfields[5],
                                DateTimeRule.WALL_TIME);
                        secondRule = new AnnualTimeZoneRule(tr.getTo().getName(),
                                tr.getTo().getRawOffset(), tr.getTo().getDSTSavings(),
                                dtr, dtfields[0] - 1, AnnualTimeZoneRule.MAX_YEAR);
                        // Make sure this rule can be applied to the specified date
                        Date d = secondRule.getPreviousStart(date, tr.getFrom().getRawOffset(),
                                tr.getFrom().getDSTSavings(), true);
                        if (d != null && d.getTime() <= date
                                && initialRaw == tr.getTo().getRawOffset()
                                && initialDst == tr.getTo().getDSTSavings()) {
                            // We can use this rule as the second transition rule
                            annualRules[1] = secondRule;
                        }
                    }
                }
                if (annualRules[1] == null) {
                    // Try previous transition
                    tr = getPreviousTransition(date, true);
                    if (tr != null) {
                        // Check if the previous transition is either DST->STD or STD->DST.
                        // The actual transition time does not matter here.
                        if ((tr.getFrom().getDSTSavings() == 0 && tr.getTo().getDSTSavings() != 0)
                                || (tr.getFrom().getDSTSavings() != 0 && tr.getTo().getDSTSavings() == 0)) {
                            // Generate another DOW rule
                            dtfields = Grego.timeToFields(tr.getTime()
                                    + tr.getFrom().getRawOffset() + tr.getFrom().getDSTSavings(), dtfields);
                            weekInMonth = Grego.getDayOfWeekInMonth(dtfields[0], dtfields[1], dtfields[2]);
                            dtr = new DateTimeRule(dtfields[1], weekInMonth, dtfields[3], dtfields[5],
                                    DateTimeRule.WALL_TIME);
                            secondRule = new AnnualTimeZoneRule(tr.getTo().getName(),
                                    tr.getTo().getRawOffset(), tr.getTo().getDSTSavings(),
                                    dtr, annualRules[0].getStartYear() - 1, AnnualTimeZoneRule.MAX_YEAR);
                            // Check if this rule start after the first rule after the specified date
                            Date d = secondRule.getNextStart(date,
                                    tr.getFrom().getRawOffset(), tr.getFrom().getDSTSavings(), false);
                            if (d.getTime() > nextTransitionTime) {
                                // We can use this rule as the second transition rule
                                annualRules[1] = secondRule;
                            }
                        }
                    }
                }
                if (annualRules[1] == null) {
                    // Cannot generate a good pair of AnnualTimeZoneRule
                    annualRules = null;
                } else {
                    // The initial rule should represent the rule before the previous transition
                    initialName = annualRules[0].getName();
                    initialRaw = annualRules[0].getRawOffset();
                    initialDst = annualRules[0].getDSTSavings();
                }
            }
            initialRule = new InitialTimeZoneRule(initialName, initialRaw, initialDst);
        } else {
            // Try the previous one
            tr = getPreviousTransition(date, true);
            if (tr != null) {
                initialRule = new InitialTimeZoneRule(tr.getTo().getName(),
                        tr.getTo().getRawOffset(), tr.getTo().getDSTSavings());
            } else {
                // No transitions in the past.  Just use the current offsets
                int[] offsets = new int[2];
                getOffset(date, false, offsets);
                initialRule = new InitialTimeZoneRule(getID(), offsets[0], offsets[1]);
            }
        }

        TimeZoneRule[] result = null;
        if (annualRules == null) {
            result = new TimeZoneRule[1];
            result[0] = initialRule;
        } else {
            result = new TimeZoneRule[3];
            result[0] = initialRule;
            result[1] = annualRules[0];
            result[2] = annualRules[1];
        }

        return result;
    }

    /**
     * The time type option for standard time used by
     * {@link #getOffsetFromLocal(long, int, int, int[])}
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public static final int LOCAL_STD = 0x01;

    /**
     * The time type option for daylight saving time used by
     * {@link #getOffsetFromLocal(long, int, int, int[])}
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public static final int LOCAL_DST = 0x03;

    /**
     * The option designate former time to be used by
     * {@link #getOffsetFromLocal(long, int, int, int[])}
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public static final int LOCAL_FORMER = 0x04;

    /**
     * The option designate latter time to be used by
     * {@link #getOffsetFromLocal(long, int, int, int[])}
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public static final int LOCAL_LATTER = 0x0C;

    /**
     * The bit mask for the time type option used by
     * {@link #getOffsetFromLocal(long, int, int, int[])}
     * @internal
     * @deprecated This API is ICU internal only.
     */
    protected static final int STD_DST_MASK = 0x03;

    /**
     * The bit mask for the former/latter option used by
     * {@link #getOffsetFromLocal(long, int, int, int[])}
     * @internal
     * @deprecated This API is ICU internal only.
     */
    protected static final int FORMER_LATTER_MASK = 0x0C;

    /**
     * Get time zone offsets from local wall time.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    public void getOffsetFromLocal(long date,
            int nonExistingTimeOpt, int duplicatedTimeOpt, int[] offsets) {
        throw new IllegalStateException("Not implemented");
    }

    /**
     * Protected no arg constructor.
     * @stable ICU 3.8
     */
    protected BasicTimeZone() {
    }
}
