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

/**
 * <code>TimeArrayTimeZoneRule</code> represents a time zone rule whose start times are
 * defined by an array of milliseconds since the standard base time.
 * 
 * @stable ICU 3.8
 */
public class TimeArrayTimeZoneRule extends TimeZoneRule {

    private static final long serialVersionUID = -1117109130077415245L;

    private final long[] startTimes;
    private final int timeType;

    /**
     * Constructs a <code>TimeArrayTimeZoneRule</code> with the name, the GMT offset of its
     * standard time, the amount of daylight saving offset adjustment and
     * the array of times when this rule takes effect.
     * 
     * @param name          The time zone name.
     * @param rawOffset     The UTC offset of its standard time in milliseconds.
     * @param dstSavings    The amount of daylight saving offset adjustment in
     *                      milliseconds.  If this ia a rule for standard time,
     *                      the value of this argument is 0.
     * @param startTimes    The start times in milliseconds since the base time
     *                      (January 1, 1970, 00:00:00).
     * @param timeType      The time type of the start times, which is one of
     *                      <code>DataTimeRule.WALL_TIME</code>, <code>STANDARD_TIME</code>
     *                      and <code>UTC_TIME</code>.
     * 
     * @stable ICU 3.8
     */
    public TimeArrayTimeZoneRule(String name, int rawOffset, int dstSavings, long[] startTimes, int timeType) {
        super(name, rawOffset, dstSavings);
        if (startTimes == null || startTimes.length == 0) {
            throw new IllegalArgumentException("No start times are specified.");
        } else {
            this.startTimes = startTimes.clone();
            Arrays.sort(this.startTimes);
        }
        this.timeType = timeType;
    }

    /**
     * Gets the array of start times used by this rule.
     * 
     * @return  An array of the start times in milliseconds since the base time
     *          (January 1, 1970, 00:00:00 GMT).
     * @stable ICU 3.8
     */
    public long[] getStartTimes() {
        return startTimes.clone();
    }

    /**
     * Gets the time type of the start times used by this rule.  The return value
     * is either <code>DateTimeRule.WALL_TIME</code> or <code>DateTimeRule.STANDARD_TIME</code>
     * or <code>DateTimeRule.UTC_TIME</code>.
     * 
     * @return The time type used of the start times used by this rule.
     * @stable ICU 3.8
     */
    public int getTimeType() {
        return timeType;
    }

    /**
     * {@inheritDoc}
     * @stable ICU 3.8
     */
    public Date getFirstStart(int prevRawOffset, int prevDSTSavings) {
        return new Date(getUTC(startTimes[0], prevRawOffset, prevDSTSavings));
    }

    /**
     * {@inheritDoc}
     * @stable ICU 3.8
     */
    public Date getFinalStart(int prevRawOffset, int prevDSTSavings) {
        return new Date(getUTC(startTimes[startTimes.length - 1], prevRawOffset, prevDSTSavings));
    }

    /**
     * {@inheritDoc}
     * @stable ICU 3.8
     */
    public Date getNextStart(long base, int prevOffset, int prevDSTSavings, boolean inclusive) {
        int i = startTimes.length - 1;
        for (; i >= 0; i--) {
            long time = getUTC(startTimes[i], prevOffset, prevDSTSavings);
            if (time < base || (!inclusive && time == base)) {
                break;
            }
        }
        if (i == startTimes.length - 1) {
            return null;
        }
        return new Date(getUTC(startTimes[i + 1], prevOffset, prevDSTSavings));
    }

    /**
     * {@inheritDoc}
     * @stable ICU 3.8
     */
    public Date getPreviousStart(long base, int prevOffset, int prevDSTSavings, boolean inclusive) {
        int i = startTimes.length - 1;
        for (; i >= 0; i--) {
            long time = getUTC(startTimes[i], prevOffset, prevDSTSavings);
            if (time < base || (inclusive && time == base)) {
                return new Date(time);
            }
        }
        return null;
    }

    /**
     * {@inheritDoc}
     * @stable ICU 3.8
     */
    public boolean isEquivalentTo(TimeZoneRule other) {
        if (!(other instanceof TimeArrayTimeZoneRule)) {
            return false;
        }
        if (timeType == ((TimeArrayTimeZoneRule)other).timeType
                && Arrays.equals(startTimes, ((TimeArrayTimeZoneRule)other).startTimes)) {
            return super.isEquivalentTo(other);
        }
        return false;
    }

    /**
     * {@inheritDoc}<br><br>
     * Note: This method in <code>TimeArrayTimeZoneRule</code> always returns true.
     * @stable ICU 3.8
     */
    public boolean isTransitionRule() {
        return true;
    }

    /* Get UTC of the time with the raw/dst offset */
    private long getUTC(long time, int raw, int dst) {
        if (timeType != DateTimeRule.UTC_TIME) {
            time -= raw;
        }
        if (timeType == DateTimeRule.WALL_TIME) {
            time -= dst;
        }
        return time;
    }

    /**
     * Returns a <code>String</code> representation of this <code>TimeArrayTimeZoneRule</code> object.
     * This method is used for debugging purpose only.  The string representation can be changed
     * in future version of ICU without any notice.
     * 
     * @stable ICU 3.8
     */
    public String toString() {
        StringBuilder buf = new StringBuilder();
        buf.append(super.toString());
        buf.append(", timeType=");
        buf.append(timeType);
        buf.append(", startTimes=[");
        for (int i = 0; i < startTimes.length; i++) {
            if (i != 0) {
                buf.append(", ");
            }
            buf.append(Long.toString(startTimes[i]));
        }
        buf.append("]");
        return buf.toString();
    }
}
