package com.eactive.eai.batch.flowController;

import java.util.HashMap;
import java.util.Iterator;

import com.eactive.eai.agent.AgentUtil;
import com.eactive.eai.agent.command.Command;
import com.eactive.eai.agent.flowController.UpdateBatchTargetCommand;
import com.eactive.eai.common.dao.DAOException;
import com.eactive.eai.common.dao.DAOFactory;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.lifecycle.Lifecycle;
import com.eactive.eai.common.lifecycle.LifecycleException;
import com.eactive.eai.common.lifecycle.LifecycleListener;
import com.eactive.eai.common.lifecycle.LifecycleSupport;
import com.eactive.eai.common.util.Logger;

/**
* 1. 기능 : Flow Controller에서 사용하는 메소드들의 모임
* 2. 처리 개요 : 대부분의 값은 메모리에 로딩하지 않는 것으로 한다.
* 3. 주의사항
*
* @author  : YCLee  2006/1/11
* @version : v 1.0.0
* @see : 관련 기능을 참조
* @since   :
*/
public class FlowControllerManager implements Lifecycle
{

	//파일로거
	private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);

	/**
     * EAIServerManager Single Instance
     */
    private static FlowControllerManager instance = new FlowControllerManager();

    /**
     * LifeccyleSupport object
     */
    private LifecycleSupport lifecycle = new LifecycleSupport(this);

    /**
     * 기동 여부
     */
    private boolean started;

    /**
     * BatchTargetVO들을 저장하는 HashMap
     */
    private HashMap<String, BatchTargetVO> targets;

    /**
    * 1. 기능 :  Default Constructor
    * 2. 처리 개요 : Flow Rule 정보를 저장하기 위한 HashMap을 초기화한다.
    * 3. 주의사항
    *
    **/
    private FlowControllerManager() {
    	targets = new HashMap<String, BatchTargetVO>();
    }

    /**
    * 1. 기능 :  FlowControllerManager Singleton Object를 반환하는 getter method
    * 2. 처리 개요 : FlowControllerManager Singleton Object를 반환한다.
    * 3. 주의사항
    *
    * @return   FlowControllerManager Singleton object
    **/
    public static FlowControllerManager getInstance() {
        return instance;
    }

    /* ****************************************************************** */
    /*           FlowControllerManager 자체적인 메소드 정의               */
    /* ****************************************************************** */

    /**
     * 1. 기능 : 요구 송수신에서 사용할 대외기관의 연결 정보를 반환한다.
     * 2. 처리 개요 :
     *
     * 3. 주의사항
     *
     * @return   XML을 담고 있는 String 객체 반환
     * @exception
     **/
    public DemandTargetVO[] getRemoteHostInfo(String processCode, String organCode)
    {
        if((BatchTargetVO)targets.get(processCode + organCode) == null)
            return null;
        else
            return ((BatchTargetVO)targets.get(processCode + organCode)).getDemadnTargets();
    }

    public BatchTargetVO getBatchTargetInfo(String processCode, String organCode)
    {
        return (BatchTargetVO)targets.get(processCode + organCode);
    }

    public HashMap<String, BatchTargetVO> getTargets()
    {
        return targets;
    }

    /**
     * 1.기능: F/C에서 요청 처리중 운영자에 의해서 해당 건이 취소되었는지를 확인하는 메소드
     */
    public boolean getStatusCode(String uuid) throws Exception
    {
		FlowControllerDAO dao = (FlowControllerDAO)DAOFactory.newInstance().create(FlowControllerDAO.class);

		//반환값이 C(사용자취소)인 경우만 false로 반환한다.
		if (dao.getStatusCode(uuid).equals("C"))
			return false;
		else
			return true;
    }


    /* ****************************************************************** */
    /*                  Lifecycle 인터페이스에 정의된 메소드              */
    /* ****************************************************************** */

    /**
    * 1. 기능 :  Lifecycle의 start 메서드로 FlowControllerManager 초기화하는 메서드
    * 2. 처리 개요 : FlowControllerDAO를 이용해 대상 기관의 정보 모두를 가져와 초기화한다.
    * 3. 주의사항
    *
    * @exception    LifecycleException  이미 시작되었거나,
    *               DAOExcepiton이 발생될 경우
    **/
    public void start() throws LifecycleException
    {
        if (started) throw new LifecycleException("BECEAIMFC010");	//FlowControllerManager 가 이미 시작되었습니다.

        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(STARTING_EVENT, this);

        try {
            FlowControllerDAO dao = (FlowControllerDAO)DAOFactory.newInstance().create(FlowControllerDAO.class);
            this.targets = dao.getAllTargets();

		} catch (DAOException e) {
			String errMsg = ExceptionUtil.getErrorCode(e, "BECEAIMFC011");
			throw new LifecycleException(errMsg);	//Lifecycle 에서 FlowControllerManager 시작 시 (대외기관 별 연결정보 로딩) 오류가 발생하였습니다.
        }

        started = true;

        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(STARTED_EVENT, this);
    }

    /**
    * 1. 기능 :  Lifecycle의 stop 메서드로 EAIServerManager를 종료하는 메서드
    * 2. 처리 개요 : 멤버에 캐싱항 EAIServer Rule 정보를 clear한다.
    * 3. 주의사항
    *
    * @exception    LifecycleException  이미 종료된 경우 발생
    **/
    public void stop() throws LifecycleException {
        // Validate and update our current component state
        if (!started)
            throw new LifecycleException("BECEAIMFC012");   //FlowControllerManager 가 이미 종료되었습니다.

        this.targets.clear();
        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(STOPING_EVENT, this);

        started = false;
        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(STOPPED_EVENT, this);
    }

    /**
    * 1. 기능 :  LifecycleListener를 등록하는 메서드
    * 2. 처리 개요 : LifecycleListener를 등록한다.
    * 3. 주의사항
    *
    * @param    listener    LifecycleEvent를 수신한 LifecycleListener
    **/
    public void addLifecycleListener(LifecycleListener listener)
    {
        lifecycle.addLifecycleListener(listener);
    }

    /**
    * 1. 기능 :  등록된 LifecycleListener 리스트를 반환하는 메서드
    * 2. 처리 개요 : 등록된 LifecycleListener 리스트를 반환하다.
    * 3. 주의사항
    *
    * @return   등록된 LifecycleListener 리스트
    **/
    public LifecycleListener[] findLifecycleListeners()
    {
        return lifecycle.findLifecycleListeners();
    }

    /**
    * 1. 기능 :  등록된 LifecycleListener를 삭제하는 메서드
    * 2. 처리 개요 : 파라미터의 LifecycleListener를 삭제한다.
    * 3. 주의사항
    *
    * @param    listener    삭제할 LifecycleListener
    **/
    public void removeLifecycleListener(LifecycleListener listener)
    {
        lifecycle.removeLifecycleListener(listener);
    }

    /**
    * 1. 기능 :  FlowRuleManager의 초기화 여부를 반환하는 getter 메서드
    * 2. 처리 개요 : FlowRuleManager의 초기화 여부를 반환한다.
    * 3. 주의사항
    *
    * @return   초기화 여부
    **/
    public boolean isStarted() {
        return this.started;
    }

	public int updateSystemConnLineStatus(String processCode, String organCode, String lineStatus) throws Exception {
		logger.debug("▣▣▣▣▣ ==================================================================================");
		logger.debug("▣▣▣▣▣ ★ 응답수신 '회선 "+ (lineStatus.equals(DemandTargetVO.ORGAN_SOCKET_STATUS_NORNAL)? "장애회복" : "장애") +" 통보 전문' 처리 Start......");
		logger.debug("▣▣▣▣▣    - 업무구분코드 : ["+ processCode     +"]");
		logger.debug("▣▣▣▣▣    - 대외기관코드 : ["+ organCode       +"]");

		logger.debug("▣▣▣▣▣ ① 해당 대외기관의 전체 연결정보 DB Update......");
		FlowControllerDAO dao = (FlowControllerDAO)DAOFactory.newInstance().create(FlowControllerDAO.class);
		int resultCnt = dao.updateSystemConnLineStatus(processCode, organCode, lineStatus);

		logger.debug("▣▣▣▣▣ ② Agent를 통한 모든 서버의 연결정보 HashMap Update......");
		Command command = new UpdateBatchTargetCommand();
		String[] args = new String[] {processCode, organCode, lineStatus};
		command.setArgs(args);
		HashMap<String, Object> map = AgentUtil.broadcast(command);

		Iterator<String> it = map.keySet().iterator();
		while (it.hasNext()) {
			String svrName   = it.next();
			String resultStr = (String) map.get(svrName);
			logger.debug("▣▣▣▣▣   - '"+ svrName +"' 서버 호출 결과: "+ resultStr);
		}
		logger.debug("▣▣▣▣▣ ==================================================================================");

		return resultCnt;
	}

}

