// © 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
     */
    @Override
    public Date getFirstStart(int prevRawOffset, int prevDSTSavings) {
        return new Date(getUTC(startTimes[0], prevRawOffset, prevDSTSavings));
    }

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

    /**
     * {@inheritDoc}
     * @stable ICU 3.8
     */
    @Override
    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
     */
    @Override
    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
     */
    @Override
    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
     */
    @Override
    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
     */
    @Override
    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();
    }
}
