package com.eactive.eai.common.bpa;


import java.util.List;

import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.message.CondPerRtgInfo;
import com.eactive.eai.common.message.EAIMessage;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.common.util.MessageUtil;
import com.eactive.eai.transformer.function.util.CodeConversion;
import com.eactive.eai.transformer.layout.Layout;
import com.eactive.eai.transformer.message.EbcdicMessage;
import com.eactive.eai.transformer.message.Message;
import com.eactive.eai.transformer.message.MessageFactory;
import com.eactive.eai.transformer.message.XMLMessage;
import com.eactive.eai.transformer.transform.Transform;
import com.eactive.eai.transformer.transform.TransformManager;

/** 
* 1. 기능 : 복합거래 FlowControl에서 
*           EAI 서비스메시지에 등록된 조건부 라우팅 룰에 대한 제어(TRUE/FALSE)를 처리하는 기능을 담당한다
* 2. 처리 개요 : 
*     - 응답메시지의 특정키갑을 정상값과 비교
*     - 정상인 경우 결과처리번호(다음처리순번), 오류인경우 -1을 리턴한다.
* 3. 주의사항 
*
* @author  : 
* @version : v 1.0.0
* @see :
* @since : 
*/
public final class RuleManager {
	private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);

	private RuleManager() {

	}

	/**
	 * 1. 기능 : 업무메시지에서 추적필드를 추출하는 함수 2. 처리 개요 : - BizKeyManager에서 Rule정보를 조회 - 조회된
	 * Rule을 기반으로 기능 처리 3. 주의사항
	 * 
	 * @param eaiSvcCd  EAI서비스코드
	 * @param messageID EAI 헤더에 정의된 메시지ID
	 * @param message   업무메시지 Object
	 * @return 결과 String 값(추적필드값)
	 * @exception Exception
	 */
	public static int getNextServieSeq(EAIMessage eaiMsg) throws Exception {
		try {
			String transformName = eaiMsg.getCurrentSvcMsg().getBsRspCnvMsgID();
			Object message = eaiMsg.getStandardMessage().getBizData();

			if (message == null) {
				logger.error("RoutingRuleManager] 응답메시지가 NULL입니다 - " + message);
				throw new Exception("RECEAICRR003");
			}

			logger.debug("RoutingRuleManager] 서비스메시지 [ " + eaiMsg.getCurrentSvcMsg().getSvcPssSeq() + " ] 에 대한 변환명은 [ "
					+ transformName + " ]입니다.");

			// ----------------------------------------------------
			// Message Object 생성
			// ----------------------------------------------------
			TransformManager manager = TransformManager.getManager();
			Transform info = manager.getTransform(transformName);
			if (info == null)
				throw new Exception("변환 정보를 찾을 수 없습니다.. - " + transformName);
			Layout l = info.getTargetLayout();
			String messageID = l.getName();
			if (messageID == null) {
				logger.error("RoutingRuleManager] Message ID is null.");
				throw new RuntimeException("RECEAICRR004");
			}

			Message msg = MessageFactory.getFactory().getMessage(messageID);
			logger.debug("RoutingRuleManager] layoutType [ " + l.getLayoutType().getName() + " ]");
			if (l.getLayoutType().getName().equals("XML")) {

				String xmlString = "";
				if (message instanceof byte[]) {
					xmlString = new String((byte[]) message);
				} else {
					xmlString = (String) message;
				}
				String rootItemName = ((XMLMessage) msg).getLayout().getRootItem().getName();

				xmlString = MessageUtil.removeXMLHeader(xmlString);
				xmlString = "<" + rootItemName + ">" + xmlString + "</" + rootItemName + ">";
				msg.setData(xmlString);
			} else if (l.getLayoutType().getName().equals("BYTES") || l.getLayoutType().getName().equals("EBCDIC")) {
				msg.setData(message);
			} else {
				msg.setData(message);
			}

			// Routing Rule 조회
			List<CondPerRtgInfo> condPerRtgInfoList = eaiMsg.getCurrentSvcMsg().getCondPerRtgInfo();

			String prcssNo = "-1";
			if (condPerRtgInfoList != null) {
				int ruleSize = condPerRtgInfoList.size();

				for (int i = 0; i < ruleSize; i++) {
					CondPerRtgInfo rtnInfo =  condPerRtgInfoList.get(i);

					prcssNo = rtnInfo.getRsultPrcssNo();

					String defVal = rtnInfo.getRuleCprTxt(); // 비교내용
					String colName = rtnInfo.getRuleColNm(); // 규칙필드명
					String keyVal = "";
					if (msg instanceof EbcdicMessage) {
						keyVal = new String(CodeConversion.seToAsc(msg.getByteArray(colName)));
					} else {
						keyVal = msg.getString(colName);
					}

					if (!defVal.equals(keyVal)) {
						logger.info("RoutingRuleManager] FALSE RETURN[" + keyVal + " : " + defVal + " ]");
						return (-1);
					}
				}
			}
			// 정상 Routing Rule 리턴
			int iprcssNo = -1;

			try {
				iprcssNo = Integer.parseInt(prcssNo);
			} catch (Exception nfe) {
				logger.error("RoutingRuleManager] Invalid RsultPrcssNo [" + prcssNo + "]" + nfe.getMessage());
				throw new Exception("RECEAICRR002");
			}
			return iprcssNo;
		} catch (Exception e) {
			throw new Exception(ExceptionUtil.getErrorCode(e, "RECEAICRR001"));
		}
	}
}