/*
 * (C) Copyright IBM Corp. 2002-2008 - 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.HashMap;
import java.util.Map;

import com.ibm.icu.util.ULocale;

/**
 * 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 {

    /**
     * The package for ICU locale data.
     */
    private static final String ICU_PACKAGE = "com.ibm.icu.impl.data";

    /**
     * The base name (bundle name) for ICU locale data.
     */
    static final String LOCALE_ELEMENTS = "LocaleElements";

    /**
     * Creates a LocaleElements resource bundle for the given locale
     * in the default ICU package.
     * @param locale the locale of the bundle to retrieve, or
     * null to use the default locale
     * @return a ResourceBundle for the LocaleElements of the given
     * locale, or null on failure
     */
    public static ResourceBundle getLocaleElements(ULocale locale) {
        if (locale == null) {
            locale = ULocale.getDefault();
        }
        return getResourceBundle(ICU_PACKAGE, LOCALE_ELEMENTS, locale.getBaseName());
    }

    /**
     * Creates a LocaleElements resource bundle for the given locale
     * in the default ICU package.
     * @param localeName the string name of the locale of the bundle
     * to retrieve, e.g., "en_US".
     * @return a ResourceBundle for the LocaleElements of the given
     * locale, or null on failure
     */
    public static ResourceBundle getLocaleElements(String localeName) {
        return getResourceBundle(ICU_PACKAGE, LOCALE_ELEMENTS, localeName);
    }


    /**
     * Creates a resource bundle for the given base name and locale
     * in the default ICU package.
     * @param bundleName the base name of the bundle to retrieve,
     * e.g. "LocaleElements".
     * @param localeName the string name of the locale of the bundle
     * to retrieve, e.g. "en_US".
     * @return a ResourceBundle with the given base name for the given
     * locale, or null on failure
     */
    public static ResourceBundle getResourceBundle(String bundleName, String localeName) {
        return getResourceBundle(ICU_PACKAGE, bundleName, localeName);
    }

    /**
     * Creates a resource bundle for the given base name and locale
     * in the default ICU package.
     * @param bundleName the base name of the bundle to retrieve,
     * e.g. "LocaleElements".
     * @param locale the locale of the bundle to retrieve, or
     * null to use the default locale
     * @return a ResourceBundle with the given base name for the given
     * locale, or null on failure
     */
    public static ResourceBundle getResourceBundle(String bundleName, ULocale locale) {
        if (locale == null) {
            locale = ULocale.getDefault();
        }
        return getResourceBundle(ICU_PACKAGE, bundleName, locale.getBaseName());
    }

    /**
     * Creates a resource bundle for the given package, base name, and
     * locale.
     * @param packageName a package name, e.g., "com.ibm.icu.impl.data".
     * @param bundleName the base name of the bundle to retrieve,
     * e.g. "LocaleElements".
     * @param localeName the string name of the locale of the bundle
     * to retrieve, e.g. "en_US".
     * @return the first ResourceBundle with the given base name for
     * the given locale found in each of the packages, or null on
     * failure
     */
    public static ResourceBundle getResourceBundle(String packageName, String bundleName, String localeName) {
        try {
            String path = packageName + "." + bundleName;
            if (DEBUG) System.out.println("calling instantiate: " + path + "_" + localeName);
            return instantiate(path, localeName);
        } catch (MissingResourceException e) {
            if (DEBUG) System.out.println(bundleName + "_" + localeName + " not found in " + packageName);
            throw e;
        }
    }

    /**
     * Creates a resource bundle for the given base name and locale in
     * one of the given packages, trying each package in order.
     * @param packages a list of one or more package names
     * @param bundleName the base name of the bundle to retrieve,
     * e.g. "LocaleElements".
     * @param localeName the string name of the locale of the bundle
     * to retrieve, e.g. "en_US".
     * @return the first ResourceBundle with the given base name for
     * the given locale found in each of the packages, or null on
     * failure
     */
    public static ResourceBundle getResourceBundle(String[] packages, String bundleName, String localeName) {
        ResourceBundle r=null;
        for (int i=0; r==null && i<packages.length; ++i) {
            r = getResourceBundle(packages[i], bundleName, localeName);
        }
        return r;
    }

    /**
     * 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, ULocale locale) {
        if (locale == null) {
            locale = ULocale.getDefault();
        }
        return loadResourceBundle(bundleName, locale.getBaseName());
    }

    /**
     * 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;
        }
        String name = ICU_PACKAGE + "." + 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(name + " not found");
            }
            // ignore, keep looking
        }
        catch (Exception e) {
            if (DEBUG) {
                e.printStackTrace();
                System.out.println(e.getMessage());
            }
        }
        if (DEBUG) {
            System.out.println(bundleName + " not found.");
        }

        return null;
    }

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

    // Flag for enabling/disabling debugging code
    private static final boolean DEBUG = ICUDebug.enabled("localedata");

    // Cache for getAvailableLocales
    //private static SoftReference GET_AVAILABLE_CACHE;

    // Cache for ResourceBundle instantiation
    private static SoftReference BUNDLE_CACHE;

    private static ResourceBundle loadFromCache(String key) {
        if (BUNDLE_CACHE != null) {
            Map m = (Map)BUNDLE_CACHE.get();
            if (m != null) {
                return (ResourceBundle)m.get(key);
            }
        }
        return null;
    }

    private static void addToCache(String key, ResourceBundle b) {
        Map m = null;
        if (BUNDLE_CACHE != null) {
            m = (Map)BUNDLE_CACHE.get();
        }
        if (m == null) {
            m = new HashMap();
            BUNDLE_CACHE = new SoftReference(m);
        }
        m.put(key, b);
    }

    // recursively build bundle
    private static ResourceBundle instantiate(String name) {
        ResourceBundle b = loadFromCache(name);
        if (b == null) {
            ResourceBundle parent = null;
            int i = name.lastIndexOf('_');

            // TODO: convert this to use ULocale
            final Locale rootLocale = new Locale("", "", "");
 
            if (i != -1) {
                parent = instantiate(name.substring(0, i));
            }
            try {
                Locale locale = rootLocale;
                i = name.indexOf('_');
                if (i != -1) {
                    locale = LocaleUtility.getLocaleFromName(name.substring(i+1));
                } else {
                    i = name.length();
                }

                ClassLoader cl = ICULocaleData.class.getClassLoader();
                if (cl == null) {
                    // we're on the bootstrap
                    cl = ClassLoader.getSystemClassLoader();
                }
                Class cls = cl.loadClass(name);
				b = ResourceBundle.getBundle(name.substring(0, i), locale); 
                addToCache(name, b);
            }
            catch (ClassNotFoundException e) {

                int j = name.indexOf('_');
                int k = name.lastIndexOf('_');
                // if a bogus locale is passed then the parent should be
                // the default locale not the root locale!
                if(k==j && j!=-1){
                    
                    String locName = name.substring(j+1,name.length());
                    String defaultName = ULocale.getDefault().toString();
                    
                    if(!locName.equals(rootLocale.toString()) &&
                       defaultName.indexOf(locName)==-1){
                        String bundle =  name.substring(0,j);
                        parent = instantiate(bundle+"_"+defaultName);
                    }
                }
                b = parent;
            }
            catch (Exception e) {
                System.out.println("failure");
                System.out.println(e);
            }
        }
        //if(b==null){
        //    throw new MissingResourceException("Could not load data "+name,"","");
        //}
        return b;
    }

    /**
     * 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 synchronized static ResourceBundle instantiate(String name, String localeName) {
        if (localeName.length() != 0) {
            name = name + "_" + localeName;
        }
        ResourceBundle b =  instantiate(name);
        if(b==null){
            throw new MissingResourceException("Could not load data "+name,"","");
        }
        return b;
    }

/*    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) {
            if (DEBUG) 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) {
            if (DEBUG) System.out.println("couldn't find index for bundleName: " + bundleName);
            Thread.dumpStack();
        }
        return new Locale[0];
    }
    */
}
