package com.eactive.eai.adapter;

import java.util.HashMap;

import com.eactive.eai.adapter.socket.service.InboundControl;
import com.eactive.eai.batch.doc.BatchDoc;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.inbound.ResponseHandler;

/**
* 1. 기능 : AdapterGroupVO와 AdapterVO 생성
* 2. 처리 개요 :
*     - AdapterGroupVO와 AdapterVO 생성
*     - Adapter.isStatus()를 통해 어뎁터 상태 확인
*     - property에 어뎁터 그룹명, 어뎁터 명, 표준메시지여부, REQUESTACTION class 등록
*     - Processor 클래스의 execute(Object message, Properties prop) 호출
* 3. 주의사항
*
* @author  :
* @version : v 1.0.0
* @see : AdapterGroupVO, AdapterVO
* @since   :
*/
public class RequestDispatcher
{
    /**
     * Default Logger
     */
    static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);

    /**
     * RequestDispatcher HashMap
     */
    private static HashMap<String, RequestDispatcher> dispatchers = new HashMap<String, RequestDispatcher>();

    /**
    * 1. 기능 :  RequestDispatcher HashMap 객체로 부터
    *            요청한 어탭터 그룹의 RequestDispatcher instance 획득
    * 2. 처리 개요 :
    *     - RequestDispatcher HashMap 객체로 부터 요청한 어탭터 그룹의 RequestDispatcher instance 획득
    *     - RequestDispatcher instance가 없으면 생성 한다.
    * 3. 주의사항
    *
    * @param    adapterGroupName    어댑터 그룹명
    * @return   RequestDispatcher instance
    **/
    public static RequestDispatcher getRequestDispatcher(String adapterGroupName) {
        RequestDispatcher dispatcher = dispatchers.get(adapterGroupName);
        if(dispatcher==null) {
           dispatcher = new RequestDispatcher(adapterGroupName);
           dispatchers.put(adapterGroupName, dispatcher);
        }

        return dispatcher;
    }

    /**
     * 어댑터 그룹명
     */
    private String adapterGroupName;

    /**
    * 1. 기능 :  Default Constructor
    * 2. 처리 개요 :
    *     - 어댑터 그룹명 초기화
    *     - ProcessorFactory instance 생성
    * 3. 주의사항
    *
    * @param    adapterGroupName    어댑터 그룹명
    **/
    private RequestDispatcher(String adapterGroupName) {
        this.adapterGroupName = adapterGroupName;
    }


    /**
    * 1. 기능 :  Processor 클래스의 execute(Object message, Properties prop) 호출
    * 2. 처리 개요 :
    *     - 어댑터 프라퍼티를 설정하고 Processor Class의
    *       execute(Object message, Properties prop) method 호출
    *     - 리턴된 메시지 객체를 반환
    * 3. 주의사항
    *
    * @param    adapterName 어댑터명
    * @param    message     요청 메시지
    * @param    prop        어댑터 프라퍼티
    * @return   Object      Processor로 부터 리턴된 message Object
    * @exception    Exception   Adapter가 없거나 액티브 상태가 아닐때, 프라퍼티 설정 오류 시 발생
    **/
    //public BatchDoc handle(InboundControl control) throws Exception {
    public void handle(InboundControl control) throws Exception {

        logger.debug("[ELINK]################ RequestDispatcher.handle() 호출됨.");

        long srtTime = 0;
        srtTime = System.currentTimeMillis();

        String adapterName = control.getAdapterName();
        AdapterManager manager = AdapterManager.getInstance();
        AdapterGroupVO group = manager.getAdapterGroupVO(this.adapterGroupName);
        if(group == null) {
            String code = "BECEAIMAD042";
            String[] msgArgs = new String[2];
            msgArgs[0] = adapterGroupName;
            msgArgs[1] = adapterName;
            String errText = ExceptionUtil.make(code, msgArgs);
            if (logger.isError()) logger.error(errText);
            throw new Exception(errText);
        }

        AdapterVO adapter = group.getAdapterVO(adapterName);
        if(adapter==null) {
            String code = "BECEAIMAD022";
            String[] msgArgs = new String[3];
            msgArgs[0] = adapterGroupName;
            msgArgs[1] = adapterName;
            msgArgs[2] = group.toString();
            String errText = ExceptionUtil.make(code, msgArgs);
            if (logger.isError()) logger.error(errText);
            throw new Exception(errText);
        }


        if(!adapter.isStatus()) {
            String code = "BECEAIMAD023";
            String[] msgArgs = new String[1];
            msgArgs[0] = adapter.toString();
            String errText = ExceptionUtil.make(code, msgArgs);
            if (logger.isError()) logger.error(errText);
            throw new Exception(errText);
        }

        //BatchDoc batchMsgDoc = null;
        try {
            group.increase();
            ResponseHandler handler = new ResponseHandler();
            BatchDoc batchMsgDoc = handler.execute(control.getBatchMsgDoc());
            control.setBatchMsgDoc(batchMsgDoc);
            ////batchMsgDoc = handler.execute(control.getBatchMsgDoc());

        } catch(Exception e) {
            throw new Exception(ExceptionUtil.getErrorCode(e, "BECEAIMAD025"));
        } finally {
            group.decrease();
        }

		logger.debug("[ELINK]################ RequestDispatcher.handle() 종료. (수행 시간: "+ ((System.currentTimeMillis() - srtTime)/1000.0) +" Sec)");
		//return batchMsgDoc;
    }
}
