/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights reserved. <a>http://www.crunii.com</a>
 */
package com.crunii.micro.common.exception;

import com.crunii.micro.common.dto.Result;
import com.crunii.micro.common.utils.Slf4jUtil;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

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

/**
 * @author 田平 create 2014-12-8下午4:41:03
 */
@ToString
@Slf4j
public class MicroException extends RuntimeException {

	private static final long serialVersionUID = 1L;

	public static final Map<String, String> messages = new HashMap<String, String>();

	public static final String LOCK_FAILURE = "1000";

	static {
		messages.put(LOCK_FAILURE, "lockId={} lock failure by reason:{}!");
	}

	private String code = Result.DEFAULT_ERROR_CODE;
	private String message;

	public MicroException() {
	}

	/**
	 * <pre>
	 * 注意不要使用code和message来调用这个方法
	 * 需要直接设置这两个属性使用
	 * MicroException me = new MicroException();
	 * me.setCode(result.getCode());
	 * me.setMessage(result.getMsg());
	 * throw me;
	 * </pre>
	 *
	 * @param code
	 * @param args
	 */
	public MicroException(String code, Object... args) {
		this(code, null, args);
	}

	public MicroException(String code, Throwable cause, Object... args) {
		super(cause);
		this.code = code;
		this.message = getMessageDetail(code, cause, args);
	}

	private static String getMessageDetail(String code, Throwable cause, Object... args) {

		String pattern = messages.get(code);

		if (!StringUtils.hasLength(pattern)) {
			throw new RuntimeException("错误编码code:" + code + " 未定义！");
		}

		if (args != null && args.length > 0) {
			Object[] params = new Object[args.length + 1];
			System.arraycopy(args, 0, params, 0, args.length);
			params[args.length] = cause;
			return Slf4jUtil.formatException(pattern, params);
		} else {
			return Slf4jUtil.formatException(pattern, cause);
		}
	}

	public MicroException(ErrorCode errorCode) {
		this.code = Integer.toString(errorCode.getCode());
		this.message = errorCode.getMsg();
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public static String getErrorMsg(Throwable e) {
		return Slf4jUtil.getErrorMsg(e);
	}

	public static String getMaxDesc(Object desc) {
		return Slf4jUtil.getMaxDesc(desc);
	}

	public static void main(String[] args) {
		MicroException m = new MicroException("1015", null, "OSHIT", "1231");
		log.error("测试错误!", m);
	}
}
