package com.eactive.eai.batch.rule.phaseinfo;

import java.util.ArrayList;
import java.util.HashMap;


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;

/**
 * PhaseInfo 관련한 DB Table " + Keys.TABLE_OWNER + "tseaibr02 조회를 위한 모든 함수를 정의하는 클래스
 */
public class PhaseInfoManager implements Lifecycle
{

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

    /**
     * TelegramInfoManager Single Instance
     */
    private static PhaseInfoManager instance = new PhaseInfoManager();

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

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

    /**
     * 전문 정보를 저장하는 collection
     */
    private HashMap<String, ArrayList<PhaseInfoVO>> phaseInfos;

    /**
    * 1. 기능 :  Default Constructor
    * 2. 처리 개요 : 전문(Telegram) 정보를 저장하기 위한 HashMap을 초기화한다.
    * 3. 주의사항
    *
    **/
    private PhaseInfoManager() {
    	phaseInfos = new HashMap<String, ArrayList<PhaseInfoVO>>();

    }

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

        return instance;
    }

    public synchronized void setRuleCodeArray(String strRuleCode, ArrayList<PhaseInfoVO> al) throws Exception
    {
        this.phaseInfos.put(strRuleCode, al);
    }

    public synchronized void removeRuleCodeArray(String strRuleCode) throws Exception
    {
        this.phaseInfos.remove(strRuleCode);
    }

    /**
     * Telegram Mapping 정보 조회 : --> 텔레그램 클래스, 메시지 메타코드
     */
    public ArrayList<PhaseInfoVO> getPhaseInfo(String strRuleCode, String strCurrPhaseCode) throws Exception
    {
        ArrayList<PhaseInfoVO>   al = new ArrayList<PhaseInfoVO>();
        ArrayList<PhaseInfoVO>   al_target = new ArrayList<PhaseInfoVO>();

        al = this.phaseInfos.get(strRuleCode);
        if (al != null) {
            for (int i=0; i<al.size(); i++) {
                PhaseInfoVO  vo = (PhaseInfoVO) al.get(i);
                if (vo.getPhaseCode().trim().equalsIgnoreCase(strCurrPhaseCode.trim())) {
                    al_target.add(vo);
                }
            }
        }

        return al_target;
    }

    public HashMap<String, ArrayList<PhaseInfoVO>> getAllData() throws Exception
    {
        return this.phaseInfos;
    }

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

    /**
    * 1. 기능 :  Lifecycle의 start 메서드로 TelegramManager를 초기화하는 메서드
    * 2. 처리 개요 : TelegramDAO를 이용해 추출 전문 정보 모두를 가져와 초기화한다.
    * 3. 주의사항
    *
    * @exception    LifecycleException  이미 시작되었거나,
    *               EAIServerDAO를 통해 Rule 정보를 가져온다.
    *               DAOExcepiton이 발생될 경우
    **/
    public void start() throws LifecycleException
    {
        if (started)
            throw new LifecycleException("BECEAIMFR025");

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

        DAOFactory daoFactory = DAOFactory.newInstance();
        PhaseInfoDAO dao = null;
        try {
            dao = (PhaseInfoDAO)daoFactory.create(PhaseInfoDAO.class);
            this.phaseInfos = dao.getAllPhaseInfos();
            logger.info("[PhaseInfoManager] : phase information loaded >> " + this.phaseInfos.size());

            Object[] objs = this.phaseInfos.keySet().toArray();
            for(int i=0; i<objs.length; i++)
            {
            	ArrayList<PhaseInfoVO>   arr = this.phaseInfos.get((String)objs[i]);
                if (arr!=null) {
                    for (int z=0; z<arr.size(); z++) {
                        PhaseInfoVO vo = (PhaseInfoVO) arr.get(z);
                        if (z==0) {
                            logger.debug("RULE >> phase changing rule : " + vo.getRuleCode());
                        }
                        logger.debug("  - ["+vo.getRuleCode()+"] ["+vo.getPhaseCode()+"] ["+vo.getTelegramType()+"] ["+vo.getConditionTxt()+"] ["+vo.getCTelegramType()+"] ["+vo.getNextPhaseCode()+"]");
                    }
                }
            }
        } catch(DAOException e) {
            throw new LifecycleException(ExceptionUtil.getErrorCode(e,"BECEAIMFR026"));
        }

        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("BECEAIMFR027");

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

        this.phaseInfos.clear();

        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;
    }
}