package com.eactive.eai.custom.message;

import java.util.Properties;

import org.apache.commons.lang3.StringUtils;

import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.message.EAIMessage;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.server.EAIServerManager;
import com.eactive.eai.common.util.DatetimeUtil;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.common.util.MessageUtil;
import com.eactive.eai.custom.stderrorcode.ChannelErrorCodeManager;
import com.eactive.eai.custom.stderrorcode.ChannelErrorCodeVO;
import com.eactive.eai.custom.stderrorcode.StdErrorCodeManager;
import com.eactive.eai.custom.stderrorcode.StdErrorCodeVO;
import com.eactive.eai.inbound.error.InboundErrorKeys;
import com.eactive.eai.inbound.processor.ProcessVO;
import com.eactive.eai.message.StandardItem;
import com.eactive.eai.message.StandardMessage;
import com.eactive.eai.message.manager.StandardMessageManager;
import com.eactive.eai.message.service.DefaultStandardMessageCoordinator;
import com.eactive.eai.message.service.InterfaceMapper;
import com.ext.eai.common.stdmessage.STDMessageErrorKeys;
import com.ext.eai.common.stdmessage.STDMessageKeys;

public class StandardMessageCoordinatorKAKAOCARD extends DefaultStandardMessageCoordinator  {
   static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
   //private static int defaultTimeout = 30; 
   private static String GW_SESSION_ID         = "INTERFACE_COMMON.GTWY_SESN_ID";
   private static String GW_INSTANCE_ID        = "INTERFACE_COMMON.GTWY_INSTNC_ID";
   private static String MESSAGE_OUT_ATRB_CD   = "MESSAGE.OUT_ATRB_CD";//출력속성코드
   private static String MESSAGE_OUT_MSG_DESC  = "MESSAGE.OUT_MSG_DESC";//출력메시지설명
   private static String COMMON_OUT_FMSG_DSTCD = "COMMON.OUT_FMSG_DSTCD";//출력전문구별코드
   private static String MESSAGE               = "MESSAGE";//메시지부

   @Override
   public void coordinateAfterParsing(StandardMessage standardMessage, Object paramObject, Properties prop) {
      StandardMessageManager standardManager = StandardMessageManager.getInstance();
      InterfaceMapper mapper = standardManager.getMapper();
      //표준에서 들어올때 표준전문의 값을 header에 셋팅
      //표준전문 to prop 
      if (EAIServerManager.getInstance().isFEP()) {
         StandardItem gwSesnId = standardMessage.findItem(GW_SESSION_ID);//transactionId
         StandardItem gwNodeNo = standardMessage.findItem(GW_INSTANCE_ID);//instanceId
         if (gwSesnId != null && gwNodeNo != null && StringUtils.isNotBlank(gwSesnId.getValue()) && StringUtils.isNotBlank(gwNodeNo.getValue())) {
            prop.put(HttpClientAdapterServiceKey.TRANSACTION_ID, gwSesnId.getValue());
            prop.put(HttpClientAdapterServiceKey.INSTANCE_ID, gwNodeNo.getValue());
         }
      }      

      // REST용 전달값 중 api_path 이후의 값을 표준전문 API_PATH에 셋팅
      String adapterApiPath = prop.getProperty(HttpAdapterServiceKey.API_PATH);
      if (StringUtils.isNotBlank(adapterApiPath)) {
         String adapterExtUri = prop.getProperty(HttpAdapterServiceKey.INBOUND_EXTURI);
         /*
          * apiPath 나머지를 추출하기 위해서
          * 예) 어댑터에 설정되어 있는 API_PATH = /api/cts
          *     어댑터에 들어온 INBOUND_EXTURI = /api/cts/cmb/api/user/custom
          *     표준전문에 셋팅하고 싶은값 /cmb/api/user/custom
          */
         String standardApiPath = adapterExtUri.replaceAll(adapterApiPath, "");
         if (!standardApiPath.startsWith("/")) {
            standardApiPath = standardApiPath + "/";
         }
         if (standardApiPath.length() > 1) {
            mapper.setServiceId(standardMessage,standardApiPath);
         }
      }
      
      //아래로직은 표준전문에서 요청일때 MESSAGE부가 안보이고 응답일때 MESSAGE부 보이게 설정
      String sendRecvDivision = mapper.getSendRecvDivision(standardMessage);
      StandardItem msg = standardMessage.findItem(MESSAGE);
      if (StringUtils.equals(sendRecvDivision, STDMessageKeys.SEND_RECV_CD_SEND)) {
         msg.setHidden(true);
      }
      if (StringUtils.equals(sendRecvDivision, STDMessageKeys.SEND_RECV_CD_RECV)) {
         msg.setHidden(false);
      }
      
      //mci이고 요청 거래시에 설정 인스턴스ID설정
      EAIServerManager server = EAIServerManager.getInstance();
      if (server != null && server.isMCI() && (StringUtils.equals(sendRecvDivision, STDMessageKeys.SEND_RECV_CD_SEND))) {
         //인스턴스ID설정
         String instCode = mapper.getInstCode(standardMessage);
         String localServer = server.getLocalServerName();
         if (instCode != null && localServer != null) {
            mapper.setInstCode(standardMessage, localServer);
         }
         //타임아웃값이 없을경우 default값 설정
         String timeout = mapper.getTimeout(standardMessage);
         
         int defaultTimeout = getDefaultTimeout();
         if (StringUtils.isBlank(timeout)) {
            mapper.setTimeout(standardMessage, Integer.toString(defaultTimeout));
         }else {
            try {
               Integer.parseInt(timeout);
            }catch(Exception e) {
               mapper.setTimeout(standardMessage, Integer.toString(defaultTimeout));
            }
         }
      }
      //TODO 표준전문 메시지 설정해야됨
      //표준전문에 메시지 부에 값이 있을경우 처리
      if (!msg.isHidden()) {
         String errmsg = mapper.getErrorMsg(standardMessage);
         if (StringUtils.isBlank(errmsg)) {
            String errCode = mapper.getErrorCode(standardMessage);
            if (StringUtils.isNotBlank(errCode)) {
               StdErrorCodeManager manager = StdErrorCodeManager.getInstance();
               StdErrorCodeVO vo = manager.getSTDErrorCode(errCode);
               if (vo != null) {
                  mapper.setErrorMsg(standardMessage, vo.getErrMsg());
                  if (server != null && server.isMCI()) {
                     String type = mapper.getChannelDetailCd(standardMessage);
                     //채널오류코드 셋팅
                     ChannelErrorCodeManager cmanager = ChannelErrorCodeManager.getInstance();
                     ChannelErrorCodeVO cvo = cmanager.getChannelErrorCode(errCode+"_"+type);
                     if (cvo != null) {
                        mapper.setErrorMsg(standardMessage, cvo.getErrMsg());
                     }
                  }
               }
            }
         }
      }
   }

   @Override
   //비표준처리
   public void coordinateAfterCreateMessageByRule(StandardMessage standardMessage, Object paramObject, Properties prop) {
      StandardMessageManager standardManager = StandardMessageManager.getInstance();
      InterfaceMapper mapper = standardManager.getMapper();
      //비표준에서 들어올때 header값을 표준전문에 셋팅
      //prop to 표준전문 
      if (EAIServerManager.getInstance().isFEP()) {
         String trandactionId = prop.getProperty(HttpClientAdapterServiceKey.TRANSACTION_ID);
         String instanceId = prop.getProperty(HttpClientAdapterServiceKey.INSTANCE_ID);
         if (StringUtils.isNotBlank(trandactionId) && StringUtils.isNotBlank(instanceId)) {
            StandardItem gwSesnId = standardMessage.findItem(GW_SESSION_ID);//transactionId
            if (gwSesnId != null) {
               gwSesnId.setValue(trandactionId);
            }
            StandardItem gwNodeNo = standardMessage.findItem(GW_INSTANCE_ID);//instanceId
            if (gwNodeNo != null) {
               gwNodeNo.setValue(instanceId);
            }
         }
      }

      EAIServerManager eaiServerManager = EAIServerManager.getInstance();
      //HEADER.GUID설정
      mapper.setGuid(standardMessage,GUIDGeneratorKAKAOCARD.getGUID(eaiServerManager.getSystemType()));
      //HEADER.FMSG_REQ_RES_DSTCD 전문요청응답구별코드 : 표준전문값

      //HEADER.FRST_TRNM_IPAD 최초전송IP주소
      mapper.setFirstReqIp(standardMessage, "0.0.0.0");
      //HEADER.GNRZ_TMOT_TM 총괄타임아웃시간 
      mapper.setTimeout(standardMessage, "180");
      // HEADER.SYS_ENV_DSTCD 시스템운영환경구분코드
      String operationEnv = mapper.getOperationEnv(standardMessage);
      if (operationEnv != null && StringUtils.isBlank(operationEnv)) {
         mapper.setOperationEnv(standardMessage, getSysOprtEnvDvcd(eaiServerManager));
      }
      // HEADER.CARD_TX_TYP_DSTCD 거래유형구별코드
      StandardItem cardTxTypDstcd = standardMessage.findItem("HEADER.CARD_TX_TYP_DSTCD");
      if (cardTxTypDstcd != null ) {
         cardTxTypDstcd.setValue("O");
      }
      //COMMON.GROUP_CMP_CD 그룹회사코드
      StandardItem groupCmpCd = standardMessage.findItem("COMMON.GROUP_CMP_CD");
      if (groupCmpCd != null ) {
         groupCmpCd.setValue("090");
      }
      //COMMON.TX_BRCD 거래부점코드
      StandardItem txBrcd = standardMessage.findItem("COMMON.TX_BRCD");
      if (txBrcd != null ) {
         txBrcd.setValue("0000");
      }
      //COMMON.RLTR_BRCD 실거래부점코드
      StandardItem rltrBrcd = standardMessage.findItem("COMMON.RLTR_BRCD");
      if (rltrBrcd != null ) {
         rltrBrcd.setValue("0000");
      }
      //COMMON.TLRNO 텔러번호
      StandardItem tlrno = standardMessage.findItem("COMMON.TLRNO");
      if (tlrno != null ) {
         tlrno.setValue("000000");
      }
      //COMMON.TX_DT 거래일자
      StandardItem txDt = standardMessage.findItem("COMMON.TX_DT");
      if (txDt != null ) {
         txDt.setValue(DatetimeUtil.getFormattedDate("yyyyMMdd"));
      }
      //COMMON.TX_TM 거래시간
      StandardItem txTm = standardMessage.findItem("COMMON.TX_TM");
      if (txTm != null ) {
         txTm.setValue(DatetimeUtil.getFormattedDate("HHmmssSSS"));
      }
      
      //아래로직은 표준전문에서 요청일때 MESSAGE부가 안보이고 응답일때 MESSAGE부 보이게 설정
      String sendRecvDivision = mapper.getSendRecvDivision(standardMessage);
      StandardItem msg = standardMessage.findItem(MESSAGE);
      if (StringUtils.equals(sendRecvDivision, STDMessageKeys.SEND_RECV_CD_SEND)) {
         msg.setHidden(true);
      }
      if (StringUtils.equals(sendRecvDivision, STDMessageKeys.SEND_RECV_CD_RECV)) {
         msg.setHidden(false);
      }

      //TODO 표준전문 메시지 설정해야됨
      //응답일경우 MESSAGE부에 정상 메시지 헤더를 설정하기 위해서
      if (StringUtils.equals(sendRecvDivision, STDMessageKeys.SEND_RECV_CD_RECV)) {
         StandardItem outputAtrbCd = standardMessage.findItem(MESSAGE_OUT_ATRB_CD);//출력속성코드
         outputAtrbCd.setValue("1");
         
         mapper.setErrorCode(standardMessage, STDMessageErrorKeys.SUCCESS_CODE_VALUE);
         mapper.setErrorMsg(standardMessage, STDMessageErrorKeys.SUCCESS_MSG_VALUE);
         mapper.setResponseType(standardMessage, STDMessageKeys.RESPONSE_TYPE_CODE_N);
      }
   }
   @Override
   public void coordinateInReturnObject(StandardMessage standardMessage) {
      //아래로직은 표준전문에서 응답일때 MESSAGE부가 보이게 하기위해서
      StandardMessageManager standardManager = StandardMessageManager.getInstance();
      InterfaceMapper mapper = standardManager.getMapper();
      mapper.setSendRecvDivision(standardMessage, STDMessageKeys.SEND_RECV_CD_RECV);
      StandardItem msg = standardMessage.findItem(MESSAGE);
      msg.setHidden(false);
   }
   public String getSysOprtEnvDvcd(EAIServerManager eaiServerManager) {
      String result = "";
      if (eaiServerManager.isPEAIServer()) { // 운영
         result = "R";
      } else if (eaiServerManager.isDEAIServer()) { // 개발
         result = "D";
      } else if (eaiServerManager.isSEAIServer()) { // 테스트/검증
         result = "T";
      }
      return result;
   }

   @Override
   public void coordinateBeforeInboundErrorResponse(StandardMessage standardMessage) {
      StandardMessageManager standardManager = StandardMessageManager.getInstance();
      InterfaceMapper mapper = standardManager.getMapper();
      mapper.setSendRecvDivision(standardMessage, STDMessageKeys.SEND_RECV_CD_RECV);
      StandardItem msg = standardMessage.findItem(MESSAGE);
      msg.setHidden(false);
   }

   @Override
   public boolean coordinateSetStandardMessageError(StandardMessage standardMessage, InterfaceMapper mapper,
         String errCode, String errMsg) {
      String siteErrCode = null;
      String siteErrMessage = null;
      if(errCode != null) {
         siteErrCode = MessageUtil.getTobeCode(errCode);
         siteErrMessage = MessageUtil.getTobeMessage(errCode);
      }

      String sendRecvDivision = mapper.getSendRecvDivision(standardMessage);
      if (StringUtils.equals(sendRecvDivision, STDMessageKeys.SEND_RECV_CD_RECV)) {
         StandardItem msg = standardMessage.findItem(MESSAGE);
         msg.setHidden(false);
      }
      
      StandardItem outputAtrbCd = standardMessage.findItem(MESSAGE_OUT_ATRB_CD);//출력속성코드
      outputAtrbCd.setValue("1");
   
      if (siteErrCode != null) {
         mapper.setErrorCode(standardMessage, siteErrCode);
      }else if (errCode != null) {
         mapper.setErrorCode(standardMessage, errCode);
      }
      
      if (siteErrMessage != null) {
         mapper.setErrorMsg(standardMessage, siteErrMessage);
      }else if (errMsg != null){
         mapper.setErrorMsg(standardMessage, errMsg);
      }
      
      StandardItem outputMsgDesc = standardMessage.findItem(MESSAGE_OUT_MSG_DESC);//출력메시지설명
      if (errMsg != null){
         outputMsgDesc.setValue(errMsg);
      }
      mapper.setResponseType(standardMessage, STDMessageKeys.RESPONSE_TYPE_CODE_E);
      
      return false;
      
   }

   @Override
   //복원시
   public void coordinateAfterRestored(StandardMessage dbMessage, StandardMessage responseMessage) {
      StandardMessageManager standardManager = StandardMessageManager.getInstance();
      InterfaceMapper mapper = standardManager.getMapper();
      String interfaceId = mapper.getInterfaceId(responseMessage);
      mapper.setInterfaceId(dbMessage, interfaceId);

      String sendRecvDivision = mapper.getSendRecvDivision(responseMessage);
      mapper.setSendRecvDivision(dbMessage, sendRecvDivision);

      String inExDivision = mapper.getInExDivision(responseMessage);
      mapper.setInExDivision(dbMessage, inExDivision);

      String recoverYn = mapper.getRecoverYn(responseMessage);
      mapper.setRecoverYn(dbMessage, recoverYn);
      
      //복원시 처리결과수신 서비스코드를 서비스코드에 셋팅한다.
      //처리결과수신값이 없을경우 원거래 서비스ID를 셋팅한다.
      String returnServiceId = mapper.getReturnServiceId(dbMessage);
      if (StringUtils.isBlank(returnServiceId)){
         returnServiceId = mapper.getServiceId(dbMessage);
      }
      mapper.setServiceId(dbMessage, returnServiceId);
      
      //표준전문 메시지 관련 설정 
      String dbSendRecvDivision = mapper.getSendRecvDivision(dbMessage);
      StandardItem msg = dbMessage.findItem(MESSAGE);
      if ( StringUtils.equals(dbSendRecvDivision, STDMessageKeys.SEND_RECV_CD_SEND)) {
         msg.setHidden(true);
      }
      if (StringUtils.equals(dbSendRecvDivision, STDMessageKeys.SEND_RECV_CD_RECV)) {
         msg.setHidden(false);
      }
      //응답일경우 MESSAGE부 정상설정
      if (StringUtils.equals(dbSendRecvDivision, STDMessageKeys.SEND_RECV_CD_RECV)) {
         StandardItem outputAtrbCd = dbMessage.findItem(MESSAGE_OUT_ATRB_CD);//출력속성코드
         outputAtrbCd.setValue("1");
         
         mapper.setErrorCode(dbMessage, STDMessageErrorKeys.SUCCESS_CODE_VALUE);//출력메시지코드
         mapper.setErrorMsg(dbMessage, STDMessageErrorKeys.SUCCESS_MSG_VALUE);//출력메시지내용
         mapper.setResponseType(dbMessage, STDMessageKeys.RESPONSE_TYPE_CODE_N);
      }
   }
   @Override
   public boolean coordinateIsWaitCheckForSync(StandardMessage responseMessage) {
      StandardItem outputMesgTycd = responseMessage.findItem(COMMON_OUT_FMSG_DSTCD);
      if (outputMesgTycd != null && StringUtils.equals(outputMesgTycd.getValue(), "9")) {
         return true;
      }

      return false;
   }
   @Override
   public int coordinateForTimeoutCodeToValue(EAIMessage eaiMessage) {
      StandardMessageManager standardManager = StandardMessageManager.getInstance();
      InterfaceMapper mapper = standardManager.getMapper();      
      EAIServerManager server = EAIServerManager.getInstance();
      if (server != null && server.isMCI()) { //MCI 일경우 처리
         StandardMessage standardMessage = eaiMessage.getStandardMessage();
         String timeout = mapper.getTimeout(standardMessage);
         int defaultTimeout = getDefaultTimeout();
         
         if (StringUtils.isBlank(timeout)) {
            return defaultTimeout;
         }else {
            try {
               return Integer.parseInt(timeout);
            }catch(Exception e) {
               return defaultTimeout;
            }
         }
      }else { //MCI 이외일 경우 처리 (인터페이스에 있는 타임아웃기준)
         return eaiMessage.getCurrentSvcMsg().getTmoVl();
      }
   }
   private int getDefaultTimeout() {
      PropManager manager = PropManager.getInstance();
      int defaultTimeout = 30;
      try {
         String sdefaultTimeout = manager.getProperty("KAKAO_CARD", "DEFAULT_TIMEOUT", Integer.toString(defaultTimeout));
         defaultTimeout = Integer.parseInt(sdefaultTimeout);
      }catch(Exception e) {
         
      }
      return defaultTimeout;
   }

	@Override
	public boolean coordinateValidation(StandardMessage standardMessage, ProcessVO vo) {
		// RECEAIIRP110 인터페이스 ({1}) 에 표준전문 항목 ({2}) 의 값이 없습니다.
		// RECEAIIRP120 인터페이스 ({1}) 에 표준전문 항목 ({2}) 의 값을 확인하세요.

		StandardMessageManager standardManager = StandardMessageManager.getInstance();
		InterfaceMapper mapper = standardManager.getMapper();
		String interfaceId = mapper.getInterfaceId(standardMessage);

		String guid = mapper.getGuid(standardMessage);
		if (StringUtils.isBlank(guid)) {
			vo.setRspErrorCode("RECEAIIRP110");
			vo.setRspErrorMsg(ExceptionUtil.make(vo.getRspErrorCode(), new String[] { interfaceId, "GUID" }));
			vo.setErrTypeCode(InboundErrorKeys.IN_ERROR);
			return false;
		}
		String guidSeq = mapper.getGuidSeq(standardMessage);
		if (StringUtils.isBlank(guidSeq)) {
			vo.setRspErrorCode("RECEAIIRP110");
			vo.setRspErrorMsg(ExceptionUtil.make(vo.getRspErrorCode(), new String[] { interfaceId, "GUID" }));
			vo.setErrTypeCode(InboundErrorKeys.IN_ERROR);
			return false;
		}

		if (guid.length() + guidSeq.length() != 36) {
			vo.setRspErrorCode("RECEAIIRP120");
			vo.setRspErrorMsg(ExceptionUtil.make(vo.getRspErrorCode(), new String[] { interfaceId, "GUID" }));
			vo.setErrTypeCode(InboundErrorKeys.IN_ERROR);
			return false;
		}

		return true;
	}

}