// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * 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 that an old-style 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);
                    }
                }
            }
        }
    }
}
