// © 2018 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
package com.ibm.icu.impl;

import java.util.Arrays;

import com.ibm.icu.util.ICUException;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.UResourceBundle;
import com.ibm.icu.util.UResourceBundleIterator;

/**
 * <code>EraRules</code> represents calendar era rules specified
 * in supplementalData/calendarData.
 *
 * @author Yoshito Umaoka
 */
public class EraRules {
    private static final int MAX_ENCODED_START_YEAR = 32767;
    private static final int MIN_ENCODED_START_YEAR = -32768;

    public static final int MIN_ENCODED_START = encodeDate(MIN_ENCODED_START_YEAR, 1, 1);

    private static final int YEAR_MASK = 0xFFFF0000;
    private static final int MONTH_MASK = 0x0000FF00;
    private static final int DAY_MASK = 0x000000FF;

    private int[] startDates;
    private int numEras;
    private int currentEra;

    private EraRules(int[] startDates, int numEras) {
        this.startDates = startDates;
        this.numEras = numEras;
        initCurrentEra();
    }

    public static EraRules getInstance(CalType calType, boolean includeTentativeEra) {
        UResourceBundle supplementalDataRes = UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME,
                "supplementalData", ICUResourceBundle.ICU_DATA_CLASS_LOADER);
        UResourceBundle calendarDataRes = supplementalDataRes.get("calendarData");
        UResourceBundle calendarTypeRes = calendarDataRes.get(calType.getId());
        UResourceBundle erasRes = calendarTypeRes.get("eras");

        int numEras = erasRes.getSize();
        int firstTentativeIdx = Integer.MAX_VALUE; // first tentative era index
        int[] startDates = new int[numEras];

        UResourceBundleIterator itr = erasRes.getIterator();
        while (itr.hasNext()) {
            UResourceBundle eraRuleRes = itr.next();
            String eraIdxStr = eraRuleRes.getKey();
            int eraIdx = -1;
            try {
                eraIdx = Integer.parseInt(eraIdxStr);
            } catch (NumberFormatException e) {
                throw new ICUException("Invald era rule key:" + eraIdxStr + " in era rule data for " + calType.getId());
            }
            if (eraIdx < 0 || eraIdx >= numEras) {
                throw new ICUException("Era rule key:" + eraIdxStr + " in era rule data for " + calType.getId()
                        + " must be in range [0, " + (numEras - 1) + "]");
            }
            if (isSet(startDates[eraIdx])) {
                throw new ICUException(
                        "Duplicated era rule for rule key:" + eraIdxStr + " in era rule data for " + calType.getId());
            }

            boolean hasName = true;
            boolean hasEnd = false;
            UResourceBundleIterator ruleItr = eraRuleRes.getIterator();
            while (ruleItr.hasNext()) {
                UResourceBundle res = ruleItr.next();
                String key = res.getKey();
                if (key.equals("start")) {
                    int[] fields = res.getIntVector();
                    if (fields.length != 3 || !isValidRuleStartDate(fields[0], fields[1], fields[2])) {
                        throw new ICUException(
                                "Invalid era rule date data:" + Arrays.toString(fields) + " in era rule data for "
                                + calType.getId());
                    }
                    startDates[eraIdx] = encodeDate(fields[0], fields[1], fields[2]);
                } else if (key.equals("named")) {
                    String val = res.getString();
                    if (val.equals("false")) {
                        hasName = false;
                    }
                } else if (key.equals("end")) {
                    hasEnd = true;
                }
            }
            if (isSet(startDates[eraIdx])) {
                if (hasEnd) {
                    // This implementation assumes either start or end is available, not both.
                    // For now, just ignore the end rule.
                }
            } else {
                if (hasEnd) {
                    if (eraIdx != 0) {
                        // This implementation does not support end only rule for eras other than
                        // the first one.
                        throw new ICUException(
                                "Era data for " + eraIdxStr + " in era rule data for " + calType.getId()
                                + " has only end rule.");
                    }
                    startDates[eraIdx] = MIN_ENCODED_START;
                } else {
                    throw new ICUException("Missing era start/end rule date for key:" + eraIdxStr + " in era rule data for "
                            + calType.getId());
                }
            }

            if (hasName) {
                if (eraIdx >= firstTentativeIdx) {
                    throw new ICUException(
                            "Non-tentative era(" + eraIdx + ") must be placed before the first tentative era");
                }
            } else {
                if (eraIdx < firstTentativeIdx) {
                    firstTentativeIdx = eraIdx;
                }
            }
        }

        if (firstTentativeIdx < Integer.MAX_VALUE && !includeTentativeEra) {
            return new EraRules(startDates, firstTentativeIdx);
        }

        return new EraRules(startDates, numEras);
    }

    /**
     * Gets number of effective eras
     * @return  number of effective eras
     */
    public int getNumberOfEras() {
        return numEras;
    }

    /**
     * Gets start date of an era
     * @param eraIdx    Era index
     * @param fillIn    Receives date fields if supplied. If null, or size of array
     *                  is less than 3, then a new int[] will be newly allocated.
     * @return  An int array including values of year, month, day of month in this order.
     *          When an era has no start date, the result will be January 1st in year
     *          whose value is minimum integer.
     */
    public int[] getStartDate(int eraIdx, int[] fillIn) {
        if (eraIdx < 0 || eraIdx >= numEras) {
            throw new IllegalArgumentException("eraIdx is out of range");
        }
        return decodeDate(startDates[eraIdx], fillIn);
    }

    /**
     * Gets start year of an era
     * @param eraIdx    Era index
     * @return  The first year of an era. When a era has no start date, minimum integer
     *          value is returned.
     */
    public int getStartYear(int eraIdx) {
        if (eraIdx < 0 || eraIdx >= numEras) {
            throw new IllegalArgumentException("eraIdx is out of range");
        }
        int[] fields = decodeDate(startDates[eraIdx], null);
        return fields[0];
    }

    /**
     * Returns era index for the specified year/month/day.
     * @param year  Year
     * @param month Month (1-base)
     * @param day   Day of month
     * @return  era index (or 0, when the specified date is before the first era)
     */
    public int getEraIndex(int year, int month, int day) {
        if (month < 1 || month > 12 || day < 1 || day > 31) {
            throw new IllegalArgumentException("Illegal date - year:" + year + "month:" + month + "day:" + day);
        }
        int high = numEras; // last index + 1
        int low;

        // Short circuit for recent years.  Most modern computations will
        // occur in the last few eras.
        if (compareEncodedDateWithYMD(startDates[getCurrentEraIndex()], year, month, day) <= 0) {
            low = getCurrentEraIndex();
        } else {
            low = 0;
        }

        // Do binary search
        while (low < high - 1) {
            int i = (low + high) / 2;
            if (compareEncodedDateWithYMD(startDates[i], year, month, day) <= 0) {
                low = i;
            } else {
                high = i;
            }
        }
        return low;
    }

    /**
     * Gets the current era index. This is calculated only once for an instance of
     * EraRules. The current era calculation is based on the default time zone at
     * the time of instantiation.
     *
     * @return era index of current era (or 0, when current date is before the first era)
     */
    public int getCurrentEraIndex() {
        return currentEra;
    }

    private void initCurrentEra() {
        long localMillis = System.currentTimeMillis();
        TimeZone zone = TimeZone.getDefault();
        localMillis += zone.getOffset(localMillis);

        int[] fields = Grego.timeToFields(localMillis, null);
        int currentEncodedDate = encodeDate(fields[0], fields[1] + 1 /* changes to 1-base */, fields[2]);
        int eraIdx = numEras - 1;
        while (eraIdx > 0) {
            if (currentEncodedDate >= startDates[eraIdx]) {
                break;
            }
            eraIdx--;
        }
        // Note: current era could be before the first era.
        // In this case, this implementation returns the first era index (0).
        currentEra = eraIdx;
    }

    //
    // private methods
    //

    private static boolean isSet(int startDate) {
        return startDate != 0;
    }

    private static boolean isValidRuleStartDate(int year, int month, int day) {
        return year >= MIN_ENCODED_START_YEAR && year <= MAX_ENCODED_START_YEAR
                && month >= 1 && month <= 12 && day >= 1 && day <= 31;
    }

    /**
     * Encode year/month/date to a single integer.
     * year is high 16 bits (-32768 to 32767), month is
     * next 8 bits and day of month is last 8 bits.
     *
     * @param year  year
     * @param month month (1-base)
     * @param day   day of month
     * @return  an encoded date.
     */
    private static int encodeDate(int year, int month, int day) {
        return year << 16 | month << 8 | day;
    }

    private static int[] decodeDate(int encodedDate, int[] fillIn) {
        int year, month, day;
        if (encodedDate == MIN_ENCODED_START) {
            year = Integer.MIN_VALUE;
            month = 1;
            day = 1;
        } else {
            year = (encodedDate & YEAR_MASK) >> 16;
            month = (encodedDate & MONTH_MASK) >> 8;
            day = encodedDate & DAY_MASK;
        }

        if (fillIn != null && fillIn.length >= 3) {
            fillIn[0] = year;
            fillIn[1] = month;
            fillIn[2] = day;
            return fillIn;
        }

        int[] result = {year, month, day};
        return result;
    }

    /**
     * Compare an encoded date with another date specified by year/month/day.
     * @param encoded   An encoded date
     * @param year      Year of another date
     * @param month     Month of another date
     * @param day       Day of another date
     * @return -1 when encoded date is earlier, 0 when two dates are same,
     *          and 1 when encoded date is later.
     */
    private static int compareEncodedDateWithYMD(int encoded, int year, int month, int day) {
        if (year < MIN_ENCODED_START_YEAR) {
            if (encoded == MIN_ENCODED_START) {
                if (year > Integer.MIN_VALUE || month > 1 || day > 1) {
                    return -1;
                }
                return 0;
            } else {
                return 1;
            }
        } else if (year > MAX_ENCODED_START_YEAR) {
            return -1;
        } else {
            int tmp = encodeDate(year, month, day);
            if (encoded < tmp) {
                return -1;
            } else if (encoded == tmp) {
                return 0;
            } else {
                return 1;
            }
        }
    }
}
