package com.eactive.eai.flowcontroller;

import java.nio.charset.Charset;
import java.util.Properties;

import org.apache.commons.lang3.StringUtils;

import com.eactive.eai.adapter.AdapterGroupVO;
import com.eactive.eai.adapter.AdapterManager;
import com.eactive.eai.adapter.Keys;
import com.eactive.eai.common.EAIKeys;
import com.eactive.eai.common.EAITable;
import com.eactive.eai.common.exception.ExceptionHandler;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.message.EAIMessage;
import com.eactive.eai.common.message.EAIMessageKeys;
import com.eactive.eai.common.message.MessageType;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.routing.IFRouter;
import com.eactive.eai.common.routing.Process;
import com.eactive.eai.common.routing.RouteKeys;
import com.eactive.eai.common.server.EAIServerManager;
import com.eactive.eai.common.util.B2BExtractor;
import com.eactive.eai.common.util.B2BServiceMapper;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.common.util.MessageUtil;
import com.eactive.eai.common.util.ObjectUtil;
import com.eactive.eai.common.util.ServiceUtil;
import com.eactive.eai.control.LogSender;
import com.eactive.eai.message.StandardMessage;
import com.eactive.eai.message.service.InterfaceMapper;
import com.eactive.eai.transformer.function.util.CodeConversion;
import com.ext.eai.common.stdmessage.STDMessageKeys;

public class B2BFCProcess extends Process {
	private String adptrMsgPtrnCd;

	private int logPssSeq;

	private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);

	private java.util.Properties callProp;

	private EAIMessage resEaiMsg;

	private com.eactive.eai.common.message.EAIMessage reqEaiMsg;

	static Logger esbLogger = Logger.getLogger(Logger.LOGGER_ESBFW);
	private int svrLogLevel;
	private static ThreadLocal local = new ThreadLocal();

	static final long serialVersionUID = 1L;

	private String guidLogPrefix = "";

	public EAIMessage clientReturn() {
		if (svrLogLevel >= 1) {
			try {
				long msgSndTm = System.currentTimeMillis();

				Long threadData = (Long) local.get();
				long processTm = msgSndTm - threadData.longValue();
				if (esbLogger.isInfo())
					esbLogger.info(
							guidLogPrefix + " End... - 경과시간 : " + processTm + "(ms) - EAI Server Log Level is INFO");
			} catch (Exception e) {
				logger.warn("clientReturn", e);
			}
		}
		return resEaiMsg;
	}

	public void callService(com.eactive.eai.common.message.EAIMessage reqEaiMsg, java.util.Properties callProp) {
		this.reqEaiMsg = reqEaiMsg;
		this.callProp = callProp;

		if (this.reqEaiMsg == null)
			return;

		svrLogLevel = this.reqEaiMsg.getSvrLogLvl();
		guidLogPrefix = "B2BFCProcess] GUID[" + getGuid(reqEaiMsg) + "] UUID[" + this.reqEaiMsg.getSvcOgNo() + "] ";

		if (svrLogLevel >= 1) {
			try {
				long msgRcvTm = System.currentTimeMillis();
				local.set(new Long(msgRcvTm));
				if (esbLogger.isInfo()) {
					esbLogger.info(guidLogPrefix + " started... - EAI Server Log Level is INFO");
				}
			} catch (Exception e) {
				logger.warn("callService", e);
			}
		}

		try {
			flow();
		} catch (Exception e) {
			printExceptionMessage(e);
			if (isSourceAsync()) {
				logSenderCtrlSend();
				callExceptionHandler();
			}
		}
	}

	public void flow() throws Exception {
		if (!isRealCall()) {
			return;
		}
		init();
		// B2BOutboud Mapping
		setRoute();
		setAdptrInstiCode();
		ifRouterProcess();
		setGUID();

		// ASYNC-SYNC
		if (checkServiceMsgSize()) {
			setCurrentService();
			ifRouterProcessResponse();
		}
	}

	public void ifRouterProcess() throws Exception {
		try {
			EAIMessage reqMsg = (EAIMessage) ObjectUtil.deepCopy(this.reqEaiMsg);
			this.resEaiMsg = IFRouter.process(reqMsg, this.callProp);
		} catch (Exception e) {
			String[] msgArgs = new String[1];
			msgArgs[0] = this.reqEaiMsg.getEAISvcCd();
			String rspErrorCode = "RECEAIFBR001";
			String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs);
			logger.error(guidLogPrefix + rspErrorMsg);
//			this.resEaiMsg.setRspErrCd(rspErrorCode);
//			this.resEaiMsg.setRspErrMsg(rspErrorMsg);
			this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg);
			throw new Exception(rspErrorCode);
		}

		// ----------------------------------------------------
		// 기동시스템이 Async 거래의 OUtbound에서 오류가 발생할 경우
		// ExceptionHandler를 통해 응답메시지를 전송한다.
		// ---------------------------------------------------
		if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) {
			if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) {
				try {
					String bizData = this.reqEaiMsg.getStandardMessage().getBizData();
					String inboundCharset = callProp.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN);
					this.resEaiMsg.getStandardMessage().setBizData(bizData, inboundCharset);					
					ExceptionHandler.handle(this.resEaiMsg);
				} catch (Exception e) {
					if (logger.isError())
						logger.error(guidLogPrefix + " ExceptionHandler Call Error :" + e.getMessage());
				}
			}
		}
	}

	public void ifRouterProcessResponse() throws Exception {
		try {
			String returnServiceId = this.resEaiMsg.getMapper().getReturnServiceId(this.resEaiMsg.getStandardMessage());
			this.resEaiMsg.getMapper().setServiceId(this.resEaiMsg.getStandardMessage(), returnServiceId);
			this.resEaiMsg = IFRouter.process(this.resEaiMsg, this.callProp);
		} catch (Exception e) {
			String[] msgArgs = new String[1];
			msgArgs[0] = this.reqEaiMsg.getEAISvcCd();
			String rspErrorCode = "RECEAIFBR100";
			String orgErrorCode = ExceptionUtil.getErrorCode(e, rspErrorCode);
			String rspErrorMsg = ExceptionUtil.make(rspErrorCode, orgErrorCode, msgArgs);
			
			logger.error(guidLogPrefix + " " + rspErrorMsg);
//			this.resEaiMsg.setRspErrCd(rspErrorCode);
//			this.resEaiMsg.setRspErrMsg(rspErrorMsg);
			this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg);
			this.logPssSeq = com.eactive.eai.common.logger.Keys.LOG_SEQ_4;
			LogSender.send(this.logPssSeq, this.resEaiMsg, null);
		}
	}

	public void logSenderCtrlSend() {
		String telgmDmndDstcd = reqEaiMsg.getMapper().getSendRecvDivision(reqEaiMsg.getStandardMessage()); // S|R
		if (STDMessageKeys.SEND_RECV_CD_RECV.equals(telgmDmndDstcd)) {
			this.logPssSeq = com.eactive.eai.common.logger.Keys.LOG_SEQ_4;
		} else {
			this.logPssSeq = com.eactive.eai.common.logger.Keys.LOG_SEQ_2;
		}

		try {
			LogSender.send(this.logPssSeq, this.resEaiMsg, null);
		} catch (Exception e) {
			if (logger.isError())
				logger.error(guidLogPrefix + " AA Exception Logging Error :" + e.getMessage());
		}
	}

	public boolean checkServiceMsgSize() {
		if (MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) && reqEaiMsg.getSvcMsgs().size() > 1) {
			return true;
		} else {
			return false;
		}
	}

	public void setCurrentService() throws Exception {
		String keyMgtMsgVl = resEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl();
		if (logger.isDebug()) {
			logger.debug(guidLogPrefix + " AS 응답 keyMgtMsgVl[" + keyMgtMsgVl + "]");
		}
		resEaiMsg.setSvcPssSeq(resEaiMsg.getSvcPssSeq() + 1);
		resEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl);

		// AS 응답거래 라우팅
		try {
			// Service Routing
			String[] b2bKeys = B2BExtractor.getB2BRouteKeyValues(this.resEaiMsg.getEAISvcCd(),
					this.resEaiMsg.getSvcPssSeq(),
					this.resEaiMsg.getStandardMessage().getBizData(), getInboundCharset());
			String mappedKey = "DEFAULT";
			if (b2bKeys != null && b2bKeys.length > 0) {
				for (int i = 0; i < b2bKeys.length; i++) {
					if (logger.isDebug())
						logger.debug(guidLogPrefix + " AS 응답거래 : B2B RouteKey [" + b2bKeys[i] + "]");
					EAIMessage mappedEaiMsg = B2BServiceMapper.setB2BService(b2bKeys[i], this.resEaiMsg);
					if (mappedEaiMsg != null) {
						if (logger.isDebug())
							logger.debug(guidLogPrefix + " AS 응답거래 : EAISVCCD[" + this.resEaiMsg.getEAISvcCd()
									+ "] B2B RouteKey [" + b2bKeys[i] + "]의 서비스메시지를 매핑함");
						this.resEaiMsg = mappedEaiMsg;
						mappedKey = b2bKeys[i];
						break;
					}
				}
			} else {
				if (logger.isDebug())
					logger.debug(guidLogPrefix + " AS 응답거래 : 조회된 서비스 라우팅 키가 없습니다.");
				// 기동이 내부표준이 아닌 경우 기관코드로 라우팅 하도록 수정
				if (!com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.resEaiMsg.getStdMsgUsgCls())) {
					String instCd = this.resEaiMsg.getMapper().getInstCode(this.resEaiMsg.getStandardMessage());
					if (instCd == null || instCd.trim().length() == 0) {
						if (logger.isDebug())
							logger.debug(guidLogPrefix + " AS 응답거래 : 내부표준의 대외기관코드의 값이 없음");
					} else {
						String extBizCode = this.resEaiMsg.getExtBizCd();
						if (logger.isDebug())
							logger.debug(guidLogPrefix + " AS 응답거래 : B2B RouteKey 인터페이스 대외업무구분코드 [" + extBizCode + "]");
						if (logger.isDebug())
							logger.debug(guidLogPrefix + " AS 응답거래 : B2B RouteKey 내부표준의 대외기관코드 [" + instCd + "]");
						EAIMessage mappedEaiMsg = B2BServiceMapper.setB2BService( (extBizCode+instCd), this.resEaiMsg);
						if (mappedEaiMsg != null) {
							if (logger.isDebug())
								logger.debug(guidLogPrefix + " AS 응답거래 : EAISVCCD[" + this.resEaiMsg.getEAISvcCd()
										+ "] B2B RouteKey [" + extBizCode + instCd + "]의 서비스메시지를 매핑함");
							this.reqEaiMsg = mappedEaiMsg;
							mappedKey = extBizCode + instCd;
						}
					}
				}
			}

			// Adapter Routing
			if (logger.isDebug())
				logger.debug(guidLogPrefix + " AS 응답거래 : B2B Service RouteKey [" + mappedKey + "]");

			String[] adapterRouteKeys = B2BExtractor.getB2BAdapterRouteKeyValues(this.resEaiMsg.getEAISvcCd(),
					this.resEaiMsg.getSvcPssSeq(),
					this.resEaiMsg.getStandardMessage().getBizData()
					, getInboundCharset());
			if (adapterRouteKeys != null && adapterRouteKeys.length > 0) {
				for (int i = 0; i < adapterRouteKeys.length; i++) {
					if (logger.isDebug())
						logger.debug(guidLogPrefix + " AS 응답거래 : B2B Adapter RouteKey [" + adapterRouteKeys[i] + "]");
					EAIMessage mappedEaiMsg = B2BServiceMapper.setB2BAdapter(mappedKey, adapterRouteKeys[i],
							this.resEaiMsg, this.callProp);
					if (mappedEaiMsg != null) {
						if (logger.isDebug()) {
							logger.debug(guidLogPrefix + " AS 응답거래 : EAISVCCD[" + this.resEaiMsg.getEAISvcCd()
									+ "] B2B Adapter RouteKey [" + adapterRouteKeys[i] + "]의 어댑터를 매핑함");
						}
						this.resEaiMsg = mappedEaiMsg;
						break;
					} else {
						if (logger.isDebug()) {
							logger.debug(guidLogPrefix + " AS 응답거래 : EAISVCCD[" + this.resEaiMsg.getEAISvcCd()
									+ "] B2B Adapter RouteKey [" + adapterRouteKeys[i] + "] Not Found");
						}
					}
				}
			} else {
				if (logger.isDebug())
					logger.debug(guidLogPrefix + " AS 응답거래 : 조회된 어댑터 라우팅 키가 없습니다.");
			}
		} catch (Exception e) {
			if (logger.isError())
				logger.error(guidLogPrefix + " AS 응답거래 : B2B Serice Routing Set Error :" + e.getMessage());
			String[] msgArgs = new String[1];
			msgArgs[0] = this.resEaiMsg.getEAISvcCd();
			String rspErrorCode = "RECEAIFBR002";
			String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs);
			if (logger.isError())
				logger.error(guidLogPrefix + " AS 응답거래 : " + rspErrorMsg);
//			this.resEaiMsg.setRspErrCd(rspErrorCode);
//			this.resEaiMsg.setRspErrMsg(rspErrorMsg);
			this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg);
			throw new Exception(rspErrorCode);
		}

		// 기동이 표준인 경우만
		if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls())) {
			setReturnType(resEaiMsg, STDMessageKeys.SEND_RECV_CD_RECV);
		}
	}

	public boolean isOutboundCall() {
		return true;
	}

	public void init() throws Exception {
		try {
			String guid = this.reqEaiMsg.getMapper().getGuid(this.reqEaiMsg.getStandardMessage());
			String guidseq = this.reqEaiMsg.getMapper().getGuidSeq(this.reqEaiMsg.getStandardMessage());

			if (logger.isDebug())
				logger.debug(guidLogPrefix + " REQ Current GUID [" + guid + "][" + guidseq + "]");
			this.reqEaiMsg.getMapper().nextGuidSeq(this.reqEaiMsg.getStandardMessage());
			guidseq = this.reqEaiMsg.getMapper().getGuidSeq(this.reqEaiMsg.getStandardMessage());
			if (logger.isDebug())
				logger.debug(guidLogPrefix + " REQ ADD PATHSEQ GUID [" + guid + "][" + guidseq + "]");

			this.resEaiMsg = this.reqEaiMsg;
		} catch (Exception e) {
			String[] msgArgs = new String[1];
			msgArgs[0] = this.reqEaiMsg.getEAISvcCd();
			String rspErrorCode = "RECEAIFBR003";
			String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs);
			if (logger.isError())
				logger.error(guidLogPrefix + " " + rspErrorMsg, e);
//			this.resEaiMsg.setRspErrCd(rspErrorCode);
//			this.resEaiMsg.setRspErrMsg(rspErrorMsg);
			this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg);
			throw new Exception(rspErrorCode);
		}

		EAIServerManager eaiServerManager = EAIServerManager.getInstance();

		String srcAdapterGroupName = reqEaiMsg.getSngSysItfTp();
		AdapterManager adapterManager = AdapterManager.getInstance();
		AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(srcAdapterGroupName);

		if (eaiServerManager.isTASEnabledEAIServer() && EAIMessageKeys.TRANTYPE_FROMTAS.equals(reqEaiMsg.getTranType())
				&& inAdptGrpVO == null) {
			logger.info(guidLogPrefix + "- TAS 기동거래 [" + srcAdapterGroupName + "] = " + MessageType.ASC);
		} else {
			if (inAdptGrpVO == null) {
				String[] msgArgs = new String[1];
				msgArgs[0] = this.reqEaiMsg.getEAISvcCd();
				String rspErrorCode = "RECEAIFBF003";
				String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs) + "(어댑터그룹 미등록/미사용 - "
						+ srcAdapterGroupName + ")";
				if (logger.isError())
					logger.error(guidLogPrefix + rspErrorMsg);
//				this.resEaiMsg.setRspErrCd(rspErrorCode);
//				this.resEaiMsg.setRspErrMsg(rspErrorMsg);
				this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg);
				throw new Exception(rspErrorCode);
			}
		}
	}

	public void printExceptionMessage(Exception e) {
		if (logger.isError())
			logger.error(guidLogPrefix + " ExceptionPath : " + e.getMessage());
	}

	public boolean isSourceAsync() {
		if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) {
			return true;
		} else {
			return false;
		}
	}

	public void callExceptionHandler() {
		try {
			AdapterManager adapterManager = AdapterManager.getInstance();
			AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp());
			String inAdapterMsgType = inAdptGrpVO.getMessageType();
			if (EAITable.EBCDIC_TYPE.equals(inAdapterMsgType)) {
				String bizData = this.reqEaiMsg.getStandardMessage().getBizData();
				byte[] asc = CodeConversion.meToMixedAsc(bizData.getBytes());
				try {
					String inboundCharset = callProp.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN);
					this.reqEaiMsg.getStandardMessage().setBizData(new String(asc), inboundCharset);
				} catch (Exception e) {
					logger.error("setBizData error", e);
				}
			}
			ExceptionHandler.handle(this.reqEaiMsg);
		} catch (Exception e) {
			if (logger.isError())
				logger.error(guidLogPrefix + " ExceptionHandler Call Error", e);
		}
	}

	public boolean isRealCall() {
		if (this.callProp != null) {
			String mode = this.callProp.getProperty(EAIKeys.CALL_MODE_KEY);
			if (mode != null && EAIKeys.CALL_MODE_WARMUP.equals(mode)) {
				logger.warn(guidLogPrefix + " Warming Up Called");
				return false;
			} else {
				return true;
			}
		} else {
			return true;
		}
	}
	
	private String getInboundCharset() {
		String srcAdapterGroupName = reqEaiMsg.getSngSysItfTp();
		AdapterManager adapterManager = AdapterManager.getInstance();
		AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(srcAdapterGroupName);
		String charset = StringUtils.defaultIfBlank(inAdptGrpVO.getMessageEncode(), Charset.defaultCharset().name());
		return charset;
	}
	
	public void setRoute() throws Exception {
		String adapterGroupName;
		try {
			// Service Routing
			String[] b2bKeys = B2BExtractor.getB2BRouteKeyValues(this.reqEaiMsg.getEAISvcCd(),
					this.reqEaiMsg.getSvcPssSeq()
					, this.reqEaiMsg.getStandardMessage().getBizData(), getInboundCharset());

			String mappedKey = "DEFAULT";
			if (b2bKeys != null && b2bKeys.length > 0) {
				for (int i = 0; i < b2bKeys.length; i++) {
					if (logger.isDebug())
						logger.debug(guidLogPrefix + " B2B RouteKey [" + b2bKeys[i] + "]");
					EAIMessage mappedEaiMsg = B2BServiceMapper.setB2BService(b2bKeys[i], this.reqEaiMsg);
					if (mappedEaiMsg != null) {
						if (logger.isDebug())
							logger.debug(guidLogPrefix + " EAISVCCD[" + this.reqEaiMsg.getEAISvcCd()
									+ "] B2B RouteKey [" + b2bKeys[i] + "]의 서비스메시지를 매핑함");
						this.reqEaiMsg = mappedEaiMsg;
						mappedKey = b2bKeys[i];
						break;
					}
				}
			} else {
				if (logger.isDebug())
					logger.debug(guidLogPrefix + " 조회된 서비스 라우팅 키가 없습니다.");

				// 기동이 내부 표준인 경우 기관코드로 라우팅 하도록 수정
				if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls())) {
					String instCd = this.reqEaiMsg.getMapper().getInstCode(this.reqEaiMsg.getStandardMessage());
					
					if (instCd == null || instCd.trim().length() == 0) {
						if (logger.isDebug())
							logger.debug(guidLogPrefix + " 내부표준의 대외기관코드의 값이 없음");
					} else {
						String extBizCode = this.reqEaiMsg.getExtBizCd();
						if (logger.isDebug()) {
							logger.debug(guidLogPrefix + " B2B RouteKey 인터페이스의 대외업무구분코드 [" + extBizCode + "]");
							logger.debug(guidLogPrefix + " B2B RouteKey 내부표준의 대외기관코드 [" + instCd + "]");
						}
						EAIMessage mappedEaiMsg = B2BServiceMapper.setB2BService(extBizCode + instCd, this.reqEaiMsg);
						if (mappedEaiMsg != null) {
							if (logger.isDebug())
								logger.debug(guidLogPrefix + " EAISVCCD[" + this.reqEaiMsg.getEAISvcCd()
										+ "] B2B RouteKey [" + instCd + "]의 서비스메시지를 매핑함");
							this.reqEaiMsg = mappedEaiMsg;
							mappedKey = extBizCode + instCd;
						}
					}
				}
			}

			// EAI서비스코드 앞 3자리와 he03의 PSVSYSBZWKDSTCD 의 앞 3자리가 다른경우 추출
			PropManager pMan = PropManager.getInstance();
			String differenceLog = pMan.getProperty("DIFFERENCE", "LOG_YN", "Y");
			if ("Y".equals(differenceLog)) {
				if (this.reqEaiMsg != null && this.reqEaiMsg.getCurrentSvcMsg() != null) {

					String eaiSvcName = this.reqEaiMsg.getEAISvcCd();
					String instCd = getInstCode(this.reqEaiMsg);
					String biz = this.reqEaiMsg.getCurrentSvcMsg().getPsvBwkSysNm();
					String keys = "";
					String apcode = "";

					if (eaiSvcName != null && eaiSvcName.trim().length() >= 3) {
						apcode = eaiSvcName.trim().substring(0, 3);
					}

					if (b2bKeys != null && b2bKeys.length > 0) {
						for (String k : b2bKeys) {
							keys += "," + k;
						}
					}
					keys = "[" + keys + "]";
					if (biz != null) {
						biz = biz.trim();
					}
					if (apcode != null && biz != null) {
						if (!biz.equals(apcode)) {
							logger.error("B2BFCProcess] difference apcode set apcode=" + apcode + ", bwksysnm=" + biz
									+ ", eaisvcname=" + eaiSvcName + ", keys=" + keys + ", instCd=" + instCd);
						}
					} else {
						logger.error("B2BFCProcess] difference apcode set apcode=" + apcode + ", bwksysnm=" + biz
								+ ", eaisvcname=" + eaiSvcName + ", keys=" + keys + ", instCd=" + instCd);
					}
				}
			}

			// Adapter Routing
			if (logger.isDebug())
				logger.debug(guidLogPrefix + " B2B Service RouteKey [" + mappedKey + "]");

			String[] adapterRouteKeys = B2BExtractor.getB2BAdapterRouteKeyValues(this.reqEaiMsg.getEAISvcCd(),
					this.reqEaiMsg.getSvcPssSeq()
					, this.reqEaiMsg.getStandardMessage().getBizData()
					, getInboundCharset());
			if (adapterRouteKeys != null && adapterRouteKeys.length > 0) {
				for (int i = 0; i < adapterRouteKeys.length; i++) {
					if (logger.isDebug()) {
						logger.debug(guidLogPrefix + " B2B Adapter RouteKey [" + adapterRouteKeys[i] + "]");
					}
					EAIMessage mappedEaiMsg = B2BServiceMapper.setB2BAdapter(mappedKey, adapterRouteKeys[i],
							this.reqEaiMsg, this.callProp);
					if (mappedEaiMsg != null) {
						if (logger.isDebug()) {
							logger.debug(guidLogPrefix + " EAISVCCD[" + this.reqEaiMsg.getEAISvcCd()
									+ "] B2B Adapter RouteKey [" + adapterRouteKeys[i] + "]의 어댑터를 매핑함 - "
									+ callProp.getProperty(Keys.OUT_ADAPTER_GROUP_NAME));
						}
						this.reqEaiMsg = mappedEaiMsg;
						break;
					} else {
						if (logger.isDebug())
							logger.debug(guidLogPrefix + " EAISVCCD[" + this.reqEaiMsg.getEAISvcCd()
									+ "] B2B Adapter RouteKey [" + adapterRouteKeys[i] + "] Not Found");
					}
				}
			} else {
				if (logger.isDebug())
					logger.debug(guidLogPrefix + " 조회된 어댑터 라우팅 키가 없습니다.");
			}
		} catch (Exception e) {
			if (logger.isError())
				logger.error(guidLogPrefix + " B2B Serice Routing Set Error :" + e.getMessage());
			String[] msgArgs = new String[1];
			msgArgs[0] = this.reqEaiMsg.getEAISvcCd();
			String rspErrorCode = "RECEAIFBR002";
			String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs);
			if (logger.isError())
				logger.error(guidLogPrefix + " " + rspErrorMsg);
//			this.resEaiMsg.setRspErrCd(rspErrorCode);
//			this.resEaiMsg.setRspErrMsg(rspErrorMsg);
			this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg);
			throw new Exception(rspErrorCode);
		}

		try {
			adapterGroupName = reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp();

			EAIServerManager eaiServerManager = EAIServerManager.getInstance();
			if (eaiServerManager.isTASEnabledEAIServer()
					&& EAIMessageKeys.TRANTYPE_TAS.equals(reqEaiMsg.getTranType())) {
				PropManager manager = PropManager.getInstance();
				Properties prop = manager.getProperties(RouteKeys.SIM);

				if (reqEaiMsg.getCurrentSvcMsg().isSyncItfTp()) {
					adapterGroupName = prop.getProperty(RouteKeys.SIM_ADAPTER_SYNC, "_SIM_OU_HTT_SyC");
				} else {
					adapterGroupName = prop.getProperty(RouteKeys.SIM_ADAPTER_ASYNC, "_SIM_OU_HTT_AsC");
				}
			} else {
				AdapterManager adapterManager = AdapterManager.getInstance();
				AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName);

				if (adptGrpVO == null) {
					throw new Exception("수동어댑터[" + adapterGroupName + "]가 사용 중이 아님");
				}
				this.adptrMsgPtrnCd = adptGrpVO.getAdptrMsgPtrnCd();
			}
		} catch (Exception e) {
			String[] msgArgs = new String[1];
			msgArgs[0] = this.reqEaiMsg.getEAISvcCd();
			String rspErrorCode = "RECEAIFBR003";
			String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs);
			if (logger.isError())
				logger.error(guidLogPrefix + " " + rspErrorMsg, e);
//			this.resEaiMsg.setRspErrCd(rspErrorCode);
//			this.resEaiMsg.setRspErrMsg(rspErrorMsg);
			this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg);
			throw new Exception(rspErrorCode);
		}

		// AA가 아니고 기동이 KB표준이 아닌 경우 Adapter의 timeout값을 설정한다.
		try {
			String svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // 기동 호출방식
			String psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 수동 호출방식

			AdapterManager adapterManager = AdapterManager.getInstance();
			AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName);

			if (!(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp))
					&& !(com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls()))) {
				// SA 또는 SNA Adapter일 경우에 는 SA Timeout값을 설정
				if ((EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp))
						|| Keys.TYPE_SNA.equals(adptGrpVO.getType())) {
					int saTimeoutSec = this.reqEaiMsg.getCurrentSvcMsg().getTmoVl();
					if (logger.isDebug())
						logger.debug("BaseFCProcess] SA TimeoutValue [" + saTimeoutSec + "]");
					setTimeout(this.reqEaiMsg, "" + saTimeoutSec);
				} else {
					int timeout = ServiceUtil.getTimeoutValue(adapterGroupName);
					if (logger.isDebug())
						logger.debug("BaseFCProcess] Target Adapter TimeoutValue [" + timeout + "]");
					if (timeout > 0) {
						if (logger.isDebug())
							logger.debug("BaseFCProcess] Set Adapter TimeoutValue [" + timeout + "] to KBMessage");
						setTimeout(this.reqEaiMsg, "" + timeout);
					}
				}
			}
		} catch (Exception e) {
			if (logger.isWarn()) {
				logger.warn("BaseFCProcess] Get Adapter TimeoutValue Error - " + e.getMessage(), e);
			}
		}
	}

	public void setAdptrInstiCode() throws Exception {
		String groupName = reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp();
		
		AdapterManager adapterManager = AdapterManager.getInstance();
		AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(groupName);

		if (adptGrpVO != null) {
			String adptrInstiCode = adptGrpVO.getAdptrInstiCode();
			if (adptrInstiCode != null && !"".equals(adptrInstiCode)) {
				reqEaiMsg.setAdptrInstiCode(adptrInstiCode);
			}
		}
	}

	public void setGUID() throws Exception {
		InterfaceMapper mapper = this.resEaiMsg.getMapper();
		StandardMessage standardMessage = this.resEaiMsg.getStandardMessage();
		String guid = mapper.getGuid(standardMessage);
		String guidseq = mapper.getGuidSeq(standardMessage);

		if (logger.isDebug())
			logger.debug(guidLogPrefix + " REQ Current GUID [" + guid + "][" + guidseq + "]");
		mapper.nextGuidSeq(standardMessage);
		guidseq = mapper.getGuidSeq(standardMessage);
		if (logger.isDebug())
			logger.debug(guidLogPrefix + " REQ ADD PATHSEQ GUID [" + guid + "][" + guidseq + "]");

		String svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // 기동 호출방식
		String psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 수동 호출방식

		if ((!(com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd))
				&& !(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)))
				|| ((com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd))
						&& (EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp)
								&& EAIMessageKeys.SYNC_SVC.equals(psvItfTp)))) {
			String prcssRtdTranCd = mapper.getReturnServiceId(standardMessage);

			if (prcssRtdTranCd != null && prcssRtdTranCd.length() >= 14) {
				String telgmRecvTranCd = prcssRtdTranCd.substring(4, 14);
				mapper.setServiceId(standardMessage, telgmRecvTranCd);
			} else {
				if (logger.isInfo()) {
					logger.info(guidLogPrefix + "- PrcssRtdTranCd Length < 14 [" + prcssRtdTranCd + "]");
				}
			}
		}

		if (!(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp))
				&& (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls()))
				&& (STDMessageKeys.RECOVER_YN_YES
						.equals(this.reqEaiMsg.getMapper().getRecoverYn(this.reqEaiMsg.getStandardMessage())))) {
			String reqOgtranGuIdNo = this.reqEaiMsg.getMapper().getOrgGuid(this.reqEaiMsg.getStandardMessage());
			mapper.setOrgGuid(standardMessage, reqOgtranGuIdNo);
			if (logger.isInfo()) {
				logger.info(guidLogPrefix + " OgtranGuIdNo 복원 " + this.reqEaiMsg.getSvcOgNo() + " OgtranGuIdNo ["
						+ mapper.getOrgGuid(standardMessage) + "]");
			}
		}
	}
}
