/*
 * (C) Copyright IBM Corp. 2002 - All Rights Reserved
 */

package com.ibm.icu.impl;

import java.lang.ref.SoftReference;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Provides information about and access to resource bundles in the
 * com.ibm.text.resources package.  Unlike the java version, this does
 * not include resources from any other location.  In particular, it
 * does not look in the boot or system class path.
 */
public class ICULocaleData {
    private static Locale[] localeList;
    private static final String PACKAGE1 = "com.ibm.icu.impl.data";
    private static final String[] packageNames = { PACKAGE1 };
    private static boolean debug = ICUDebug.enabled("localedata");

    /**
     * Returns a list of the installed locales.
     *
     * The following note by Rich is obsolete, see below.  -- dlf 01 Oct. 2002
     * -----
     * @param key A resource tag.  Currently, this parameter is ignored.  The obvious
     * intent, however,  is for getAvailableLocales() to return a list of only those
     * locales that contain a resource with the specified resource tag.
     *
     * <p>Before we implement this function this way, however, some thought should be
     * given to whether this is really the right thing to do.  Because of the lookup
     * algorithm, a NumberFormat, for example, is "installed" for all locales.  But if
     * we're trying to put up a list of NumberFormats to choose from, we may want to see
     * only a list of those locales that uniquely define a NumberFormat rather than
     * inheriting one from another locale.  Thus, if fr and fr_CA uniquely define
     * NumberFormat data, but fr_BE doesn't, the user wouldn't see "French (Belgium)" in
     * the list and would go for "French (default)" instead.  Of course, this means
     * "Engish (United States)" would not be in the list, since it is the default locale.
     * This might be okay, but might be confusing to some users.
     *
     * <p>In addition, the other functions that call getAvailableLocales() don't currently
     * all pass the right thing for "key," meaning that all of these functions should be
     * looked at before anything is done to this function.
     *
     * <p>We recommend that someone take some careful consideration of these issues before
     * modifying this function to pay attention to the "key" parameter.  --rtg 1/26/98
     * -----
     *
     * Return a list of the locales supported by a collection of resource bundles.
     * All ICULocaleData-based services that use a particular resource bundle support
     * all the locales from that bundle.  If support for a particular service is spotty,
     * a different bundle prefix should be used for that service.
     * @param bundlePrefix the prefix of the resource bundles to use.
     */
    public static Locale[] getAvailableLocales(String bundlePrefix) {
        return (Locale[])getAvailEntry(bundlePrefix).getLocaleList().clone();
    }

    /**
     * Convenience method that returns a list of all the avilable LOCALE_ELEMENTS locales.
     */
    public static Locale[] getAvailableLocales() {
        return getAvailableLocales(LOCALE_ELEMENTS);
    }

    /**
     * Return a set of the locale names supported by a collection of resource bundles.
     * @param bundlePrefix the prefix of the resource bundles to use.
     */
    public static Set getAvailableLocaleNameSet(String bundlePrefix) {
        return getAvailEntry(bundlePrefix).getLocaleNameSet();
    }

    /**
     * Return a set of the locale names supported by a collection of resource bundles.
     * @param bundlePrefix the prefix of the resource bundles to use.
     */
    public static Set getAvailableLocaleNameSet() {
        return getAvailableLocaleNameSet(LOCALE_ELEMENTS);
    }

    /**
     * Holds the prefix, and lazily creates the Locale[] list or the locale name Set as needed.
     */
    private static final class AvailEntry {
        private String prefix;
        private Locale[] locales;
        private Set nameSet;

        AvailEntry(String prefix) {
            this.prefix = prefix;
        }

        Locale[] getLocaleList() {
            if (locales == null) {
                locales = createLocaleList(prefix);
            }
            return locales;
        }

        Set getLocaleNameSet() {
            if (nameSet == null) {
                nameSet = createLocaleNameSet(prefix);
            }
            return nameSet;
        }
    }

    /**
     * Stores the locale information in a cache accessed by key (bundle prefix).  The
     * cached objects are AvailEntries.  The cache is held by a SoftReference
     * so it can be GC'd.
     */
    private static AvailEntry getAvailEntry(String key) {
        AvailEntry ae = null;
        Map lcache = null;
        if (lcacheref != null) {
            lcache = (Map)lcacheref.get();
            if (lcache != null) {
                ae = (AvailEntry)lcache.get(key);
            }
        }

        if (ae == null) {
            ae = new AvailEntry(key);
            if (lcache == null) {
                lcache = new HashMap();
                lcache.put(key, ae);
                lcacheref = new SoftReference(lcache);
            } else {
                lcache.put(key, ae);
            }
        }

        return ae;
    }
    private static SoftReference lcacheref;

    /**
     * The default name for resources containing ICU locale data.
     */
    public static final String LOCALE_ELEMENTS = "LocaleElements";

    /**
     * Gets a LocaleElements resource bundle.
     */
    public static ResourceBundle getLocaleElements(Locale locale) {
        return getResourceBundle(LOCALE_ELEMENTS, locale);
    }

    /**
     * Gets a LocaleElements resource bundle.
     */
    public static ResourceBundle getLocaleElements(String localeName) {
    return getResourceBundle(LOCALE_ELEMENTS, localeName);
    }

    /**
     * Still need permissions to use our own class loader, is there no way
     * to load class resources from new locations that aren't already on the
     * class path?
     */
    private static ResourceBundle instantiateBundle(String name, Locale l) {
    ResourceBundle rb = ResourceBundle.getBundle(name, l);
    return rb;
    }

    /**
     * Get a resource bundle from the lookup chain.
     */
    public static ResourceBundle getResourceBundle(String bundleName, String localeName) {
    Locale locale = LocaleUtility.getLocaleFromName(localeName);
    return getResourceBundle(bundleName, locale);
    }

    /**
     * Get a resource bundle from the lookup chain.
     */
    public static ResourceBundle getResourceBundle(String bundleName, Locale locale) {
    if (locale == null) {
        locale = Locale.getDefault();
    }
    for (int i = 0; i < packageNames.length; ++i) {
        try {
        String path = packageNames[i] + "." + bundleName;
        if (debug) System.out.println("calling instantiateBundle: " + path + "_" + locale);
        ResourceBundle rb = instantiateBundle(path, locale);
        return rb;
        }
        catch (MissingResourceException e) {
        if (debug) System.out.println(bundleName + "_" + locale + " not found in " + packageNames[i]);
        throw e;
        }
    }

    return null;
    }

    /**
     * Get a resource bundle from the lookup chain.
     */
    public static ResourceBundle getResourceBundle(String[] packages, String bundleName, String localeName) {
        Locale locale = LocaleUtility.getLocaleFromName(localeName);
        if (locale == null) {
            locale = Locale.getDefault();
        }
        for (int i = 0; i < packages.length; ++i) {
            try {
                String path = packages[i] + "." + bundleName;
                if (debug) System.out.println("calling instantiateBundle: " + path + "_" + locale);
                ResourceBundle rb = instantiateBundle(path, locale);
                return rb;
            }
            catch (MissingResourceException e) {
               if (debug) System.out.println(bundleName + "_" + locale + " not found in " + packages[i]);
               throw e;
            }
        }
        return null;
    }

    /**
     * Get a resource bundle from the lookup chain.
     */
    public static ResourceBundle getResourceBundle(String packageName, String bundleName, String localeName) {
        Locale locale = LocaleUtility.getLocaleFromName(localeName);
        if (locale == null) {
            locale = Locale.getDefault();
        }

        try {
            String path = packageName + "." + bundleName;
            if (debug) System.out.println("calling instantiateBundle: " + path + "_" + locale);
            ResourceBundle rb = instantiateBundle(path, locale);
            return rb;
        }
        catch (MissingResourceException e) {
           if (debug) System.out.println(bundleName + "_" + locale + " not found in " + packageName);
           throw e;
        }
    }
    /**
     * Get a resource bundle from the resource bundle path.  Unlike getResourceBundle, this
     * returns an 'unparented' bundle that exactly matches the bundle name and locale name.
     */
    public static ResourceBundle loadResourceBundle(String bundleName, Locale locale) {
    if (locale == null) {
        locale = Locale.getDefault();
    }
    return loadResourceBundle(bundleName, locale.toString());
    }

    /**
     * Get a resource bundle from the resource bundle path.  Unlike getResourceBundle, this
     * returns an 'unparented' bundle that exactly matches the bundle name and locale name.
     */
    public static ResourceBundle loadResourceBundle(String bundleName, String localeName) {
    if (localeName != null && localeName.length() > 0) {
        bundleName = bundleName + "_" + localeName;
    }
    for (int i = 0; i < packageNames.length; ++i) {
        String name = packageNames[i] + "." + bundleName;
        try {
        if (name.indexOf("_zh_") == -1) { // DLF temporary hack
            Class rbclass = Class.forName(name);
            ResourceBundle rb = (ResourceBundle)rbclass.newInstance();
            return rb;
        }
        }
        catch (ClassNotFoundException e) {
        if (debug) {
            System.out.println(bundleName + " not found in " + packageNames[i]);
        }
        // ignore, keep looking
        }
        catch (Exception e) {
        if (debug) {
            System.out.println(e.getMessage());
        }
        }
    }
    if (debug) {
        System.out.println(bundleName + " not found.");
    }

    return null;
    }

    // ========== privates ==========

    private static Set createLocaleNameSet(String bundleName) {
    try {
        	ResourceBundle index = getResourceBundle(bundleName, "index");
        	Object[][] localeStrings = (Object[][]) index.getObject("InstalledLocales");
        	String[] localeNames = new String[localeStrings.length];

            // barf gag choke spit hack...
            // since java's Locale 'fixes' the locale string for some locales,
            // we have to fix our names to match, otherwise the Locale[] list
            // won't match the locale name set.  What were they thinking?!?
            for (int i = 0; i < localeNames.length; ++i) {
                localeNames[i] = LocaleUtility.getLocaleFromName((String)localeStrings[i][0]).toString();
            }

            HashSet set = new HashSet();
            set.addAll(Arrays.asList(localeNames));
            return Collections.unmodifiableSet(set);
    }
    catch (MissingResourceException e) {
            System.out.println("couldn't find index for bundleName: " + bundleName);
            Thread.dumpStack();
    }
        return Collections.EMPTY_SET;
    }

    private static Locale[] createLocaleList(String bundleName) {
    try {
        ResourceBundle index = getResourceBundle(bundleName, "index");
       	Object[][] localeStrings = (Object[][]) index.getObject("InstalledLocales");
        Locale[] locales = new Locale[localeStrings.length];
        for (int i = 0; i < localeStrings.length; ++i) {
        locales[i] = LocaleUtility.getLocaleFromName((String)localeStrings[i][0]);
        }
        return locales;
    }
    catch (MissingResourceException e) {
            System.out.println("couldn't find index for bundleName: " + bundleName);
            Thread.dumpStack();
    }
    return new Locale[0];
    }
}
