/*
 *******************************************************************************
 * Copyright (C) 2008-2012, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.impl.javaspi;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.ULocale.Builder;

public class ICULocaleServiceProvider {
    private static final String SPI_PROP_FILE = "com/ibm/icu/impl/javaspi/ICULocaleServiceProviderConfig.properties";

    private static final String SUFFIX_KEY = "com.ibm.icu.impl.javaspi.ICULocaleServiceProvider.icuVariantSuffix";
    private static final String ENABLE_VARIANTS_KEY = "com.ibm.icu.impl.javaspi.ICULocaleServiceProvider.enableIcuVariants";
    private static final String ENABLE_ISO3_LANG_KEY = "com.ibm.icu.impl.javaspi.ICULocaleServiceProvider.enableIso3Languages";
    private static final String USE_DECIMALFORMAT_KEY = "com.ibm.icu.impl.javaspi.ICULocaleServiceProvider.useDecimalFormat";

    private static boolean configLoaded = false;

    private static String suffix = "ICU4J";
    private static boolean enableVariants = true;
    private static boolean enableIso3Lang = true;
    private static boolean useDecimalFormat = false;

    private static final Locale[] SPECIAL_LOCALES = {
        new Locale("ja", "JP", "JP"),
        new Locale("no"),
        new Locale("no", "NO"),
        new Locale("no", "NO", "NY"),
        new Locale("sr", "CS"),
        new Locale("th", "TH", "TH"),
    };

    private static Map<Locale, Locale> SPECIAL_LOCALES_MAP = null;

    private static Locale[] LOCALES = null;

    public static Locale[] getAvailableLocales() {
        Locale[] all = getLocales();
        return Arrays.copyOf(all, all.length);
    }

    public static ULocale toULocaleNoSpecialVariant(Locale locale) {
        // If the given Locale has legacy ill-formed variant
        // reserved by JDK, use the map to resolve the locale.
        Locale spLoc = getSpecialLocalesMap().get(locale);
        if (spLoc != null) {
            return ULocale.forLocale(spLoc);
        }

        // The locale may have script field on Java 7+.
        // So we once convert it to ULocale, then strip the ICU suffix off
        // if necessary.
        ULocale result = ULocale.forLocale(locale);
        String variant = result.getVariant();
        String suffix = getIcuSuffix();
        String variantNoSuffix = null;
        if (variant.equals(suffix)) {
            variantNoSuffix = "";
        } else if (variant.endsWith(suffix) && variant.charAt(variant.length() - suffix.length() - 1) == '_') {
            variantNoSuffix = variant.substring(0, variant.length() - suffix.length() - 1);
        }
        if (variantNoSuffix == null) {
            return result;
        }

        // Strip off ICU's special suffix - cannot use Builder because
        // original locale may have ill-formed variant
        StringBuilder id = new StringBuilder(result.getLanguage());
        String script = result.getScript();
        String country = result.getCountry();
        if (script.length() > 0) {
            id.append('_');
            id.append(script);
        }
        if (country.length() > 0 || variantNoSuffix.length() > 0) {
            id.append('_');
            id.append(country);
        }
        if (variantNoSuffix.length() > 0) {
            id.append('_');
            id.append(variantNoSuffix);
        }
        String orgID = result.getName();
        int kwdIdx = orgID.indexOf('@');
        if (kwdIdx >= 0) {
            id.append(orgID.substring(kwdIdx));
        }
        return new ULocale(id.toString());
    }

    public static boolean useDecimalFormat() {
        loadConfiguration();
        return useDecimalFormat;
    }

    private static synchronized Map<Locale, Locale> getSpecialLocalesMap() {
        if (SPECIAL_LOCALES_MAP != null) {
            return SPECIAL_LOCALES_MAP;
        }

        Map<Locale, Locale> splocs = new HashMap<Locale, Locale>();
        for (Locale spLoc : SPECIAL_LOCALES) {
            String var = spLoc.getVariant();
            if (var.length() > 0) {
                splocs.put(new Locale(spLoc.getLanguage(), spLoc.getCountry(), var + "_" + getIcuSuffix()), spLoc);
            }
        }
        SPECIAL_LOCALES_MAP = Collections.unmodifiableMap(splocs);
        return SPECIAL_LOCALES_MAP;
    }

    private static synchronized Locale[] getLocales() {
        if (LOCALES != null) {
            return LOCALES;
        }

        Set<Locale> localeSet = new HashSet<Locale>();
        ULocale[] icuLocales = ICUResourceBundle.getAvailableULocales();

        for (ULocale uloc : icuLocales) {
            String language = uloc.getLanguage();
            if (language.length() >= 3 && !enableIso3Languages()) {
                continue;
            }
            addULocale(uloc, localeSet);

            if (uloc.getScript().length() > 0 && uloc.getCountry().length() > 0) {
                // ICU's available locales do not contain language+country
                // locales if script is available. Need to add them too.
                Builder locBld = new Builder();
                try {
                    locBld.setLocale(uloc);
                    locBld.setScript(null);
                    ULocale ulocWithoutScript = locBld.build();
                    addULocale(ulocWithoutScript, localeSet);
                } catch (Exception e) {
                    // ignore
                }
            }
        }

        for (Locale l : SPECIAL_LOCALES) {
            addLocale(l, localeSet);
        }

        LOCALES = localeSet.toArray(new Locale[0]);
        return LOCALES;
    }

    private static void addLocale(Locale loc, Set<Locale> locales) {
        locales.add(loc);

        if (enableIcuVariants()) {
            // Add ICU variant
            String language = loc.getLanguage();
            String country = loc.getCountry();
            String variant = loc.getVariant();

            StringBuilder var = new StringBuilder(variant);
            if (var.length() != 0) {
                var.append("_");
            }
            var.append(getIcuSuffix());
            locales.add(new Locale(language, country, var.toString()));
        }
    }

    private static void addULocale(ULocale uloc, Set<Locale> locales) {
        // special case - nn
        // ULocale#toLocale on Java 6 maps "nn" to "no_NO_NY"
        if (uloc.getLanguage().equals("nn") && uloc.getScript().length() == 0) {
            Locale locNN = new Locale(uloc.getLanguage(), uloc.getCountry(), uloc.getVariant());
            addLocale(locNN, locales);
            return;
        }

        locales.add(uloc.toLocale());

        if (enableIcuVariants()) {
            // Add ICU variant
            StringBuilder var = new StringBuilder(uloc.getVariant());
            if (var.length() != 0) {
                var.append("_");
            }
            var.append(getIcuSuffix());

            Builder locBld = new Builder();
            try {
                locBld.setLocale(uloc);
                locBld.setVariant(var.toString());
                ULocale ulocWithVar = locBld.build();
                locales.add(ulocWithVar.toLocale());
            } catch (Exception e) {
                // ignore
            }
        }
    }

    private static boolean enableIso3Languages() {
        return enableIso3Lang;
    }

    private static boolean enableIcuVariants() {
        loadConfiguration();
        return enableVariants;
    }

    private static String getIcuSuffix() {
        loadConfiguration();
        return suffix;
    }

    private static synchronized void loadConfiguration() {
        if (configLoaded) {
            return;
        }
        Properties spiConfigProps = new Properties();
        try {
            InputStream is = ClassLoader.getSystemResourceAsStream(SPI_PROP_FILE);
            spiConfigProps.load(is);

            String val = (String)spiConfigProps.get(SUFFIX_KEY);
            if (val != null && val.length() > 0) {
                suffix = val;
            }
            enableVariants = parseBooleanString((String)spiConfigProps.get(ENABLE_VARIANTS_KEY), enableVariants);
            enableIso3Lang = parseBooleanString((String)spiConfigProps.get(ENABLE_ISO3_LANG_KEY), enableIso3Lang);
            useDecimalFormat = parseBooleanString((String)spiConfigProps.get(USE_DECIMALFORMAT_KEY), useDecimalFormat);
        } catch (IOException ioe) {
            // Any IO errors, ignore
        }
        configLoaded = true;
    }

    private static boolean parseBooleanString(String str, boolean defaultVal) {
        if (str == null) {
            return defaultVal;
        }
        if (str.equalsIgnoreCase("true")) {
            return true;
        } else if (str.equalsIgnoreCase("false")) {
            return false;
        }
        return defaultVal;
    }
}
