/*
 * 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.openjpa.lib.util;

import java.security.AccessController;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * The Localizer provides convenient access to localized
 * strings. It inlcudes built-in support for parameter substitution through
 * the use of the {@link MessageFormat} utility.
 * Strings are stored in per-package {@link Properties} files.
 * The property file for the default locale must be named
 * <code>localizer.properties</code>. Additional locales can be supported
 * through additional property files using the naming conventions specified
 * in the {@link ResourceBundle} class. For example, the german locale
 * could be supported through a <code>localizer_de_DE.properties</code> file.
 *
 * @author Abe White
 */
public class Localizer {

    // static cache of package+loc name to localizer mappings
    private static final Map<String,Localizer> _localizers = new ConcurrentHashMap<>();

    // list of resource providers to delegate to when locating resources
    private static final Collection<ResourceBundleProvider> _providers =
        new CopyOnWriteArraySet<>
        (Arrays.asList(new ResourceBundleProvider[]{
            new SimpleResourceBundleProvider(),
            new StreamResourceBundleProvider(),
            new ZipResourceBundleProvider(), }));

    /**
     * Return a Localizer instance that will access the properties file
     * in the package of the given class using the system default locale.
     *
     * @see #forPackage(Class,Locale)
     */
    public static Localizer forPackage(Class<?> cls) {
        return forPackage(cls, null);
    }

    /**
     * Return a Localizer instance that will access the properties file
     * in the package of the given class using the given locale.
     *
     * @param cls the class whose package to check for the localized
     * properties file; if null, the system will check for
     * a top-level properties file
     * @param locale the locale to which strings should be localized; if
     * null, the system default will be assumed
     */
    public static Localizer forPackage(Class<?> cls, Locale locale) {
        if (locale == null)
            locale = Locale.getDefault();

        int dot = (cls == null) ? -1 : cls.getName().lastIndexOf('.');
        String pkg;
        String file;
        if (dot == -1) {
            pkg = "";
            file = "localizer";
        } else {
            pkg = cls.getName().substring(0, dot);
            file = pkg + ".localizer";
        }
        String key = file + locale.toString();

        // no locking; ok if bundle created multiple times
        // check for cached version
        Localizer loc = (Localizer) _localizers.get(key);
        if (loc != null)
            return loc;
        else {
            loc = new Localizer(pkg, file, locale,
                cls == null ? null:AccessController.doPrivileged(
                    J2DoPrivHelper.getClassLoaderAction(cls)));
            _localizers.put(key, loc);
            return loc;
        }
    }

    /**
     * Register a resource provider.
     */
    public static void addProvider(ResourceBundleProvider provider) {
        _providers.add(provider);
    }

    /**
     * Remove a resource provider.
     */
    public static boolean removeProvider(ResourceBundleProvider provider) {
        return _providers.remove(provider);
    }

    private String _file;
    private String _pkg;
    private ResourceBundle _bundle = null;
    private Locale _locale;
    private ClassLoader _loader;

    private Localizer(String pkg, String f, Locale locale, ClassLoader loader) {
        _pkg = pkg;
        _file = f;
        _locale = locale;
        _loader = loader;
    }

    private ResourceBundle getBundle() {
        // no locking; it's ok to create multiple bundles
        if (_bundle == null) {
            // find resource bundle
            for (Iterator<ResourceBundleProvider> itr = _providers.iterator();
                itr.hasNext() && _bundle == null; ) {
                _bundle = itr.next().findResource(_file, _locale, _loader);
            }
        }
        return _bundle;
    }

    /**
     * Return the localized string matching the given key.
     */
    public Message get(String key) {
        return get(key, null);
    }

    /**
     * Return the localized string matching the given key.
     */
    public Message getFatal(String key) {
        return getFatal(key, null);
    }

    /**
     * Return the localized string matching the given key. The given
     * <code>sub</code> object will be packed into an array and substituted
     * into the found string according to the rules of the
     * {@link MessageFormat} class.
     *
     * @see #get(String)
     */
    public Message get(String key, Object sub) {
        return get(key, new Object[]{ sub });
    }

    /**
     * Return the localized string matching the given key. The given
     * <code>sub</code> object will be packed into an array and substituted
     * into the found string according to the rules of the
     * {@link MessageFormat} class.
     *
     * @see #getFatal(String)
     */
    public Message getFatal(String key, Object sub) {
        return getFatal(key, new Object[]{ sub });
    }

    /**
     * Return the localized string for the given key.
     *
     * @see #get(String,Object)
     */
    public Message get(String key, Object sub1, Object sub2) {
        return get(key, new Object[]{ sub1, sub2 });
    }

    /**
     * Return the localized string for the given key.
     *
     * @see #getFatal(String,Object)
     */
    public Message getFatal(String key, Object sub1, Object sub2) {
        return getFatal(key, new Object[]{ sub1, sub2 });
    }

    /**
     * Return the localized string for the given key.
     *
     * @see #get(String,Object)
     */
    public Message get(String key, Object sub1, Object sub2, Object sub3) {
        return get(key, new Object[]{ sub1, sub2, sub3 });
    }

    /**
     * Return the localized string matching the given key. The given
     * <code>subs</code> objects will be substituted
     * into the found string according to the rules of the
     * {@link MessageFormat} class.
     *
     * @see #get(String)
     */
    public Message get(String key, Object[] subs) {
        return new Message(_pkg, getBundle(), key, subs, false);
    }

    /**
     * Return the localized string matching the given key. The given
     * <code>subs</code> objects will be substituted
     * into the found string according to the rules of the
     * {@link MessageFormat} class.
     *
     * @see #getFatal(String)
     */
    public Message getFatal(String key, Object[] subs) {
        return new Message(_pkg, getBundle(), key, subs, true);
    }

    /**
     * A <code>Message</code> can provide a localized message via the
     * {@link #getMessage} method call, and can also provide the original key,
     * package, and substitution array that were used to assemble the message.
     */
    public static class Message {

        private final String _pkg;
        private final String _key;
        private final Object[] _subs;
        private final String _localizedMessage;
        private boolean _localizedMessageFound;

        private Message(String packageName, ResourceBundle bundle, String key,
            Object[] subs, boolean fatal) {
            if (bundle == null && fatal)
                throw new MissingResourceException(key, key, key);

            _pkg = packageName;
            _key = key;
            _subs = subs;
            if (bundle == null) {
                _localizedMessage = key;
                _localizedMessageFound = false;
            } else {
                String localized = null;
                try {
                    localized = bundle.getString(key);
                    _localizedMessageFound = true;
                } catch (MissingResourceException mre) {
                    if (fatal)
                        throw mre;
                    _localizedMessageFound = false;
                }
                _localizedMessage = (localized == null) ? key : localized;
            }
        }

        /**
         * The localized message.
         */
        public String getMessage() {
            if (_localizedMessageFound)
                return MessageFormat.format(_localizedMessage, _subs);
            else if (_subs == null || _subs.length == 0)
                return "localized message key: " + _localizedMessage;
            else
                return "localized message key: " + _localizedMessage
                    + "; substitutions: " + Arrays.asList(_subs).toString();
        }

        /**
         * The unique key for the localized message.
         */
        public String getKey() {
            return _key;
        }

        /**
         * Substitutions inserted into the message.
         */
        public Object[] getSubstitutions() {
            return _subs;
        }

        public String getPackageName() {
            return _pkg;
        }

        @Override
        public String toString() {
            return getMessage();
        }
    }
}
