/*
 *  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.naming;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

/**
 * An internationalization / localization helper class which reduces the bother of handling ResourceBundles and takes
 * care of the common cases of message formatting which otherwise require the creation of Object arrays and such.
 * <p>
 * The StringManager operates on a package basis. One StringManager per package can be created and accessed via the
 * getManager method call.
 * <p>
 * The StringManager will look for a ResourceBundle named by the package name given plus the suffix of "LocalStrings".
 * In practice, this means that the localized information will be contained in a LocalStrings.properties file located in
 * the package directory of the classpath.
 * <p>
 * Please see the documentation for java.util.ResourceBundle for more information.
 *
 * @see java.util.ResourceBundle
 */
public class StringManager {

    /**
     * The ResourceBundle for this StringManager.
     */
    private final ResourceBundle bundle;
    private final Locale locale;

    /**
     * Creates a new StringManager for a given package. This is a private method and all access to it is arbitrated by
     * the static getManager method call so that only one StringManager per package will be created.
     *
     * @param packageName Name of package to create StringManager for.
     */
    private StringManager(String packageName) {
        String bundleName = packageName + ".LocalStrings";
        ResourceBundle tempBundle = null;
        try {
            tempBundle = ResourceBundle.getBundle(bundleName, Locale.getDefault());
        } catch (MissingResourceException ex) {
            // Try from the current loader (that's the case for trusted apps)
            // Should only be required if using a TC5 style classloader structure
            // where common != shared != server
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            if (cl != null) {
                try {
                    tempBundle = ResourceBundle.getBundle(bundleName, Locale.getDefault(), cl);
                } catch (MissingResourceException ignore) {
                    // Ignore
                }
            }
        }
        // Get the actual locale, which may be different from the requested one
        if (tempBundle != null) {
            locale = tempBundle.getLocale();
        } else {
            locale = null;
        }
        bundle = tempBundle;
    }

    /**
     * Get a string from the underlying resource bundle or return null if the String is not found.
     *
     * @param key to desired resource String
     *
     * @return resource String matching <i>key</i> from underlying bundle or null if not found.
     *
     * @throws IllegalArgumentException if <i>key</i> is null.
     */
    public String getString(String key) {
        if (key == null) {
            throw new IllegalArgumentException("key may not have a null value");
        }

        String str = null;

        try {
            // Avoid NPE if bundle is null and treat it like an MRE
            if (bundle != null) {
                str = bundle.getString(key);
            }
        } catch (MissingResourceException ignore) {
            // bad: shouldn't mask an exception the following way:
            // str = "[cannot find message associated with key '" + key + "' due to " + mre + "]";
            // because it hides the fact that the String was missing
            // from the calling code.
            // good: could just throw the exception (or wrap it in another)
            // but that would probably cause much havoc on existing
            // code.
            // better: consistent with container pattern to
            // simply return null. Calling code can then do
            // a null check.
            // str is already set to null
        }

        return str;
    }

    /**
     * Get a string from the underlying resource bundle and format it with the given set of arguments.
     *
     * @param key  The key for the required message
     * @param args The values to insert into the message
     *
     * @return The request string formatted with the provided arguments or the key if the key was not found.
     */
    public String getString(final String key, final Object... args) {
        String value = getString(key);
        if (value == null) {
            value = key;
        }

        MessageFormat mf = new MessageFormat(value);
        mf.setLocale(locale);
        return mf.format(args, new StringBuffer(), null).toString();
    }

    // --------------------------------------------------------------
    // STATIC SUPPORT METHODS
    // --------------------------------------------------------------

    private static final Map<String,StringManager> managers = new HashMap<>();

    /**
     * Get the StringManager for a particular package. If a manager for a package already exists, it will be reused,
     * else a new StringManager will be created and returned.
     *
     * @param packageName The package name
     *
     * @return The instance associated with the given package
     */
    public static synchronized StringManager getManager(String packageName) {
        StringManager mgr = managers.get(packageName);
        if (mgr == null) {
            mgr = new StringManager(packageName);
            managers.put(packageName, mgr);
        }
        return mgr;
    }


    /**
     * Returns the StringManager for the package of the given class.
     *
     * @param clazz the class whose package's StringManager is requested
     * @return the StringManager for the specified class's package
     */
    public static StringManager getManager(Class<?> clazz) {
        return getManager(clazz.getPackage().getName());
    }
}
