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

import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.TreeMap;

import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.UResourceBundle;

/**
 * Calendar utilities.
 *
 * Date/time format service classes in com.ibm.icu.text packages
 * sometimes need to access calendar internal APIs.  But calendar
 * classes are in com.ibm.icu.util package, so the package local
 * cannot be used.  This class is added in com.ibm.icu.impl
 * package for sharing some calendar internal code for calendar
 * and date format.
 */
public final class CalendarUtil {
    private static final String CALKEY = "calendar";
    private static final String DEFCAL = "gregorian";

    /**
     * Returns a calendar type for the given locale.
     * When the given locale has calendar keyword, the
     * value of calendar keyword is returned.  Otherwise,
     * the default calendar type for the locale is returned.
     * @param loc The locale
     * @return Calendar type string, such as "gregorian"
     */
    public static String getCalendarType(ULocale loc) {
        String calType = loc.getKeywordValue(CALKEY);
        if (calType != null) {
            // Convert to lower case, because getKeywordValue does not
            // canonicalize keyword value.
            return calType.toLowerCase(Locale.ROOT);
        }

        // Canonicalize, so grandfathered variant will be transformed to keywords
        ULocale canonical = ULocale.createCanonical(loc.toString());
        calType = canonical.getKeywordValue(CALKEY);
        if (calType != null) {
            return calType;
        }

        // When calendar keyword is not available, use the locale's
        // region to get the default calendar type
        String region = ULocale.getRegionForSupplementalData(canonical, true);
        return CalendarPreferences.INSTANCE.getCalendarTypeForRegion(region);
    }

    private static final class CalendarPreferences extends UResource.Sink {
        private static final CalendarPreferences INSTANCE = new CalendarPreferences();
        // A TreeMap should be good because we expect very few entries.
        Map<String, String> prefs = new TreeMap<String, String>();

        CalendarPreferences() {
            try {
                ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(
                        ICUData.ICU_BASE_NAME, "supplementalData");
                rb.getAllItemsWithFallback("calendarPreferenceData", this);
            } catch (MissingResourceException mre) {
                // Always use "gregorian".
            }
        }

        String getCalendarTypeForRegion(String region) {
            String type = prefs.get(region);
            return type == null ? DEFCAL : type;
        }

        @Override
        public void put(UResource.Key key, UResource.Value value, boolean noFallback) {
            UResource.Table calendarPreferenceData = value.getTable();
            for (int i = 0; calendarPreferenceData.getKeyAndValue(i, key, value); ++i) {
                UResource.Array types = value.getArray();
                // The first calendar type is the default for the region.
                if (types.getValue(0, value)) {
                    String type = value.getString();
                    if (!type.equals(DEFCAL)) {
                        prefs.put(key.toString(), type);
                    }
                }
            }
        }
    }
}
