package com.eactive.eai.common.exception;

import com.eactive.eai.batch.code.CodeMessageHandler;
import com.eactive.eai.batch.code.CodeMessageManager;
import com.eactive.eai.batch.code.CodeMessageVO;
import com.eactive.eai.batch.common.StringUtil;
import com.eactive.eai.batch.doc.BatchDoc;
import com.eactive.eai.common.util.Logger;

/**
* 1. 기능 : Exception 발생 시 메시지를 처리하기 위한 Utility 클래스
* 2. 처리 개요 : Exception 발생 시 메시지를 처리하는 메서드를 정의한다.
* *     -
* 3. 주의사항
*
* @author  :
* @version : v 1.0.0
* @see : 관련 기능을 참조
* @since   :
*/
public abstract class ExceptionUtil
{
    //Exception 파일 로거
    private static Logger exLogger = Logger.getLogger(Logger.LOGGER_EXCEPTION);

    //SMS전송 파일 로거
    private static Logger smsLogger = Logger.getLogger(Logger.LOGGER_SMS);


	private static void writeExceptionLog(String code, String msg, Throwable cause) {
		if (cause == null) {
			if      (code.startsWith("BW")) exLogger.warn (msg);
			else if (code.startsWith("BE")) exLogger.error(msg);
			else if (code.startsWith("BF")) exLogger.error(msg);
		} else {
			if      (code.startsWith("BD")) exLogger.debug(msg, cause);
			else if (code.startsWith("BI")) exLogger.info (msg, cause);
			else if (code.startsWith("BW")) exLogger.warn (msg, cause);
			else if (code.startsWith("BE")) exLogger.error(msg, cause);
			else if (code.startsWith("BF")) exLogger.error(msg, cause);
			else                            exLogger.debug(msg, cause);
		}
	}


	public static String getErrorCode(String code) {
		return getErrorCode(null, null, code, null);
	}

	public static String getErrorCode(String code, String[] args) {
		return getErrorCode(null, null, code, args);
	}

	public static String getErrorCode(Throwable cause, String code) {
		return getErrorCode(cause, null, code, null);
	}

    public static String getErrorCode(Throwable cause, String code, String[] args) {
		return getErrorCode(cause, null, code, args);
    }
    
    
    

	public static String getErrorCode(BatchDoc batchMsgDoc, String code) {
		return getErrorCode(null, batchMsgDoc, code, null);
	}

	public static String getErrorCode(Throwable cause, BatchDoc batchMsgDoc, String code) {
		return getErrorCode(cause, batchMsgDoc, code, null);
	}

	public static String getErrorCode(BatchDoc batchMsgDoc, String code, String[] args) {
		return getErrorCode(null, batchMsgDoc, code, args);
	}

    public static String getErrorCode(Throwable cause, BatchDoc batchMsgDoc, String code, String[] args) {

		code = StringUtil.nvlTrim(code);
        
		String returnMsg = make(batchMsgDoc, code, args);
		String errMsg = (cause == null)? "" : StringUtil.nvlTrim(cause.getMessage());
        
		//사용자 Exception : 메시지에 '에러코드'가 설정된 경우
		if (isErrorCode(errMsg)) {
			returnMsg += "\n caused by..."+ make(errMsg);

		//사용자 Exception : 메시지에 '[에러코드] 에러메시지' 형태가 설정된 경우
		} else if (isErrorCodeMsg(errMsg)) {
			returnMsg += "\n caused by..."+ errMsg;

		//Java Exception
		} else if (cause != null)  {
			returnMsg += "\n caused by..."+ cause.toString();
		}

		//batchMsgDoc 이 null 이 아닌 경우 배치메시지의 에러메시지를 Append
        if (batchMsgDoc != null) {
			String prevMsg = batchMsgDoc.getBatchMsg().getBody().getErrorMsg();
			if (prevMsg != null && !prevMsg.equals("")) {
				returnMsg += "\n caused by..."+ prevMsg;
			}
		}

		//Exception 파일로그를 따로 남김
		writeExceptionLog(code, returnMsg, cause);
		return returnMsg;
	}






	public static String make(String errorCode) {
		return make(errorCode, new String[] {});
	}

    public static String make(String errorCode, String[] args) {
		return make(null, errorCode, args);
    }

    public static String make(BatchDoc batchMsgDoc, String errorCode, String[] args) {
		if (args == null || args.length == 0) {
			return make(batchMsgDoc, errorCode, CodeMessageHandler.getMessage(errorCode));
		} else {
			return make(batchMsgDoc, errorCode, CodeMessageHandler.getMessage(errorCode, args));
		}
    }

    public static String make(String errorCode, String errorText) {
    	return make(null, errorCode, errorText);
    }

    // 2008.12.30 정동한
    //기존의  make(String errorCode, String errorText) 메소드에 추가 로깅을 위해  BatchDoc 을 추가
    public static String make(BatchDoc batchMsgDoc, String errorCode, String errorText) {

		//===============================================================================
		//코드정보의 SMS전송여부가 설정되어있으면 SMS 파일로그를 남김
        CodeMessageVO codeInfo = null;

        codeInfo = CodeMessageManager.getInstance().getMessageVO(errorCode);

		if (codeInfo == null) {
			exLogger.warn("****** 해당 메시지코드["+ errorCode +"] 가 코드테이블에 정의되지 않았습니다. ******");

		} else {
			//해당 코드의 SMS전송여부가 설정되었으면 SMS 로그 남김  -- SMS 로그포맷에 준하여 남겨야함
			//(SMS 시스템이 해당 로그파일을 Polling 하여 SMS가 발송됨)
			if (codeInfo.getSmsSendType() != null && codeInfo.getSmsSendType().equals("1")) {
				String msg = "[" + codeInfo.getMsgTxt() + "]"; 
				if ( batchMsgDoc != null ){
					smsLogger.debug(  batchMsgDoc.toString() );
					//[수신실패] 파일명:xxxxxxxxxxxxxxxx 기관명:yyyyyyyyyyyyyyy 업무명:zzzzzzzzzzz	
					if (batchMsgDoc.getBatchMsg().getHeader().getBizCode() != null )
						msg = msg + "파일명:" + batchMsgDoc.getBatchMsg().getHeader().getBizCode() + ",";
					if (batchMsgDoc.getBatchMsg().getHeader().getProcessName() != null )
						msg = msg + "업무명:" + batchMsgDoc.getBatchMsg().getHeader().getProcessName() + ",";
					if (batchMsgDoc.getBatchMsg().getHeader().getInstitutionName() != null )
						msg = msg + "기관명:" + batchMsgDoc.getBatchMsg().getHeader().getInstitutionName();
				}
		    	// 업무팀이 세팅 되어 있으면 EAI에도 한번 더 보낸다.
//				UCMsgSenderUtil.sendUCMsg( msg );
				exLogger.info("****** 해당 메시지코드["+ errorCode +"] 를 SMS 전송 파일로그에 기록하였습니다. ******");
			}
		}
		//===============================================================================

        return "["+ errorCode +"] "+ errorText;
    }


	private static boolean isErrorCode(String str) {
		if (str == null || str.equals("")) return false;
		str = str.trim();
		if (str.length() != 12) return false;
		if (StringUtil.isAlpha(str.substring(0, 9)) &&
		    StringUtil.isNumeric(str.substring(9))) return true;
		return false;
	}

	private static boolean isErrorCodeMsg(String str) {
		if (str == null || str.equals("")) return false;
		str = str.trim();
		if (str.length() < 14) return false;
		if (str.substring(0, 1).equals("[") &&
		    StringUtil.isAlpha(str.substring(1, 10)) &&
		    StringUtil.isNumeric(str.substring(10, 13)) &&
			str.substring(13, 14).equals("]")) return true;
		return false;
	}

}
