/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.axis2.i18n;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

/**
 * <p>Wrapper class for resource bundles. Property files are used to store
 * resource strings, which are the only types of resources available.
 * Property files can inherit properties from other files so that
 * a base property file can be used and a small number of properties
 * can be over-ridden by another property file. For example you may
 * create an english version of a resource file named "resource.properties".
 * You then decide that the British English version of all of the properties
 * except one are the same, so there is no need to redefine all of the
 * properties in "resource_en_GB", just the one that is different.</p>
 * <p>The basename is the name of the property file without the ".properties"
 * extension.</p>
 * <p>Properties will be cached for performance.<p>
 * <p>Property values stored in the property files can also contain dynamic
 * variables. Any dynamic variable defined in PropertiesUtil.getVariableValue()
 * can be used (such as {date}), as well as arguments in the form {0}, {1}, etc.
 * Argument values are specified in the various overloaded getString() methods.</p>
 */
public class ProjectResourceBundle extends ResourceBundle {
    private static final Log log = LogFactory.getLog(ProjectResourceBundle.class);


    // The static cache of ResourceBundles.
    // The key is the 'basename + locale + default locale'
    // The element is a ResourceBundle object
    private static final Hashtable bundleCache = new Hashtable();

    private static final Locale defaultLocale = Locale.getDefault();

    private final ResourceBundle resourceBundle;
    private final String resourceName;


    protected Object handleGetObject(String key)
            throws MissingResourceException {
        if (log.isDebugEnabled()) {
            log.debug(this.toString() + "::handleGetObject(" + key + ")");
        }
        Object obj;
        try {
            obj = resourceBundle.getObject(key);
        } catch (MissingResourceException e) {
            /* catch missing resource, ignore, & return null
             * if this method doesn't return null, then parents
             * are not searched
             */
            obj = null;
        }
        return obj;
    }

    public Enumeration getKeys() {
        Enumeration myKeys = resourceBundle.getKeys();
        if (parent == null) {
            return myKeys;
        } else {
            final HashSet set = new HashSet();
            while (myKeys.hasMoreElements()) {
                set.add(myKeys.nextElement());
            }

            Enumeration pKeys = parent.getKeys();
            while (pKeys.hasMoreElements()) {
                set.add(pKeys.nextElement());
            }

            return new Enumeration() {
                private Iterator it = set.iterator();

                public boolean hasMoreElements() {
                    return it.hasNext();
                }

                public Object nextElement() {
                    return it.next();
                }
            };
        }
    }


    /**
     * Construct a new ProjectResourceBundle
     *
     * @param projectName  The name of the project to which the class belongs.
     *                     It must be a proper prefix of the caller's package.
     * @param packageName  The package name to further construct
     *                     the basename.
     * @param resourceName The name of the resource without the
     *                     ".properties" extension
     * @throws MissingResourceException if projectName is not a prefix of
     *                                  the caller's package name, or if the resource could not be
     *                                  found/loaded.
     */
    public static ProjectResourceBundle getBundle(String projectName,
                                                  String packageName,
                                                  String resourceName)
            throws MissingResourceException {
        return getBundle(projectName, packageName, resourceName, null, null, null);
    }

    /**
     * Construct a new ProjectResourceBundle
     *
     * @param projectName  The name of the project to which the class belongs.
     *                     It must be a proper prefix of the caller's package.
     * @param caller       The calling class.
     * @param resourceName The name of the resource without the
     *                     ".properties" extension
     * @throws MissingResourceException if projectName is not a prefix of
     *                                  the caller's package name, or if the resource could not be
     *                                  found/loaded.
     */
    public static ProjectResourceBundle getBundle(String projectName,
                                                  Class caller,
                                                  String resourceName,
                                                  Locale locale)
            throws MissingResourceException {
        return getBundle(projectName,
                         caller,
                         resourceName,
                         locale,
                         null);
    }

    /**
     * Construct a new ProjectResourceBundle
     *
     * @param projectName  The name of the project to which the class belongs.
     *                     It must be a proper prefix of the caller's package.
     * @param packageName  The package name to construct base name.
     * @param resourceName The name of the resource without the
     *                     ".properties" extension
     * @param locale       The locale
     * @throws MissingResourceException if projectName is not a prefix of
     *                                  the caller's package name, or if the resource could not be
     *                                  found/loaded.
     */
    public static ProjectResourceBundle getBundle(String projectName,
                                                  String packageName,
                                                  String resourceName,
                                                  Locale locale,
                                                  ClassLoader loader)
            throws MissingResourceException {
        return getBundle(projectName, packageName, resourceName, locale, loader, null);
    }

    /**
     * Construct a new ProjectResourceBundle
     *
     * @param projectName   The name of the project to which the class belongs.
     *                      It must be a proper prefix of the caller's package.
     * @param caller        The calling class.
     *                      This is used to get the package name to further construct
     *                      the basename as well as to get the proper ClassLoader.
     * @param resourceName  The name of the resource without the
     *                      ".properties" extension
     * @param locale        The locale
     * @param extendsBundle If non-null, then this ExtendMessages will
     *                      default to extendsBundle.
     * @throws MissingResourceException if projectName is not a prefix of
     *                                  the caller's package name, or if the resource could not be
     *                                  found/loaded.
     */
    public static ProjectResourceBundle getBundle(String projectName,
                                                  Class caller,
                                                  String resourceName,
                                                  Locale locale,
                                                  ResourceBundle extendsBundle)
            throws MissingResourceException {
        return getBundle(projectName,
                         getPackage(caller.getClass().getName()),
                         resourceName,
                         locale,
                         caller.getClass().getClassLoader(),
                         extendsBundle);
    }

    /**
     * Construct a new ProjectResourceBundle
     *
     * @param projectName   The name of the project to which the class belongs.
     *                      It must be a proper prefix of the caller's package.
     * @param packageName   The package name to further construct
     *                      the basename.
     * @param resourceName  The name of the resource without the
     *                      ".properties" extension
     * @param locale        The locale
     * @param extendsBundle If non-null, then this ExtendMessages will
     *                      default to extendsBundle.
     * @throws MissingResourceException if projectName is not a prefix of
     *                                  the caller's package name, or if the resource could not be
     *                                  found/loaded.
     */
    public static ProjectResourceBundle getBundle(String projectName,
                                                  String packageName,
                                                  String resourceName,
                                                  Locale locale,
                                                  ClassLoader loader,
                                                  ResourceBundle extendsBundle)
            throws MissingResourceException {
        if (log.isDebugEnabled()) {
            log.debug("getBundle(" + projectName + ","
                    + packageName + ","
                    + resourceName + ","
                    + String.valueOf(locale) + ",...)");
        }

        Context context = new Context();
        context.setLocale(locale);
        context.setLoader(loader);
        context.setProjectName(projectName);
        context.setResourceName(resourceName);
        context.setParentBundle(extendsBundle);

        packageName = context.validate(packageName);

        ProjectResourceBundle bundle = null;
        try {
            bundle = getBundle(context, packageName);
        } catch (RuntimeException e) {
            log.debug("Exception: ", e);
            throw e;
        }

        if (bundle == null) {
            throw new MissingResourceException("Cannot find resource '" +
                    packageName + '.' + resourceName + "'",
                                               resourceName, "");
        }

        return bundle;
    }

    /**
     * get bundle...
     * - check cache
     * - try up hierarchy
     * - if at top of hierarchy, use (link to) context.getParentBundle()
     */
    private static synchronized ProjectResourceBundle getBundle(Context context, String packageName)
            throws MissingResourceException {
        String cacheKey = context.getCacheKey(packageName);

        ProjectResourceBundle prb = (ProjectResourceBundle) bundleCache.get(cacheKey);

        if (prb == null) {
            String name = packageName + '.' + context.getResourceName();
            ResourceBundle rb = context.loadBundle(packageName);
            ResourceBundle parent = context.getParentBundle(packageName);

            if (rb != null) {
                prb = new ProjectResourceBundle(name, rb);
                prb.setParent(parent);
                if (log.isDebugEnabled()) {
                    log.debug("Created " + prb + ", linked to parent " + String.valueOf(parent));
                }
            } else {
                if (parent != null) {
                    if (parent instanceof ProjectResourceBundle) {
                        prb = (ProjectResourceBundle) parent;
                    } else {
                        prb = new ProjectResourceBundle(name, parent);
                    }
                    if (log.isDebugEnabled()) {
                        log.debug("Root package not found, cross link to " + parent);
                    }
                }
            }

            if (prb != null) {
                // Cache the resource
                bundleCache.put(cacheKey, prb);
            }
        }

        return prb;
    }

    private static String getPackage(String name) {
        return name.substring(0, name.lastIndexOf('.')).intern();
    }

    /**
     * Construct a new ProjectResourceBundle
     */
    private ProjectResourceBundle(String name, ResourceBundle bundle)
            throws MissingResourceException {
        this.resourceBundle = bundle;
        this.resourceName = name;
    }

    public String getResourceName() {
        return resourceName;
    }

    /**
     * Clears the internal cache
     */
//    public static void clearCache() {
//        bundleCache.clear();
//    }
    public String toString() {
        return resourceName;
    }


    private static class Context {
        private Locale _locale;
        private ClassLoader _loader;
        private String _projectName;
        private String _resourceName;
        private ResourceBundle _parent;

        void setLocale(Locale l) {
            /* 1. Docs indicate that if locale is not specified,
             *    then the default local is used in it's place.
             * 2. A null value for locale is invalid.
             * 
             * Therefore, default...
             */
            _locale = (l == null) ? defaultLocale : l;
        }

        void setLoader(ClassLoader l) {
            _loader = (l != null) ? l : this.getClass().getClassLoader();
            // START FIX: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=16868
            if (_loader == null) {
                _loader = ClassLoader.getSystemClassLoader();
            }
            // END FIX: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=16868
        }

        void setProjectName(String name) {
            _projectName = name.intern();
        }

        void setResourceName(String name) {
            _resourceName = name.intern();
        }

        void setParentBundle(ResourceBundle b) {
            _parent = b;
        }

        Locale getLocale() {
            return _locale;
        }

        ClassLoader getLoader() {
            return _loader;
        }

        String getProjectName() {
            return _projectName;
        }

        String getResourceName() {
            return _resourceName;
        }

        ResourceBundle getParentBundle() {
            return _parent;
        }

        String getCacheKey(String packageName) {
            String loaderName = (_loader == null) ? "" : (":" + _loader.hashCode());
            return packageName + "." + _resourceName + ":" + _locale + ":" + defaultLocale +
                    loaderName;
        }

        ResourceBundle loadBundle(String packageName) {
            try {
                return ResourceBundle.getBundle(packageName + '.' + _resourceName,
                                                _locale,
                                                _loader);
            } catch (MissingResourceException e) {
                // Deliberately surpressing print stack.. just the string for info.
                log.debug("loadBundle: Ignoring MissingResourceException: " + e.getMessage());
            }
            return null;
        }

        ResourceBundle getParentBundle(String packageName) {
            ResourceBundle p;
            if (!packageName.equals(_projectName)) {
                p = getBundle(this, getPackage(packageName));
            } else {
                p = _parent;
                _parent = null;
            }
            return p;
        }

        String validate(String packageName)
                throws MissingResourceException {
            if (_projectName == null || _projectName.length() == 0) {
                log.debug("Project name not specified");
                throw new MissingResourceException("Project name not specified",
                                                   "", "");
            }

            if (packageName == null || packageName.length() == 0) {
                log.debug("Package name not specified");
                throw new MissingResourceException("Package not specified",
                                                   packageName, "");
            }
            packageName = packageName.intern();

            /* Ensure that project is a proper prefix of class.
            * Terminate project name with '.' to ensure proper match.
            */
            if (!packageName.equals(_projectName) && !packageName.startsWith(_projectName + '.')) {
                log.debug("Project not a prefix of Package");
                throw new MissingResourceException("Project '" + _projectName
                        + "' must be a prefix of Package '"
                        + packageName + "'",
                                                   packageName + '.' + _resourceName, "");
            }

            return packageName;
        }
    }
}
