package nl.quintor.commons.util;

import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import javax.faces.context.FacesContext;

import org.apache.log4j.Logger;

/**
 * Utility class with methods specific to JSF applications.
 */
public final class JSFUtils {
	private static final Logger logger = Logger.getLogger(JSFUtils.class);

	/**
	 * Private constructor; This class is not meant to be instantiated. This is a utility class with static methods
	 * only.
	 */
	private JSFUtils() {
		//
	}

	/**
	 * Tries to fetch a message from the application's resource bundle. If having some problem getting either the
	 * message or the entire bundle, the specified backup message is being used. This is so that a default message can
	 * be used, unless some application provides its own through the resource bundle.
	 * 
	 * @param msgId The id of the message that needs to be returned from the resource bundle (ie.
	 *            'validation.isnull.emailadres').
	 * @param parameters A list with value to insert into the message on predefine placeholders, using
	 *            {@link String#format(String, Object...)}.
	 * @param backupMessage A backup or default message to be used when the resourcebundle is not giving home.
	 * @return The message from the resourcebundle, based on <code>msgId</code>, or the backup message otherwise.
	 * @see #getResourceBundle()
	 * @see String#format(String, Object...)
	 */
	public static String getMessageFromFacesBundle(final String msgId, final Object[] parameters, final String backupMessage) {
		try {
			final ResourceBundle bundle = getResourceBundle();
			String msg = backupMessage;
			try {
				msg = bundle.getString(msgId);
			} catch (MissingResourceException e) {
				logger.error(String.format("Message id '%s' is unknown in resourcebundle, using backup message instead", msgId), e);
			}
			return String.format(msg, parameters);
		} catch (final RuntimeException e) {
			logger.error(String.format("Unable to query Resourcebundle for msg id '%s', using backup message instead", msgId), e);
			return String.format(backupMessage, parameters);
		}
	}

	/**
	 * @return The application's default resource bundle through the use of FacesContext.
	 * @see ResourceBundle#getBundle(String, Locale, ClassLoader)
	 */
	private static ResourceBundle getResourceBundle() {
		final FacesContext context = FacesContext.getCurrentInstance();
		final String msgBundle = context.getApplication().getMessageBundle();
		final Locale locale = context.getViewRoot().getLocale();
		final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		return ResourceBundle.getBundle(msgBundle, locale, classLoader);
	}
}
