package com.eactive.eai.adapter.sna; 

import com.eactive.eai.adapter.wca.exception.WCAException;
import com.eactive.eai.adapter.wca.global.WCADefine;
import com.eactive.eai.adapter.wca.util.RuntimeUtil;
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. 기능 : Softlink 및 SNAAdpaterManager(WCA) 관리
* 2. 처리 개요 : 
*          - start 할 경우 
*               1. Softman에게 명령어를 전송하여 Softlink 구동한다.
*               2. SNAAdpaterManager(WCA) instance 생성한다.
*                  (DB에서 SNA Adapter 정보를 메모리에 로딩 관리한다.)
*          - stop 할 경우 
*               1. Softman에게 명령어를 전송하여 Softlink 종료한다. -> 제거
* 3. 주의사항 
*          - EAI 로딩 우선순위가 AdapterManager 보다 먼저 로딩되어야 한다.
*
* @author  : 
* @version : v 1.0.0
* @see : 
* @since   : 
*/
public class SNAAdapterManager implements Lifecycle
{
    /**
     * SNAAdapterManager Single Instance
     */
    private static SNAAdapterManager instance =  new SNAAdapterManager();
    
    /**
     * LifeccyleSupport object
     */
    private LifecycleSupport lifecycle = new LifecycleSupport(this);

    /**
     * 기동 여부
     */
	private boolean started;
    /**
     * SNAAdapter critical한 정보 로깅을 위한 logger 
     */
    Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME);
    
    /**
     * softman 구동중
     */
    String SOFTMAN_RUNNING_MSG = "SoftMan is Already Running";
    
    /** 
    * 1. 기능 :  Default Constructor
    * 2. 처리 개요 : 
    * 3. 주의사항 
    **/
    private SNAAdapterManager() {
    }
    
    /** 
    * 1. 기능 :  SNAAdapterManager Singleton Object를 반환하는 getter method
    * 2. 처리 개요 : SNAAdapterManager Singleton Object를 반환한다.
    * 3. 주의사항 
    *
    * @return   SNAAdapterManager Singleton object
    **/
    public static SNAAdapterManager getInstance() {
        return instance;   
    }
    
    /** 
    * 1. 기능 :  Lifecycle의 start 메서드로 SNAAdapterManager 초기화하는 메서드
    * 2. 처리 개요 : 
    * 3. 주의사항 
    *
    * @exception    LifecycleException  이미 시작되었을 경우(RECEAICBM201)
    * 
    **/
    public void start() throws LifecycleException {
        if (started)
            throw new LifecycleException("RECEAIASA001");

        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(STARTING_EVENT, this);
                
        // Softlink 구동
        try {
            RuntimeUtil.getInstance().startSoftlink();
        }catch(WCAException e){
            String errMsg = e.toString();
            // 이미 구동중일 경우
            if (errMsg.indexOf(SOFTMAN_RUNNING_MSG) != -1){
                if(adapter_logger.isInfo()){
                    adapter_logger.info(errMsg);
                }
            }
            else 
                throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAIASA002"));
        }
        // SNAAdapter (WCA) Manager instance 생성
//        SNAAdapterManager smanager = SNAAdapterManager.getInstance();
        
        started = true;
        
        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(STARTED_EVENT, this);
    }
    
    /** 
    * 1. 기능 :  Lifecycle의 stop 메서드로 SNAAdapterManager를 종료하는 메서드
    * 2. 처리 개요 : 
    * 3. 주의사항 
    *
    * @exception    LifecycleException  이미 종료된 경우 발생(RECEAICBM203)
    **/
    public void stop() throws LifecycleException {
        // Validate and update our current component state
        if (!started)
            throw new LifecycleException("RECEAIASA003");
		
        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(STOPING_EVENT, this);
        
        // Softlink 종료 --> 제거
        /*
        try {
            RuntimeUtil.getInstance().stopSoftlink();
        }catch(WCAException e){
            throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAIASA004"));
        }        
        */
        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. 기능 :  SNAAdapterManager를 초기화 여부를 반환하는 getter 메서드
    * 2. 처리 개요 : SNAAdapterManager를 초기화 여부를 반환한다.
    * 3. 주의사항 
    *
    * @return   초기화 여부
    **/
    public boolean isStarted() {
        return this.started;   
    }
} 
