package org.seasar.framework.log;

import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Category;
import org.apache.log4j.Priority;
import org.seasar.framework.message.MessageFormatter;

public final class Logger {

	private static Map loggerMap_ = new HashMap();

	private Category category_;

	private Logger(Class clazz) {
		category_ = Category.getInstance(clazz);
	}

	public static final Logger getLogger(Class clazz) {
		Logger logger = (Logger) loggerMap_.get(clazz);
		if (logger == null) {
			synchronized (loggerMap_) {
				logger = (Logger) loggerMap_.get(clazz);
				if (logger == null) {
					logger = new Logger(clazz);
					loggerMap_.put(clazz, logger);
				}
			}
		}
		return logger;
	}

	public final boolean isDebugEnabled() {
		return category_.isDebugEnabled();
	}

	public final void debug(Object message, Throwable throwable) {
		if (isDebugEnabled()) {
			category_.debug(message, throwable);
		}
	}

	public final void debug(Object message) {
		if (isDebugEnabled()) {
			category_.debug(message);
		}
	}

	public final boolean isInfoEnabled() {
		return category_.isInfoEnabled();
	}

	public final void info(Object message, Throwable throwable) {
		if (isInfoEnabled()) {
			category_.info(message, throwable);
		}
	}

	public final void info(Object message) {
		if (isInfoEnabled()) {
			category_.info(message);
		}
	}

	public final void warn(Object message, Throwable throwable) {
		category_.warn(message, throwable);
	}

	public final void warn(Object message) {
		category_.warn(message);
	}

	public final void error(Object message, Throwable throwable) {
		category_.error(message, throwable);
	}

	public final void error(Object message) {
		category_.error(message);
	}

	public final void fatal(Object message, Throwable throwable) {
		category_.fatal(message, throwable);
	}

	public final void fatal(Object message) {
		category_.fatal(message);
	}

	public final void log(Priority priority, Object message) {
		category_.log(priority, message);
	}

	public final void log(
		Priority priority,
		Object message,
		Throwable throwable) {
		category_.log(priority, message, throwable);
	}

	public final void log(Throwable throwable) {
		error(throwable.getMessage(), throwable);
	}

	public final void log(String messageCode, Object[] args) {
		log(messageCode, args, null);
	}

	public final void log(
		String messageCode,
		Object[] args,
		Throwable throwable) {

		Priority priority = getPriority(messageCode.charAt(0));
		if (category_.isEnabledFor(priority)) {
			String message = MessageFormatter.getSimpleMessage(messageCode, args);
			log(priority, message, throwable);
		}
	}

	private static Priority getPriority(final char messageType) {
		switch (messageType) {
			case 'D' :
				return Priority.DEBUG;
			case 'I' :
				return Priority.INFO;
			case 'W' :
				return Priority.WARN;
			case 'E' :
				return Priority.ERROR;
			case 'F' :
				return Priority.FATAL;
			default :
				throw new IllegalArgumentException(String.valueOf(messageType));
		}
	}
}