package org.seasar.jsf.util;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

import org.seasar.framework.log.Logger;

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

public class MessageUtil {

	private static final String DETAIL_SUFFIX = "_detail";

	private static Logger logger_ = Logger.getLogger(MessageUtil.class);

	private MessageUtil() {
	}

	public static FacesMessage getErrorMessage(String messageId, Object args[]) {
		return getMessage(messageId, args, FacesMessage.SEVERITY_ERROR);
	}

	public static FacesMessage getMessage(String messageId, Object args[],
			FacesMessage.Severity severity) {

		return getMessage(messageId, args, FacesMessage.SEVERITY_ERROR,
				FacesContext.getCurrentInstance());
	}

	public static FacesMessage getMessage(String messageId, Object args[],
			FacesMessage.Severity severity, FacesContext context) {

		return getMessage(messageId, args, severity, context.getApplication()
				.getMessageBundle(), context.getViewRoot().getLocale());
	}

	public static FacesMessage getMessage(String messageId, Object args[],
			FacesMessage.Severity severity, String appBundleName, Locale locale) {

		ResourceBundle appBundle = null;
		ResourceBundle defBundle = null;
		String summary = null;
		String detail = null;

		appBundle = getBundle(appBundleName, locale);
		summary = getBundleString(appBundle, messageId);
		if (summary != null) {
			detail = getBundleString(appBundle, messageId + DETAIL_SUFFIX);
		} else {
			defBundle = getBundle(FacesMessage.FACES_MESSAGES, locale);
			summary = getBundleString(defBundle, messageId);
			if (summary != null) {
				detail = getBundleString(defBundle, messageId + DETAIL_SUFFIX);
			} else {
				detail = getBundleString(appBundle, messageId + DETAIL_SUFFIX);
				if (detail != null) {
					summary = null;
				} else {
					detail = getBundleString(defBundle, messageId
							+ DETAIL_SUFFIX);
					if (detail != null) {
						summary = null;
					} else {
						return null;
					}
				}
			}
		}
		MessageFormat format;
		if (summary != null) {
			format = new MessageFormat(summary, locale);
			summary = format.format(args);
		}
		if (detail != null) {
			format = new MessageFormat(detail, locale);
			detail = format.format(args);
		}
		return new FacesMessage(severity, summary, detail);
	}

	public static String getBundleString(ResourceBundle bundle, String key) {
		try {
			return bundle == null ? null : bundle.getString(key);
		} catch (MissingResourceException e) {
			return null;
		}
	}

	public static ResourceBundle getBundle(String bundleName, Locale locale) {
		if (bundleName == null) {
			return null;
		}
		try {
			return ResourceBundle.getBundle(bundleName, locale, Thread
					.currentThread().getContextClassLoader());
		} catch (MissingResourceException ex) {
			logger_.log(ex);
			return null;
		}
	}
}