/*
 * 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
<<<<<<< Updated upstream
 *
 *     https://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
=======
 * 
 *     https://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 
>>>>>>> Stashed changes
 * limitations under the License.
 */

package javax.jdo.spi;

import java.lang.reflect.InvocationTargetException;
import java.security.PrivilegedAction;
import java.text.MessageFormat;
import java.util.Hashtable;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.jdo.JDOFatalInternalException;
import javax.jdo.LegacyJava;

/**
 * Helper class for constructing messages from bundles. The intended usage of this class is to
 * construct a new instance bound to a bundle, as in
 *
 * <p><code>I18NHelper msg = I18NHelper.getInstance("javax.jdo.Bundle");</code>
 *
 * <p>This call uses the class loader that loaded the I18NHelper class to find the specified Bundle.
 * The class provides two overloaded getInstance methods allowing to specify a different class
 * loader: {@link #getInstance(Class cls)} looks for a bundle called "Bundle.properties" located in
 * the package of the specified class object and {@link #getInstance(String bundleName,ClassLoader
 * loader)} uses the specified class loader to find the bundle.
 *
 * <p>Subsequently, instance methods can be used to format message strings using the text from the
 * bundle, as in
 *
 * <p><code>throw new JDOFatalInternalException (msg.msg("ERR_NoMetadata",
 * cls.getName()));</code>
 *
 * @since 1.0.1
 * @version 1.1
 */
public class I18NHelper {

  /** Bundles that have already been loaded */
  private static final Hashtable<String, ResourceBundle> bundles = new Hashtable<>();

  /** Helper instances that have already been created */
  private static final Hashtable<String, I18NHelper> helpers = new Hashtable<>();

  /** The default locale for this VM. */
  private static final Locale locale = Locale.getDefault();

  /** The bundle used by this instance of the helper. */
  private ResourceBundle bundle = null;

  /** Throwable if ResourceBundle couldn't be loaded */
  private Throwable failure = null;

  /** The unqualified standard name of a bundle. */
  private static final String BUNDLE_SUFFIX = ".Bundle"; // NOI18N

  /** Constructor */
  private I18NHelper() {}

  /**
   * Constructor for an instance bound to a bundle.
   *
   * @param bundleName the name of the resource bundle
   * @param loader the class loader from which to load the resource bundle
   */
  private I18NHelper(String bundleName, ClassLoader loader) {
    try {
      bundle = loadBundle(bundleName, loader);
    } catch (Throwable e) {
      failure = e;
    }
  }

  /**
   * An instance bound to a bundle. This method uses the current class loader to find the bundle.
   *
   * @param bundleName the name of the bundle
   * @return the helper instance bound to the bundle
   */
  public static I18NHelper getInstance(String bundleName) {
    return getInstance(bundleName, I18NHelper.class.getClassLoader());
  }

  /**
   * An instance bound to a bundle. This method figures out the bundle name for the class object's
   * package and uses the class' class loader to find the bundle. Note, the specified class object
   * must not be <code>null</code>.
   *
   * @param cls the class object from which to load the resource bundle
   * @return the helper instance bound to the bundle
   */
  public static I18NHelper getInstance(final Class<?> cls) {
    ClassLoader classLoader = doPrivileged(cls::getClassLoader);
    String bundle = getPackageName(cls.getName()) + BUNDLE_SUFFIX;
    return getInstance(bundle, classLoader);
  }

  /**
   * An instance bound to a bundle. This method uses the specified class loader to find the bundle.
   * Note, the specified class loader must not be <code>null</code>.
   *
   * @param bundleName the name of the bundle
   * @param loader the class loader from which to load the resource bundle
   * @return the helper instance bound to the bundle
   */
  public static I18NHelper getInstance(String bundleName, ClassLoader loader) {
    I18NHelper helper = helpers.get(bundleName);
    if (helper != null) {
      return helper;
    }
    helper = new I18NHelper(bundleName, loader);
    helpers.put(bundleName, helper);
    // if two threads simultaneously create the same helper, return the first
    // one to be put into the Hashtable.  The other will be garbage collected.
    return helpers.get(bundleName);
  }

  /**
   * Message formatter
   *
   * @param messageKey the message key
   * @return the resolved message text
   */
  public String msg(String messageKey) {
    assertBundle(messageKey);
    return getMessage(bundle, messageKey);
  }

  /**
   * Message formatter
   *
   * @param messageKey the message key
   * @param arg1 the first argument
   * @return the resolved message text
   */
  public String msg(String messageKey, Object arg1) {
    assertBundle(messageKey);
    return getMessage(bundle, messageKey, arg1);
  }

  /**
   * Message formatter
   *
   * @param messageKey the message key
   * @param arg1 the first argument
   * @param arg2 the second argument
   * @return the resolved message text
   */
  public String msg(String messageKey, Object arg1, Object arg2) {
    assertBundle(messageKey);
    return getMessage(bundle, messageKey, arg1, arg2);
  }

  /**
   * Message formatter
   *
   * @param messageKey the message key
   * @param arg1 the first argument
   * @param arg2 the second argument
   * @param arg3 the third argument
   * @return the resolved message text
   */
  public String msg(String messageKey, Object arg1, Object arg2, Object arg3) {
    assertBundle(messageKey);
    return getMessage(bundle, messageKey, arg1, arg2, arg3);
  }

  /**
   * Message formatter
   *
   * @param messageKey the message key
   * @param args the array of arguments
   * @return the resolved message text
   */
  public String msg(String messageKey, Object[] args) {
    assertBundle(messageKey);
    return getMessage(bundle, messageKey, args);
  }

  /**
   * Message formatter
   *
   * @param messageKey the message key
   * @param arg the argument
   * @return the resolved message text
   */
  public String msg(String messageKey, int arg) {
    assertBundle(messageKey);
    return getMessage(bundle, messageKey, arg);
  }

  /**
   * Message formatter
   *
   * @param messageKey the message key
   * @param arg the argument
   * @return the resolved message text
   */
  public String msg(String messageKey, boolean arg) {
    assertBundle(messageKey);
    return getMessage(bundle, messageKey, arg);
  }

  /**
   * Returns the resource bundle used by this I18NHelper.
   *
   * @return the associated resource bundle
   * @since 1.1
   */
  public ResourceBundle getResourceBundle() {
    assertBundle();
    return bundle;
  }

  // ========= Internal helper methods ==========

  /**
   * Load ResourceBundle by bundle name
   *
   * @param bundleName the name of the bundle
   * @param loader the class loader from which to load the resource bundle
   * @return the ResourceBundle
   */
  private static ResourceBundle loadBundle(String bundleName, ClassLoader loader) {
    ResourceBundle messages = bundles.get(bundleName);

    if (messages == null) // not found as loaded - add
    {
      if (loader != null) {
        messages = ResourceBundle.getBundle(bundleName, locale, loader);
      } else {
        // the JDO library is loaded by the boostrap class loader
        messages = ResourceBundle.getBundle(bundleName, locale, getSystemClassLoaderPrivileged());
      }
      bundles.put(bundleName, messages);
    }
    return messages;
  }

  /**
   * Assert resources available
   *
   * @since 1.1
   * @throws JDOFatalInternalException if the resource bundle could not be loaded during
   *     construction.
   */
  private void assertBundle() {
    if (failure != null)
      throw new JDOFatalInternalException(
          "No resources could be found for bundle:\"" + bundle + "\" ", failure);
  }

  /**
   * Assert resources available
   *
   * @param key the message key
   * @since 1.0.2
   * @throws JDOFatalInternalException if the resource bundle could not be loaded during
   *     construction.
   */
  private void assertBundle(String key) {
    if (failure != null)
      throw new JDOFatalInternalException(
          "No resources could be found to annotate error message key:\"" + key + "\"", failure);
  }

  /**
   * Returns message as <code>String</code>
   *
   * @param messages the resource bundle
   * @param messageKey the message key
   * @return the resolved message text
   */
  private static String getMessage(ResourceBundle messages, String messageKey) {
    return messages.getString(messageKey);
  }

  /**
   * Formats message by adding array of arguments
   *
   * @param messages the resource bundle
   * @param messageKey the message key
   * @param msgArgs an array of arguments to substitute into the message
   * @return the resolved message text
   */
  private static String getMessage(ResourceBundle messages, String messageKey, Object[] msgArgs) {
    for (int i = 0; i < msgArgs.length; i++) {
      if (msgArgs[i] == null) msgArgs[i] = ""; // NOI18N
    }
    MessageFormat formatter = new MessageFormat(messages.getString(messageKey));
    return formatter.format(msgArgs);
  }

  /**
   * Formats message by adding an <code>Object</code> argument.
   *
   * @param messages the resource bundle
   * @param messageKey the message key
   * @param arg the argument
   * @return the resolved message text
   */
  private static String getMessage(ResourceBundle messages, String messageKey, Object arg) {
    Object[] args = {arg};
    return getMessage(messages, messageKey, args);
  }

  /**
   * Formats message by adding two <code>Object</code> arguments.
   *
   * @param messages the resource bundle
   * @param messageKey the message key
   * @param arg1 the first argument
   * @param arg2 the second argument
   * @return the resolved message text
   */
  private static String getMessage(
      ResourceBundle messages, String messageKey, Object arg1, Object arg2) {
    Object[] args = {arg1, arg2};
    return getMessage(messages, messageKey, args);
  }

  /**
   * Formats message by adding three <code>Object</code> arguments.
   *
   * @param messages the resource bundle
   * @param messageKey the message key
   * @param arg1 the first argument
   * @param arg2 the second argument
   * @param arg3 the third argument
   * @return the resolved message text
   */
  private static String getMessage(
      ResourceBundle messages, String messageKey, Object arg1, Object arg2, Object arg3) {
    Object[] args = {arg1, arg2, arg3};
    return getMessage(messages, messageKey, args);
  }

  /**
   * Formats message by adding an <code>int</code> as an argument.
   *
   * @param messages the resource bundle
   * @param messageKey the message key
   * @param arg the argument
   * @return the resolved message text
   */
  private static String getMessage(ResourceBundle messages, String messageKey, int arg) {
    Object[] args = {Integer.valueOf(arg)};
    return getMessage(messages, messageKey, args);
  }

  /**
   * Formats message by adding a <code>boolean</code> as an argument.
   *
   * @param messages the resource bundle
   * @param messageKey the message key
   * @param arg the argument
   * @return the resolved message text
   */
  private static String getMessage(ResourceBundle messages, String messageKey, boolean arg) {
    Object[] args = {String.valueOf(arg)};
    return getMessage(messages, messageKey, args);
  }

  /**
   * Returns the package portion of the specified class.
   *
   * @param className the name of the class from which to extract the package
   * @return package portion of the specified class
   */
  private static String getPackageName(final String className) {
    final int index = className.lastIndexOf('.');
    return ((index != -1) ? className.substring(0, index) : ""); // NOI18N
  }

  /** Get the system class loader. This must be done in a doPrivileged block because of security. */
  private static ClassLoader getSystemClassLoaderPrivileged() {
    return doPrivileged(ClassLoader::getSystemClassLoader);
  }

  @SuppressWarnings("unchecked")
  private static <T> T doPrivileged(PrivilegedAction<T> privilegedAction) {
    try {
      return (T) LegacyJava.doPrivilegedAction.invoke(null, privilegedAction);
    } catch (IllegalAccessException | InvocationTargetException e) {
      if (e.getCause() instanceof RuntimeException) {
        throw (RuntimeException) e.getCause();
      }
      throw new JDOFatalInternalException(e.getMessage());
    }
  }
}
