/**
 * 
 */
package com.pcloud.common.utils.log;

import java.net.InetAddress;
import java.net.UnknownHostException;

import org.slf4j.*;

import com.alibaba.fastjson.JSON;

/**
 * @描述：日志操作封装
 * @作者：songx
 * @创建时间：2016年9月21日,上午10:56:19
 * @版本：1.0
 */
public class Log {

	/**
	 * logger
	 */
	private static final Logger LOGGER = LoggerFactory.getLogger(Log.class);
	
	/**
	 * IP
	 */
	private static String ip = "0.0.0.0";
	
	/**
	 * 初始化获取本机IP
	 */
	static{
		try {
			InetAddress addr = InetAddress.getLocalHost();
			ip = addr.getHostAddress();
		} catch (UnknownHostException e) {
			LOGGER.error("获取本机IP失败~!");
		}		
	}
	
	/**
	 * @return 获得日志，自动判定日志发出者
	 */
	public static Logger get() {
		StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
		return LoggerFactory.getLogger(stackTrace[2].getClassName());
	}
	
	/**
	 * 获取logbean字符串
	 * @param msg
	 * @return
	 */
	private static String getLogBeanJson(String msg) {
		LogBean logBean = new LogBean();
		logBean.setMsg(msg);
		logBean.setIp(ip);
		return JSON.toJSONString(logBean);
	}
	
	/**
	 *
	 * Trace等级日志，小于debug<br>
	 *
	 * 由于动态获取Logger，效率较低，建议在非频繁调用的情况下使用！！
	 * @param format
	 *            格式文本，{} 代表变量
	 * @param arguments
	 *            变量对应的参数
	 */
	public static void trace(String format, Object... arguments) {
		trace(innerGet(), format, arguments);
	}
	
	/**
	 * Trace等级日志，小于Debug
	 * 
	 * @param log
	 *            日志对象
	 * @param format
	 *            格式文本，{} 代表变量
	 * @param arguments
	 *            变量对应的参数
	 */
	public static void trace(Logger logger, String format, Object... arguments) {
		logger.trace(getLogBeanJson(format(format, arguments)));
	}
    
	/**
	 * Debug等级日志，小于Info<br>
	 * 由于动态获取Logger，效率较低，建议在非频繁调用的情况下使用！！
	 * 
	 * @param format
	 *            格式文本，{} 代表变量
	 * @param arguments
	 *            变量对应的参数
	 */
	public static void debug(String format, Object... arguments) {
		debug(innerGet(), format, arguments);
	}
   
	/**
	 * Debug等级日志，小于Info
	 * 
	 * @param log
	 *            日志对象
	 * @param format
	 *            格式文本，{} 代表变量
	 * @param arguments
	 *            变量对应的参数
	 */
	public static void debug(Logger logger, String format, Object... arguments) {
		logger.debug(getLogBeanJson(format(format, arguments)));
	}

	/**
	 * Info等级日志，小于Warn<br>
	 * 由于动态获取Logger，效率较低，建议在非频繁调用的情况下使用！！
	 * 
	 * @param format
	 *            格式文本，{} 代表变量
	 * @param arguments
	 *            变量对应的参数
	 */
	public static void info(String format, Object... arguments) {
		info(innerGet(), format, arguments);
	}

	/**
	 * Info等级日志，小于Warn
	 * 
	 * @param log
	 *            日志对象
	 * @param format
	 *            格式文本，{} 代表变量
	 * @param arguments
	 *            变量对应的参数
	 */
	public static void info(Logger logger, String format, Object... arguments) {
		logger.info(format, arguments);
	}

	/**
	 * Warn等级日志，小于Error<br>
	 * 由于动态获取Logger，效率较低，建议在非频繁调用的情况下使用！！
	 * 
	 * @param format
	 *            格式文本，{} 代表变量
	 * @param arguments
	 *            变量对应的参数
	 */
	public static void warn(String format, Object... arguments) {
		warn(innerGet(), format, arguments);
	}

	/**
	 * Warn等级日志，小于Error
	 * 
	 * @param log
	 *            日志对象
	 * @param format
	 *            格式文本，{} 代表变量
	 * @param arguments
	 *            变量对应的参数
	 */
	public static void warn(Logger logger, String format, Object... arguments) {
		logger.warn(getLogBeanJson(format(format, arguments)));
	}

	/**
	 * Warn等级日志，小于Error<br>
	 * 由于动态获取Logger，效率较低，建议在非频繁调用的情况下使用！！
	 * 
	 * @param e
	 *            需在日志中堆栈打印的异常
	 * @param format
	 *            格式文本，{} 代表变量
	 * @param arguments
	 *            变量对应的参数
	 */
	public static void warn(Throwable e, String format, Object... arguments) {
		warn(innerGet(), e, format(format, arguments));
	}

	/**
	 * Warn等级日志，小于Error
	 * 
	 * @param log
	 *            日志对象
	 * @param e
	 *            需在日志中堆栈打印的异常
	 * @param format
	 *            格式文本，{} 代表变量
	 * @param arguments
	 *            变量对应的参数
	 */
	public static void warn(Logger logger, Throwable e, String format, Object... arguments) {
		logger.warn(format(format, arguments), e);
	}   

	/**
	 * Error等级日志<br>
	 * 由于动态获取Logger，效率较低，建议在非频繁调用的情况下使用！！
	 * 
	 * @param format
	 *            格式文本，{} 代表变量
	 * @param arguments
	 *            变量对应的参数
	 */
	public static void error(String format, Object... arguments) {
		error(innerGet(), format, arguments);
	}

	/**
	 * Error等级日志<br>
	 * 
	 * @param log
	 *            日志对象
	 * @param format
	 *            格式文本，{} 代表变量
	 * @param arguments
	 *            变量对应的参数
	 */
	public static void error(Logger logger, String format, Object... arguments) {
		logger.error(getLogBeanJson(format(format, arguments)));
	}     

	/**
	 * Error等级日志<br>
	 * 由于动态获取Logger，效率较低，建议在非频繁调用的情况下使用！！
	 * 
	 * @param e
	 *            需在日志中堆栈打印的异常
	 * @param format
	 *            格式文本，{} 代表变量
	 * @param arguments
	 *            变量对应的参数
	 */
	public static void error(Throwable e, String format, Object... arguments) {
		error(innerGet(), e, format(format, arguments));
	}

	/**
	 * Error等级日志<br>
	 * 由于动态获取Logger，效率较低，建议在非频繁调用的情况下使用！！
	 * 
	 * @param log
	 *            日志对象
	 * @param e
	 *            需在日志中堆栈打印的异常
	 * @param format
	 *            格式文本，{} 代表变量
	 * @param arguments
	 *            变量对应的参数
	 */
	public static void error(Logger logger, Throwable e, String format, Object... arguments) {
		logger.error(format(format, arguments), e);
	}

	/**
	 * 格式化文本
	 * 
	 * @param template
	 *            文本模板，被替换的部分用 {} 表示
	 * @param values
	 *            参数值
	 * @return 格式化后的文本
	 * 
	 */
	private static String format(String template, Object... values) {
		return String.format(template.replace("{}", "%s"), values);
	}       

	/**
	 * @return 获得日志，自动判定日志发出者
	 */
	private static Logger innerGet() {
		StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
		return LoggerFactory.getLogger(stackTrace[3].getClassName());
	}
}
