package com.eactive.eai.common.server;

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 java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;

/**
* 1. 기능 : EAI서버 Rule 정보를 DB로 부터 로딩해 메모리에 관리하는 Manager 클래스
* 2. 처리 개요 : DB Rule 정보에 저장된 필드 추출 Rule 정보를 메모리에 로딩 관리한다.
* 3. 주의사항
*
* @author  :
* @version : v 1.0.0
* @see : 관련 기능을 참조
* @since   :
*/
public class EAIServerManager implements Lifecycle
{
	/**
     * EAIServerManager Single Instance
     */
    private static EAIServerManager instance = new EAIServerManager();

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

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

    /**
     * EAIServer Rule 정보를 저장하는 collection
     */
    private HashMap<String, EAIServerVO> servers;

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

    }

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

        return instance;
    }


    public String getLocalServerName() {
        String svrName = System.getProperty(Keys.WLI_SERVER_KEY);
        return svrName;
    }

    /**
     * 1. 기능 : Manager가 동작하고 있는 서버의 HostName을 얻어내는 메소드
     * 2. 처리 개요 :
     *     - InetAddress를 통해 조회
     * 3. 주의사항
     *
     * @exception UnknownHostException
     **/
	public String getLocalServerHostName() throws java.net.UnknownHostException{

        String hostname = java.net.InetAddress.getLocalHost().getHostName();
        return hostname;
    }

    public EAIServerVO getLocalServer() {
        return null;
    }

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

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

        DAOFactory daoFactory = DAOFactory.newInstance();
        EAIServerDAO dao = null;
        try {
            dao = (EAIServerDAO)daoFactory.create(EAIServerDAO.class);
            this.servers = dao.getAllServers();
        } catch(DAOException e) {
            throw new LifecycleException(ExceptionUtil.getErrorCode(e,"BECEAIMSV202"));
        }

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

        // 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. 기능 :  EAIServer Rule 정보를 찾아 반환하는 메서드
    * 2. 처리 개요 : 파리미터의 이름에 대한 EAIServer Rule 정보를 찾아 반환한다.
    * 3. 주의사항
    *
    * @param    name    EAIServer Rule 정보를 관리하는 key 값(EAIServer 명)
    * @return   EAIServer Rule 정보
    **/
    public EAIServerVO getEAIServer(String name) {
        return (EAIServerVO)this.servers.get(name);
    }

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

    /**
    * 1. 기능 :  EAIServer Rule 정보를 저장하는 메서드
    * 2. 처리 개요 : 파라미터의 EAIServer Rule 정보를 멤버에 저장한다.
    * 3. 주의사항
    *
    * @param    vo    EAIServerVO
    **/
    public void addEAIServer(EAIServerVO vo) {
        this.servers.put(vo.getName(),vo);
    }

    /**
     * 1. 기능 : EAIServer Rule 정보를 삭제하는 메서드
     * 2. 처리 개요 :
     *     - 파라미터의 EAIServer 명의 Rule 정보를 멤버에서 삭제한다.
     * 3. 주의사항
     *
     * @param name EAIServer명
     * @exception
     **/
    public void removeEAIServer(String name) {
        this.servers.remove(name);
    }

    /**
     * 1. 기능 :  EAIServer Rule 정보를 수정하는 메서드
     * 2. 처리 개요 :
     *     - 파라미터의 EAIServerVO의 Rule 정보를 멤버에서 수정한다.
     * 3. 주의사항
     *
     * @param EAIServerVO
     * @exception
     **/
    public void setEAIServer(EAIServerVO vo) {
        this.servers.put(vo.getName(),vo);
    }

    /**
     * 1. 기능 : Rule에 저장된 EAIServerVO 리스트를 얻어내는 메소드
     * 2. 처리 개요 :
     *     - Rule에 저장된 EAIServerVO 리스트를 얻어낸다.
     * 3. 주의사항
     *
     * @return HashMap Manager의 Rule에 저장된 EAIServerVO 리스트
     * @exception
     **/
    public HashMap<String, EAIServerVO> getAllServer(){
        return this.servers;
    }

    /**
     * 1. 기능 : Rule에 저장된 EAIServerVO의 EAIServer명 리스트를 얻어내는 메소드
     * 2. 처리 개요 :
     *     - Rule에 저장된 EAIServerVO의 EAIServer명 리스트를 얻어낸다.
     * 3. 주의사항
     *
     * @return String[] Manager의 Rule에 저장된 EAIServerVO의 EAIServer명 리스트
     * @exception
     **/
    public String[] getAllEaiSvrInstNm(){
        Iterator<String> it = this.servers.keySet().iterator();

        String[] eaiIns = new String[this.servers.size()];
        for(int i = 0; it.hasNext(); i++){
            eaiIns[i] = it.next();
        }
        Arrays.sort(eaiIns);
        return eaiIns;
    }

    /**
     * 1. 기능 : 현 EAI 서버가 운영(Prod) 환경인지 여부를 반환하는 메서드
     * 2. 처리 개요 :
     *     - 현 EAI 서버가 운영(Prod) 환경인지 여부를 반환한다.
     * 3. 주의사항
     *
     * @return 현 EAI 서버가 운영(Prod) 환경인지 여부
     **/
    public boolean isPEAIServer() {

    	String SysOperEvirnDstcd = System.getProperty(Keys.EAI_SYSTEMMODE);
        if(SysOperEvirnDstcd ==null || SysOperEvirnDstcd.equals(Keys.EAI_PRODUCT)) {
        	return true;
        }
        else {
        	return false;
        }

    }

    /**
     * 1. 기능 : 현 EAI 서버가 개발(Dev) 환경인지 여부를 반환하는 메서드
     * 2. 처리 개요 :
     *     - 현 EAI 서버가 개발(Dev) 환경인지 여부를 반환한다.
     * 3. 주의사항
     *
     * @return 현 EAI 서버가 개발(Dev) 환경인지 여부
     **/
    public boolean isDEAIServer() {
    	String SysOperEvirnDstcd = System.getProperty(Keys.EAI_SYSTEMMODE);
        if( SysOperEvirnDstcd.equals(Keys.EAI_DEVELOP)) {
        	return true;
        }
        else {
        	return false;
        }

    }

    /**
     * 1. 기능 : 현 EAI 서버가 테스트(Test) 환경인지 여부를 반환하는 메서드
     * 2. 처리 개요 :
     *     - 현 EAI 서버가 테스트(Test) 환경인지 여부를 반환한다.
     * 3. 주의사항
     *
     * @return 현 EAI 서버가 테스트(Test) 환경인지 여부
     **/
    public boolean isTEAIServer() {
    	String SysOperEvirnDstcd = System.getProperty(Keys.EAI_SYSTEMMODE);
        if( SysOperEvirnDstcd.equals(Keys.EAI_TEST)) {
        	return true;
        }
        else {
        	return false;
        }

    }
}

