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

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import com.ibm.icu.util.ULocale;

public class ICULocaleService extends ICUService {
    private Locale fallbackLocale;
    private String fallbackLocaleName;

    /**
     * Construct an ICULocaleService.
     */
    public ICULocaleService() {
    }

    /**
     * Construct an ICULocaleService with a name (useful for debugging).
     */
    public ICULocaleService(String name) {
        super(name);
    }

    /**
     * Convenience override for callers using locales.  This calls
     * get(Locale, int, Locale[]) with KIND_ANY for kind and null for
     * actualReturn.
     */
    public Object get(Locale locale) {
        return get(locale, LocaleKey.KIND_ANY, null);
    }

    /**
     * Convenience override for callers using locales.  This calls
     * get(Locale, int, Locale[]) with a null actualReturn.
     */
    public Object get(Locale locale, int kind) {
        return get(locale, kind, null);
    }

    /**
     * Convenience override for callers using locales. This calls
     * get(Locale, int, Locale[]) with KIND_ANY.
     */
    public Object get(Locale locale, Locale[] actualReturn) {
        return get(locale, LocaleKey.KIND_ANY, actualReturn);
    }
                   
    /**
     * Convenience override for callers using locales. This calls
     * get(ULocale, int, ULocale[]) with KIND_ANY.
     */
    public Object get(ULocale locale, ULocale[] actualReturn) {
        return get(locale, LocaleKey.KIND_ANY, actualReturn);
    }
                   
    /**
     * Convenience override for callers using locales.  This uses
     * createKey(ULocale.toString(), kind) to create a key, calls getKey, and then
     * if actualReturn is not null, returns the actualResult from
     * getKey (stripping any prefix) into a ULocale.  
     */
    public Object get(ULocale locale, int kind, ULocale[] actualReturn) {
        Key key = createKey(locale.toString(), kind);
        if (actualReturn == null) {
            return getKey(key);
        }

        String[] temp = new String[1];
        Object result = getKey(key, temp);
        if (result != null) {
            int n = temp[0].indexOf("/");
            if (n >= 0) {
                temp[0] = temp[0].substring(n+1);
            }
            actualReturn[0] = new ULocale(temp[0]);
        }
        return result;
    }

    /**
     * Convenience override for callers using locales.  This uses
     * createKey(Locale.toString(), kind) to create a key, calls getKey, and then
     * if actualReturn is not null, returns the actualResult from
     * getKey (stripping any prefix) into a Locale.  
     */
    public Object get(Locale locale, int kind, Locale[] actualReturn) {
        Key key = createKey(locale.toString(), kind);
        if (actualReturn == null) {
            return getKey(key);
        }

        String[] temp = new String[1];
        Object result = getKey(key, temp);
        if (result != null) {
            int n = temp[0].indexOf("/");
            if (n >= 0) {
                temp[0] = temp[0].substring(n+1);
            }
            actualReturn[0] = LocaleUtility.getLocaleFromName(temp[0]);
        }
        return result;
    }

    /**
     * Convenience override for callers using locales.  This calls
     * registerObject(Object, Locale, int kind, int coverage)
     * passing KIND_ANY for the kind, and VISIBLE for the coverage.
     */
    public Factory registerObject(Object obj, Locale locale) {
        return registerObject(obj, locale, LocaleKey.KIND_ANY, LocaleKeyFactory.VISIBLE);
    }

    /**
     * Convenience function for callers using locales.  This calls
     * registerObject(Object, Locale, int kind, int coverage)
     * passing VISIBLE for the coverage.
     */
    public Factory registerObject(Object obj, Locale locale, int kind) {
        return registerObject(obj, locale, kind, LocaleKeyFactory.VISIBLE);
    }

    /**
     * Convenience function for callers using locales.  This  instantiates
     * a SimpleLocaleKeyFactory, and registers the factory.
     */
    public Factory registerObject(Object obj, Locale locale, int kind, int coverage) {
        Factory factory = new SimpleLocaleKeyFactory(obj, locale, kind, coverage);
        return registerFactory(factory);
    }

    /**
     * Convenience method for callers using locales.  This returns the standard
     * Locale list, built from the Set of visible ids.
     */
    public Locale[] getAvailableLocales() {
        // TODO make this wrap getAvailableULocales later
        Set visIDs = getVisibleIDs();
        Iterator iter = visIDs.iterator();
        Locale[] locales = new Locale[visIDs.size()];
        int n = 0;
        while (iter.hasNext()) {
            Locale loc = LocaleUtility.getLocaleFromName((String)iter.next());
            locales[n++] = loc;
        }
        return locales;
    }

    /**
     * Convenience method for callers using locales.  This returns the standard
     * ULocale list, built from the Set of visible ids.
     */
    public ULocale[] getAvailableULocales() {
        Set visIDs = getVisibleIDs();
        Iterator iter = visIDs.iterator();
        ULocale[] locales = new ULocale[visIDs.size()];
        int n = 0;
        while (iter.hasNext()) {
            locales[n++] = new ULocale((String)iter.next());
        }
        return locales;
    }
        
    /**
     * A subclass of Key that implements a locale fallback mechanism.
     * The first locale to search for is the locale provided by the
     * client, and the fallback locale to search for is the current
     * default locale.  If a prefix is present, the currentDescriptor
     * includes it before the locale proper, separated by "/".  This
     * is the default key instantiated by ICULocaleService.</p>
     *
     * <p>Canonicalization adjusts the locale string so that the
     * section before the first understore is in lower case, and the rest
     * is in upper case, with no trailing underscores.</p> 
     */
    public static class LocaleKey extends ICUService.Key {
        private int kind;
        private String primaryID;
        private String fallbackID;
        private String currentID;

        public static final int KIND_ANY = -1;

        /**
         * Create a LocaleKey with canonical primary and fallback IDs.
         */
        public static LocaleKey createWithCanonicalFallback(String primaryID, String canonicalFallbackID) {
            return createWithCanonicalFallback(primaryID, canonicalFallbackID, KIND_ANY);
        }
	    
        /**
         * Create a LocaleKey with canonical primary and fallback IDs.
         */
        public static LocaleKey createWithCanonicalFallback(String primaryID, String canonicalFallbackID, int kind) {
            if (primaryID == null) {
                return null;
            }
            String canonicalPrimaryID = LocaleUtility.canonicalLocaleString(primaryID);
            return new LocaleKey(primaryID, canonicalPrimaryID, canonicalFallbackID, kind);
        }
	    
        /**
         * PrimaryID is the user's requested locale string,
         * canonicalPrimaryID is this string in canonical form,
         * fallbackID is the current default locale's string in
         * canonical form.
         */
        protected LocaleKey(String primaryID, String canonicalPrimaryID, String canonicalFallbackID, int kind) {
            super(primaryID);

            this.kind = kind;
	    
            if (canonicalPrimaryID == null) {
                this.primaryID = "";
            } else {
                this.primaryID = canonicalPrimaryID;
            }
            if (this.primaryID == "") {
                this.fallbackID = null;
            } else {
                if (canonicalFallbackID == null || this.primaryID.equals(canonicalFallbackID)) {
                    this.fallbackID = "";
                } else {
                    this.fallbackID = canonicalFallbackID;
                }
            }

            this.currentID = this.primaryID;
        }

        /**
         * Return the prefix associated with the kind, or null if the kind is KIND_ANY.
         */
        public String prefix() {
            return kind == KIND_ANY ? null : Integer.toString(kind());
        }

        /**
         * Return the kind code associated with this key.
         */
        public int kind() {
            return kind;
        }

        /**
         * Return the (canonical) original ID.
         */
        public String canonicalID() {
            return primaryID;
        }

        /**
         * Return the (canonical) current ID, or null if no current id.
         */
        public String currentID() {
            return currentID;
        }

        /**
         * Return the (canonical) current descriptor, or null if no current id.
         */
        public String currentDescriptor() {
            String result = currentID();
            if (result != null) {
                result = "/" + result;
                if (kind != KIND_ANY) {
                    result = prefix() + result;
                }
            }
            return result;
        }

        /**
         * Convenience method to return the locale corresponding to the (canonical) original ID.
         */
        public Locale canonicalLocale() {
            return LocaleUtility.getLocaleFromName(primaryID);
        }

        /**
         * Convenience method to return the locale corresponding to the (canonical) current ID.
         */
        public Locale currentLocale() {
            return LocaleUtility.getLocaleFromName(currentID);
        }

        /**
         * If the key has a fallback, modify the key and return true,
         * otherwise return false.</p>
         *
         * <p>First falls back through the primary ID, then through
         * the fallbackID.  The final fallback is the empty string,
         * unless the primary id was the empty string, in which case
         * there is no fallback.  
         */
        public boolean fallback() {
            int x = currentID.lastIndexOf('_');
            if (x != -1) {
                currentID = currentID.substring(0, x);
                return true;
            }
            if (fallbackID != null) {
                currentID = fallbackID;
                fallbackID = fallbackID.length() == 0 ? null : "";
                return true;
            }
            currentID = null;
            return false;
        }

        /**
         * If a key created from id would eventually fallback to match the 
         * canonical ID of this key, return true.
         */
        public boolean isFallbackOf(String id) {
            return LocaleUtility.isFallbackOf(canonicalID(), id);
        }
    }

    /**
     * A subclass of Factory that uses LocaleKeys, and is able to
     * 'cover' more specific locales with more general locales that it
     * supports.  
     *
     * <p>Coverage may be either of the values VISIBLE or INVISIBLE.
     *
     * <p>'Visible' indicates that the specific locale(s) supported by
     * the factory are registered in getSupportedIDs, 'Invisible'
     * indicates that they are not.
     *
     * <p>Localization of visible ids is handled
     * by the handling factory, regardless of kind.
     */
    public static abstract class LocaleKeyFactory implements Factory {
        protected final String name;
        protected final int coverage;

        /**
         * Coverage value indicating that the factory makes
         * its locales visible, and does not cover more specific 
         * locales.
         */
        public static final int VISIBLE = 0;

        /**
         * Coverage value indicating that the factory does not make
         * its locales visible, and does not cover more specific
         * locales.
         */
        public static final int INVISIBLE = 1;

        // undefine these since hiding other factories opens a big bag of worms
        /*
         * Coverage value indicating that the factory makes
         * its locales visible, covers more specific 
         * locales, and provides localization for the covered
         * locales.
         *
         public static final int VISIBLE_COVERS = 2;

         /**
         * Coverage value indicating that the factory does not
         * make its locales visible, covers more specific
         * locales, and also does not allow the locales it
         * covers to be visible.
         *
         public static final int INVISIBLE_COVERS = 3;

         /**
         * Coverage value indicating that the factory makes
         * its locales visible, covers more specific 
         * locales, but does not allow the locales it covers
         * to be visible.
         *
         public static final int VISIBLE_COVERS_REMOVE = 6;
        */

        
        /**
         * Constructor used by subclasses.
         */
        protected LocaleKeyFactory(int coverage) {
            this.coverage = coverage;
            this.name = null;
        }

        /**
         * Constructor used by subclasses.
         */
        protected LocaleKeyFactory(int coverage, String name) {
            this.coverage = coverage;
            this.name = name;
        }

        /**
         * Implement superclass abstract method.  This checks the currentID of
         * the key against the supported IDs, and passes the canonicalLocale and
         * kind off to handleCreate (which subclasses must implement).
         */
        public Object create(Key key, ICUService service) {
            if (handlesKey(key)) {
                LocaleKey lkey = (LocaleKey)key;
                int kind = lkey.kind();
                
                if (supportsULocale()) {
                    ULocale uloc = new ULocale(lkey.currentID());
                    return handleCreate(uloc, kind, service);
                } else {
                    Locale loc = lkey.currentLocale();
                    return handleCreate(loc, kind, service);
                }
            } else {
                // System.out.println("factory: " + this + " did not support id: " + key.currentID());
                // System.out.println("supported ids: " + getSupportedIDs());
            }
            return null;
        }

        protected boolean handlesKey(Key key) {
            if (key == null) {
                return false;
            }

            String id = key.currentID();
            Set supported = getSupportedIDs();
            return supported.contains(id);
            /*
             * coverage not supported

             if (supported.contains(id)) {
             return true;
             }
             if ((coverage & 0x2) != 0) { 
             Iterator iter = supported.iterator();
             while (iter.hasNext()) {
             String s = (String)iter.next();
             if (LocaleUtility.isFallbackOf(s, id)) {
             return true;
             }
             }
             }
             return false;
            */
        }

        /**
         * Override of superclass method.  This adjusts the result based
         * on the coverage rule for this factory.
         */
        public void updateVisibleIDs(Map result) {
            Set cache = getSupportedIDs();
            
            boolean visible = (coverage & 0x1) == 0;
            // boolean covers = (coverage & 0x2) != 0;
            // boolean removes = !visible || (coverage & 0x4) != 0;

            // System.out.println("vis: " + visible + " covers: " + covers + " removes: " + removes);
            Map toRemap = new HashMap();
            Iterator iter = cache.iterator();
            while (iter.hasNext()) {
                String id = (String)iter.next();
                /*
                 * Coverage not supported
                 if (covers) {
                 int idlen = id.length();
                 Iterator miter = result.keySet().iterator();
                 while (miter.hasNext()) {
                 String mid = (String)miter.next();
                 if (mid.startsWith(id) &&
                 (mid.length() == idlen ||
                 mid.charAt(idlen) == '_')) {

                 if (removes) {
                 miter.remove();
                 } else {
                 toRemap.put(mid, this);
                 }
                 }
                 }
                 }
                */
                if (!visible) {
                    result.remove(id);
                } else {
                    toRemap.put(id, this);
                }

            }                    
            result.putAll(toRemap);
        }

        /**
         * Return a localized name for the locale represented by id.
         */
        public String getDisplayName(String id, Locale locale) {
            // assume if the user called this on us, we must have handled some fallback of this id
            //          if (isSupportedID(id)) {
            if (locale == null) {
                return id;
            }
            Locale loc = LocaleUtility.getLocaleFromName(id);
            return loc.getDisplayName(locale);
            //  	    }
            //          return null;
        }

        /**
         * Return true if this object supports ULocale.  If so, then
         * handleCreate(ULocale,...) will be called to instantiate objects.
         * Otherwise handleCreate(Locale,...) will be called.  By default,
         * subclasses do NOT support ULocale.
         *
         * SUBCLASSES should either:
         *
         * [1] implement handleCreate(Locale,...)
         *
         * or (preferably)
         *
         * [2] implement handleCreate(ULocale,...) and override
         *     supportsULocale() to return true
         */
        protected boolean supportsULocale() {
            return false;   
        }
    
        ///CLOVER:OFF
        /**
         * Utility method used by create(Key, ICUService).  Subclasses can
         * implement this instead of create.  Subclasses should implement
         * either this method or handleCreate(ULocale,...), but NOT BOTH.
         */
        protected Object handleCreate(Locale loc, int kind, ICUService service) {
            return null;
        }
        ///CLOVER:ON

        ///CLOVER:OFF
        /**
         * Utility method used by create(Key, ICUService).  Subclasses can
         * implement this instead of create.  Subclasses should implement
         * either this method or handleCreate(Locale,...), but NOT BOTH.
         * If a subclass implements this method, it should also override
         * supportULocale() to return true.
         */
        protected Object handleCreate(ULocale loc, int kind, ICUService service) {
            return null;
        }
        ///CLOVER:ON

        /**
         * Return true if this id is one the factory supports (visible or 
         * otherwise).
         */
        protected boolean isSupportedID(String id) {
            return getSupportedIDs().contains(id);
        }
        
        /**
         * Return the set of ids that this factory supports (visible or 
         * otherwise).  This can be called often and might need to be
         * cached if it is expensive to create.
         */
        protected Set getSupportedIDs() {
            return Collections.EMPTY_SET;
        }

        /**
         * For debugging.
         */
        public String toString() {
            StringBuffer buf = new StringBuffer(super.toString());
            if (name != null) {
                buf.append(", name: ");
                buf.append(name);
            }
            buf.append(", coverage: ");
            String[] coverage_names = {
                "visible", "invisible", "visible_covers", "invisible_covers", "????", "visible_covers_remove"
            };
            buf.append(coverage_names[coverage]);
            return buf.toString();
        }
    }

    /**
     * A LocaleKeyFactory that just returns a single object for a kind/locale.
     */
    public static class SimpleLocaleKeyFactory extends LocaleKeyFactory {
        private final Object obj;
        private final String id;
        private final int kind;

        public SimpleLocaleKeyFactory(Object obj, Locale locale, int kind, int coverage) {
            this(obj, locale, kind, coverage, null);
        }

        public SimpleLocaleKeyFactory(Object obj, Locale locale, int kind, int coverage, String name) {
            super(coverage, name);
            
            this.obj = obj;
            this.id = LocaleUtility.canonicalLocaleString(locale.toString());
            this.kind = kind;
        }

        /**
         * Returns the service object if kind/locale match.  Service is not used.
         */
        public Object create(Key key, ICUService service) {
            LocaleKey lkey = (LocaleKey)key;
            if (kind == LocaleKey.KIND_ANY || kind == lkey.kind()) {
                String keyID = lkey.currentID();
                if (id.equals(keyID)) {
                    return obj;
                }
            }
            return null;
        }

        protected boolean isSupportedID(String id) {
            return this.id.equals(id);
        }

        public void updateVisibleIDs(Map result) {
            if ((coverage & 0x1) == 0) {
                result.put(id, this);
            } else {
                result.remove(id);
            }
        }

        public String toString() {
            StringBuffer buf = new StringBuffer(super.toString());
            buf.append(", id: ");
            buf.append(id);
            buf.append(", kind: ");
            buf.append(kind);
            return buf.toString();
        }
    }

    /**
     * A LocaleKeyFactory that creates a service based on the ICU locale data.
     * This is a base class for most ICU factories.  Subclasses instantiate it
     * with a constructor that takes a bundle name, which determines the supported
     * IDs.  Subclasses then override handleCreate to create the actual service
     * object.  The default implementation returns a resource bundle.
     */
    public static class ICUResourceBundleFactory extends LocaleKeyFactory {
        protected final String bundleName;

        /**
         * Convenience constructor that uses the main ICU bundle name.
         */
        public ICUResourceBundleFactory() {
            this(ICUResourceBundle.ICU_BASE_NAME);
        }

        /**
         * A service factory based on ICU resource data in resources
         * with the given name.
         */
        public ICUResourceBundleFactory(String bundleName) {
            super(VISIBLE);

            this.bundleName = bundleName;
        }

        /**
         * Return the supported IDs.  This is the set of all locale names in ICU_BASE_NAME.
         */
        protected Set getSupportedIDs() {
            return ICUResourceBundle.getAvailableLocaleNameSet(bundleName);
        }

        /**
         * Create the service.  The default implementation returns the resource bundle
         * for the locale, ignoring kind, and service.
         */
        protected Object handleCreate(Locale loc, int kind, ICUService service) {
            return ICUResourceBundle.getBundleInstance(bundleName, loc);
        }

        public String toString() {
            return super.toString() + ", bundle: " + bundleName;
        }
    }

    /**
     * Return the name of the current fallback locale.  If it has changed since this was
     * last accessed, the service cache is cleared.
     */
    public String validateFallbackLocale() {
        Locale loc = Locale.getDefault();
        if (loc != fallbackLocale) {
            synchronized (this) {
                if (loc != fallbackLocale) {
                    fallbackLocale = loc;
                    fallbackLocaleName = LocaleUtility.canonicalLocaleString(loc.toString());
                    clearServiceCache();
                }
            }
        }
        return fallbackLocaleName;
    }

    public Key createKey(String id) {
        return LocaleKey.createWithCanonicalFallback(id, validateFallbackLocale());
    }

    public Key createKey(String id, int kind) {
        return LocaleKey.createWithCanonicalFallback(id, validateFallbackLocale(), kind);
    }
}
