package com.eactive.eai.batch.code;

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

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;

/**
* 1. 기능 : 코드, 텍스트 Rule 정보를 DB로 부터 로딩해 메모리에 관리하는 Manager 클래스
* 2. 처리 개요 : DB Rule 정보에 저장된코드, 텍스트 Rule  정보를 메모리에 로딩 관리한다.
* *     -
* 3. 주의사항
*/
public class CodeMessageManager implements Lifecycle
{
    /**
     * CodeMessageManager Singleton Instance
     */
    private static CodeMessageManager instance = new CodeMessageManager();

    /**
     * CodeMessage Rule 정보를 저장하기 위한 HashMap
     */
     private HashMap<String, CodeMessageVO> messages;

    /**
     * LifeccyleSupport object
     */
    private LifecycleSupport lifecycle = new LifecycleSupport(this);
	/**
     * 기동 여부
     */
	private boolean started;

    /**
    * 1. 기능 :  Default Constructor
    * 2. 처리 개요 : messages를 저장하기 위한 HashMap을 초기화한다.
    *     -
    * 3. 주의사항
    *
    **/
    private CodeMessageManager() {
    	messages = new HashMap<String, CodeMessageVO>();
    }

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

    /**
    * 1. 기능 :  Lifecycle의 start 메서드로 CodeMessageManager를 초기화하는 메서드
    * 2. 처리 개요 : CodeMessageDAO를 이용해 추출 Rule 정보 모두를 가져와 초기화한다.
    *     -
    * 3. 주의사항
    *
    * @exception    LifecycleException
    **/
    public void start() throws LifecycleException {
        if (started)
            throw new LifecycleException("BECEAIMCD201");

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

        messages = null;

        CodeMessageDAO dao = null;
        try {
            dao = (CodeMessageDAO)DAOFactory.newInstance().create(CodeMessageDAO.class);
            messages = dao.getAllMessages();
        } catch(DAOException e) {
            throw new LifecycleException(ExceptionUtil.getErrorCode(e, "BECEAIMCD202"));
        }

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

    /**
    * 1. 기능 :  Lifecycle의 stop 메서드로 CodeMessageManager를 종료하는 메서드
    * 2. 처리 개요 : 멤버에 캐싱항 코드, 텍스트 Rule 정보를 clear한다.
    *     -
    * 3. 주의사항
    *
    * @exception    LifecycleException
    **/
    public void stop() throws LifecycleException {
        // Validate and update our current component state
        if (!started)
            throw new LifecycleException("BECEAIMCD203");

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

        messages.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. 기능 :  BizKeyManager의 초기화 여부를 반환하는 getter 메서드
    * 2. 처리 개요 : BizKeyManager의 초기화 여부를 반환한다.
    * 3. 주의사항
    *
    * @return   초기화 여부
    **/
    public boolean isStarted() {
        return this.started;
    }

    /**
    * 1. 기능 :  코드에 대한 메시지 텍스트를 반환하는 메서드
    * 2. 처리 개요 : 파라미터 코드에 대한 메시지 텍스트를 찾아 반환한다.
    *     -
    * 3. 주의사항
    *
    * @param    code    메시지 코드
    * @return   메시지 텍스트
    **/
    public String getMessage(String code) {
        if(code==null) return null;
        //String msg = (String)messages.get(code);

        if (messages == null || messages.size() == 0) {
            CodeMessageDAO dao = null;
            try {
                dao = (CodeMessageDAO)DAOFactory.newInstance().create(CodeMessageDAO.class);
                CodeMessageVO codeInfo = dao.getOneCodeMessage(code);
                if (codeInfo==null) return "UNDEFINE";

				String msg = codeInfo.getMsgTxt();
                return (msg==null) ? "UNDEFINE" : msg;
            } catch(DAOException e) {
                return "The CodeMessage["+code+"] is not defiend.";
            }
        } else {
            CodeMessageVO vo = (CodeMessageVO)messages.get(code);
            if(vo==null) return "The CodeMessage["+code+"] is not defiend.";
            String msg = vo.getMsgTxt();
            return (msg==null) ? "UNDEFINE" : msg;
        }
    }

    /**
    * 1. 기능 :  코드에 대한 메시지 내용과 조치사항내용을 반환하는 메서드
    * 2. 처리 개요 : 파라미터 코드에 대한 메시지 내용과 조치사항내용을 찾아 반환한다.
    *     -
    * 3. 주의사항
    *
    * @param    code    메시지 코드
    * @return   메시지 Value Object
    **/

    public CodeMessageVO getMessageVO(String code) {
        if(code==null) return null;

        CodeMessageVO cmv = null;
        if (messages == null || messages.size() == 0) {
            CodeMessageDAO dao = null;
            try {
                dao = (CodeMessageDAO)DAOFactory.newInstance().create(CodeMessageDAO.class);
                cmv = dao.getOneCodeMessage(code);
            } catch(DAOException e) {
                cmv = null;
            }
        } else {
            cmv = (CodeMessageVO)messages.get( code );
        }
        return cmv;
    }


    /**
    * 1. 기능 :  메시지, 메시지 내용, 조치사항내용을 저장/변경하는 메서드
    * 2. 처리 개요 : 메시지에 대한 텍스트를 변경하거나 저장한다.
    *     -
    * 3. 주의사항
    *
    * @param    code     메시지 코드
    * @param    msg     메시지 텍스트
    **/

    public void setMessage(CodeMessageVO cmm) {
        messages.put(cmm.getMsgKey(), cmm);
    }

    /**
    * 1. 기능 :  코드 메시지 Rule 정보를 삭제하는 메서드.
    * 2. 처리 개요 : 파라미터의 메시지 코드에 대한 Rule 정보를 삭제한다.
    *     -
    * 3. 주의사항
    *
    * @param    code     메시지 코드
    **/
    public void removeMessage(String code) {
        messages.remove(code);
    }

    /**
    * 1. 기능 :  코드 리스트를 반환하는 메서드
    * 2. 처리 개요 : 코드 리스트를 반환한다.
    *     -
    * 3. 주의사항
    *
    * @return   코드 리스트
    **/
    public String[] getAllCodes() {
        String[] codes = new String[messages.size()];
        Iterator<String> it = messages.keySet().iterator();
        for(int i=0;it.hasNext();i++) {
            codes[i] = it.next();
        }
        return codes;
    }

    /**
    * 1. 기능 :  전체 코드메시지 리스트를 Properties 로 반환하는 메서드
    * 2. 처리 개요 : 전체 코드메시지 리스틀 Properties로 반환한다.
    *     -
    * 3. 주의사항
    *
    * @return   전체 코드 메시지 리스트를 저장하고 있는 Properties
    **/
    public HashMap<String, CodeMessageVO> getAllCodeMessages() {
        return this.messages;
    }

    public synchronized void reload(String key) throws Exception {
        CodeMessageDAO dao  = (CodeMessageDAO)DAOFactory.newInstance().create(CodeMessageDAO.class);
        CodeMessageVO vo = dao.getOneCodeMessage(key);
        if(vo != null) {
        	this.messages.put(key, vo);
        }
        else {
        	throw new Exception("CodeMessageManager not found in Database : key["+key+"]");
        }
    }      

}
