// © 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(
                        "Dupulicated 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;
            }
        }
    }
}
