package cn.hmsoft.log;

import java.io.File;
import java.io.FileInputStream;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.config.Configurator;
import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;

import cn.hmsoft.application.AppHelper;
import cn.hmsoft.application.SpringHelper;
import cn.hmsoft.helper.StringHelper;

/********************
 * 日志辅助类
 * 
 * @author zxq
 * @create 2019-05-06 08:17:12
 * @version 2.0.0
 * @email: revisit@126.com
 * @Company: www.hmsoft.cn
 */
public class LogHelper {

	private static Logger logger = null;

	public static LogType LOGTYPE = LogType.Default;

	public enum LogLevel {
		Trace, Debug, Info, Error, Warn
	}

	public static void info(Object message) {
		log(message, LogLevel.Info);
	}

	public static void warn(Object message) {
		log(message, LogLevel.Warn);
	}

	public static void trace(Object message) {
		log(message, LogLevel.Trace);
	}

	public static void debug(Object message) {
		log(message, LogLevel.Debug);
	}

	public static void log(Object message) {
		log(message, LogLevel.Info);
	}

	public static void error(String message) {
		log(message, LogLevel.Error);
	}

	public static void error(String message, Throwable e) {
		log(message, LogLevel.Error);
		logger.error(e);
	}

	public static void error(Throwable e) {
		logger.error(e.getMessage(), e);
	}

	public static void log(Object message, LogLevel logLevel) {
		if (logLevel == LogLevel.Trace)
			logger.trace(message);
		else if (logLevel == LogLevel.Debug)
			logger.debug(message);
		else if (logLevel == LogLevel.Info)
			logger.info(message);
		else if (logLevel == LogLevel.Error)
			logger.error(message);
		else if (logLevel == LogLevel.Warn)
			logger.warn(message);
	}

	static {
		loadConfig();
		logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
		// logger = LogManager.getLogger(LogHelper.class.getName());

	}

	/**********************************
	 * 自动加载log4j的配置文件
	 */
	private final static void loadConfig() {
		if (StringHelper.isEmpty(AppHelper.LogFilePath)) {
			if (SpringHelper.WebServletContext == null) {
				AppHelper.LogFilePath = SpringHelper.getRootPath() + "logs" + File.separator;
			} else {
				// Web容器，上一级
				AppHelper.LogFilePath = new File(SpringHelper.getRootPath()).getParentFile().getParent() + File.separator + "logs"
						+ File.separator;
			}
		}
		File file = null;
		if (SpringHelper.WebServletContext == null)
			file = new File(SpringHelper.getRootPath() + "log4j2.xml");
		else
			file = new File(SpringHelper.getRootPath() +"WEB-INF" + File.separator + "classes" + File.separator + "log4j2.xml");
		// 先判断是否存在log4j文件
		try {
			// 存在log4j,系统自动加载，不主动加载
			if (file.exists()) {
				LOGTYPE = LogType.Custom;
				ConfigurationSource source = null;
				try {
					source = new ConfigurationSource(new FileInputStream(file));
					Configurator.initialize(null, source);
				} catch (Exception e) {

				}
				if (source != null)
					return;
			}
			// 初始化Log容器
			ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();

			builder.setStatusLevel(Level.INFO);
			builder.setConfigurationName("HmsoftLog");

			// 添加标准输出
			AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", "CONSOLE").addAttribute("target",
					ConsoleAppender.Target.SYSTEM_OUT);
			appenderBuilder.add(builder.newLayout("PatternLayout").addAttribute("pattern", "%d %-5p %m%n"));
			// appenderBuilder.add(builder.newFilter("RegexFilter", Result.DENY,
			// Result.ACCEPT).addAttribute("regex", "*Log4j*"));
			builder.add(appenderBuilder);

			// 所有Info的消息输出定义,每天一个文件
			appenderBuilder = builder.newAppender("infoLog", "RollingFile")
					.addAttribute("fileName", AppHelper.LogFilePath + "log.log")
					.addAttribute("filePattern", AppHelper.LogFilePath + "log_%d{yyyy-MM-dd}_%i.log");
			// appenderBuilder = builder.newAppender("infoLog",
			// "File").addAttribute("fileName",
			// ".../logs/log.log").addAttribute("append", "true");
			appenderBuilder.add(builder.newLayout("PatternLayout").addAttribute("pattern", "%d %-5p %m%n"));
			appenderBuilder.addComponent(builder.newComponent("TimeBasedTriggeringPolicy")
					.addAttribute("interval", "24").addAttribute("modulate", "true"));
			builder.add(appenderBuilder);
			// ClassLoaderContextSelector
			// 所有Error消息输出的路径,每天一个文件
			appenderBuilder = builder.newAppender("errorLog", "RollingFile")
					.addAttribute("fileName", AppHelper.LogFilePath + "error.log")
					.addAttribute("filePattern", AppHelper.LogFilePath + "error_%d{yyyy-MM-dd}_%i.log");
			appenderBuilder.add(builder.newLayout("PatternLayout").addAttribute("pattern", "%d %-5p %m%n"));
			appenderBuilder.addComponent(builder.newComponent("TimeBasedTriggeringPolicy")
					.addAttribute("interval", "24").addAttribute("modulate", "true"));
			builder.add(appenderBuilder);

			builder.add(builder.newRootLogger(Level.DEBUG)
					.add(builder.newAppenderRef("Stdout").addAttribute("level", "debug"))
					.add(builder.newAppenderRef("infoLog").addAttribute("level", "info"))
					.add(builder.newAppenderRef("errorLog").addAttribute("level", "error")));

			builder.add(builder.newLogger("org.springframework", Level.ERROR));
			builder.add(builder.newLogger("org.apache.logging.log4j", Level.ERROR));
			builder.add(builder.newLogger("org.quartz", Level.ERROR));
			builder.add(builder.newLogger("com.alibaba.druid", Level.ERROR));

			// Interpolator
			Configurator.initialize(builder.build());

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
