package com.eactive.eai.adapter.wca;

import com.eactive.eai.adapter.RequestDispatcher;
import com.eactive.eai.adapter.wca.data.WCAHeader;
import com.eactive.eai.adapter.wca.exception.WCAException;
import com.eactive.eai.adapter.wca.global.WCADefine;
import com.eactive.eai.adapter.wca.util.MyUtil;
import com.eactive.eai.common.util.Logger;

import java.util.Properties;

/** 
* 1. 기능 : INBOUND 처리 interface 구현
* 2. 처리 개요 : 
* 3. 주의사항 
*
* @author  : 
* @version : v 1.0.0
* @see     : 
* @since   : 
*/
public class WCAEventListener implements WCAEventInterface, SNAProperties
{
    /**
     * SNAAdapter 로깅을 위한 logger 
     */
    Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME);
    
   /** 
    * 1. 기능 : NonResponse Transaction Mode 데이터 처리
    * 2. 처리 개요 : 
    * 3. 주의사항 
    *    
    * @param    adapterGrpName    어댑터 그룹 이름
    * @param    adapterName       어댑터 이름
    * @param    nLen              송신 길이
    * @param    pBuff             송신 데이타
    **/   
    public void handleNonRspData(String adapterGrpName, String adapterName, String sGroupCode, int nLen, byte[] pBuff) {
        WCAEventProcess(adapterGrpName, adapterName, sGroupCode, nLen, pBuff);                
    }

    /** 
    * 1. 기능 : NonResponse Transaction Mode 데이터 처리
    * 2. 처리 개요 : 
    * 3. 주의사항 
    *    
    * @param    adapterGrpName    어댑터 그룹 이름
    * @param    adapterName       어댑터 이름
    * @param    nLen              송신 길이
    * @param    pBuff             송신 데이타
    **/   
    public void handleTimeoutData(String adapterGrpName, String adapterName, String sGroupCode, int nLen, byte[] pBuff) {         
    	WCAEventProcess(adapterGrpName, adapterName, sGroupCode, nLen, pBuff);        
    }
    
    /** 
    * 1. 기능 : INBOUND 데이타 처리 로직
    * 2. 처리 개요 : 
    *       - Softlink 수신 데이타에서 프로퍼티 정보와 송신데이타 추출한다.
    *       - 프로퍼티 설정한다.
    *       - EAI INBOUND 호출한다. 
    * 3. 주의사항 
    *    
    * @param    adapterGrpName    어댑터 그룹 이름
    * @param    adapterName       어댑터 이름
    * @param    nLen              송신 길이
    * @param    pBuff             송신 데이타
    **/   
    private void WCAEventProcess(String adapterGrpName, String adapterName, String sGroupCode, int nLen, byte[] pBuff) {
        try {
            byte[] pDataBuff = new byte[pBuff.length - WCAHeader.WCA_HEADER_LEN];
            byte[] pHeaderBuff = new byte[WCAHeader.WCA_HEADER_LEN];
            
            // 1. 프러퍼티 정보 및 송신 데이타 추출
            System.arraycopy(pBuff, 0, pHeaderBuff, 0, WCAHeader.WCA_HEADER_LEN);
            System.arraycopy(pBuff, WCAHeader.WCA_HEADER_LEN, pDataBuff, 0, pBuff.length - WCAHeader.WCA_HEADER_LEN);
            
            WCAHeader header = new WCAHeader(WCAHeader.WCA_HEADER_LEN, pHeaderBuff);
            
            // 2. 프로퍼티 설정 
            Properties prop = new Properties();
            prop.setProperty(TRAN_KEY, header.getKey());
            prop.setProperty(ADAPTER_GRP_NAME, adapterGrpName);
            prop.setProperty(ADAPTER_NAME, adapterName);
            prop.setProperty(LU_NAME, header.getLUName());
            prop.setProperty(TRAN_MODE, String.valueOf(header.getMode()));
            ClientUtil.getInstance().setDataTypeProperty(header.getDataType(), prop);
            
            // response mode 일고 normal 데이타인경우 ->  DATA TYPE을 timeout으로 설정 
            if (header.getDataType().length() == WCAHeader.LEN_DATA_TYPE && 
            		(String.valueOf(header.getMode()).equals(TRAN_MODE_RESPONSE) || String.valueOf(header.getMode()).equals(TRAN_MODE_TERMINAL)) && 
            		header.getDataType().substring(0,1).equals(DATA_TYPE_NORMAL_PREFIX)) {
                prop.setProperty(DATA_TYPE, DATA_TYPE_TIMEOUT);
            }           
          
            // 20200724 Start
            /*
            if (new String(pDataBuff).indexOf(WCAException.WCA_ERROR_PREFIX) != -1) {
                prop.setProperty(DATA_TYPE, DATA_TYPE_ERROR);   
                
                // 로그 
                String sLogErrCode = new String(pDataBuff).substring(0, WCAException.SOFTLINK_ERROR_SIZE);
                
                String luName = prop.getProperty(LU_NAME, ""); 
                String tranMode = prop.getProperty(TRAN_MODE, "");
                String tranKey = prop.getProperty(TRAN_KEY, "");
                
                ClientUtil.getInstance().insertErrorLog(adapterGrpName, sGroupCode,luName, tranMode, tranKey, sLogErrCode);
            }
            */
            // public static final String 	WCA_ERROR_PREFIX               = "RECEAIOWA";
            if (pDataBuff != null && pDataBuff.length >= 12) {
	            byte[] pRecvErrorPrefix = new byte[9];
	            System.arraycopy(pDataBuff, 0, pRecvErrorPrefix, 0, 9);
	            String strRecvErrorPrefix = new String(pRecvErrorPrefix);
	            
	            if (strRecvErrorPrefix.compareTo(WCAException.WCA_ERROR_PREFIX) == 0) {
	                byte[] pRecvErrorMsg = new byte[12];
	                System.arraycopy(pDataBuff, 0, pRecvErrorMsg, 0, WCAException.SOFTLINK_ERROR_SIZE);
	                String strRecvErrorMsg = new String(pRecvErrorMsg);
	                
	                prop.setProperty(DATA_TYPE, DATA_TYPE_ERROR);
	                
	                String luName = prop.getProperty(LU_NAME, ""); 
	                String tranMode = prop.getProperty(TRAN_MODE, "");
	                String tranKey = prop.getProperty(TRAN_KEY, "");
	                
	                ClientUtil.getInstance().insertErrorLog(adapterGrpName, sGroupCode,luName, tranMode, tranKey, strRecvErrorMsg);                
	            }
            }
            // 20200724 End
            
            // 20200724 Start
            // Debug 모드인 경우에 데이터 로깅 처리로 로그 레벨 변경
            /*
            if (adapter_logger.isInfo()) {
            	adapter_logger.info("WCAEventListener:WCAEventProcess> [" + adapterGrpName + "][" + adapterName  + "] RECV - " + MyUtil.printBytes(WCADefine.EBCDIC_CODE, nLen, pBuff));
            } 
            */           	
            if (adapter_logger.isDebug()) {
            	adapter_logger.debug("WCAEventListener:WCAEventProcess> [" + adapterGrpName + "][" + adapterName  + "] RECV - " + MyUtil.printBytes(WCADefine.EBCDIC_CODE, nLen, pBuff));
            }
            // 20200724 End
            
            if (adapter_logger.isDebug()) {
            	adapter_logger.debug("WCAEventListener:WCAEventProcess> Call RequestDispatcher's Handle Function.");                                                
            }            
            
            // 3. EAI INBOUND 호출
            Object obj = RequestDispatcher.getRequestDispatcher(adapterGrpName).handle(adapterName, pDataBuff, prop);
            
            if (adapter_logger.isDebug()) {
            	adapter_logger.debug("WCAEventListener:WCAEventProcess> Evnet Handler End... + "+obj);                                                
            }            
        }
        catch (Exception e) {
        	adapter_logger.error("WCAEventListener:WCAEventProcess> [" + adapterGrpName + "][" + adapterName  + "] Exception Msg = " + e.getMessage(), e);        	
//            System.out.println("WCAEventProcess] error occures ");
        }
    }
}
