package com.eactive.eai.agent.adapter.socket;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.eactive.eai.adapter.AdapterGroupVO;
import com.eactive.eai.adapter.AdapterManager;
import com.eactive.eai.adapter.AdapterVO;
import com.eactive.eai.adapter.socket.config.SocketAdapterManager;
import com.eactive.eai.agent.command.Command;
import com.eactive.eai.agent.command.CommandException;
import com.eactive.eai.batch.osd.OutsideManager;
import com.eactive.eai.batch.osd.OutsideVO;
import com.eactive.eai.common.util.Logger;

/**
* 1. 기능 : Running중인 EAI Server의 메모리에 로딩된 CodeMessageManager의 정보 변경
* 2. 처리 개요 : CodeMessageManager에 CodeMessageVO추가
* 3. 주의사항
*
* @author
* @version  v 1.0.0
* @see  관련 기능을 참조
* @since
*/
public class SocketServerCommand extends Command
{
    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
    /**
    * 1. 기능 :  SelectSocketServerCommand 생성자
    * 2. 처리 개요 :
    * 3. 주의사항
    *
    **/
    public SocketServerCommand(String name) {
        super(name);
    }

    /**
    * 1. 기능 :  ServerSocket 정보를 가지고옮
    * 2. 처리 개요 : ServerSocket 정보를 가지고옮
    * 3. 주의사항
    *
    * @exception CommandException	Argument Type이 다르거나 Command 수행중 Excpetion이 발생할 경우
    **/
    public Object execute() throws CommandException
    {
        logger.info(this.name + " Agent 가 호출되었습니다.");

        try {

        	List<Map<String,Serializable>> ls = getSocketServerAdapterInfo();

			logger.info(this.name + " Agent 가 성공적으로 완료되었습니다.");
            return ls;

        } catch (Exception ex) {
            String msg = makeException("BECEAICAG002", ex);
            logger.error(msg, ex);
            throw new CommandException(msg);
        }
    }


	private List<Map<String,Serializable>> getSocketServerAdapterInfo() throws Exception {

		try {
			//리턴 ArrayList 생성
			List<Map<String,Serializable>> retList = new ArrayList<Map<String,Serializable>>();

			//메모리의 전체 AdapterGroup 객체 조회
			HashMap<String, AdapterGroupVO> allAdapterGroupMap = AdapterManager.getInstance().getAllAdapterGroupVO();

			//AdapterGroup 이 없으면
			if (allAdapterGroupMap == null || allAdapterGroupMap.size() == 0) {
				return retList;
			}

			//AdapterGroup 명으로 정렬
			Object[] adapterGroupNames = allAdapterGroupMap.keySet().toArray();
			Arrays.sort(adapterGroupNames);

			//===================================================================================
			//AdapterGroup 별 LOOP
			for (int i=0; i<adapterGroupNames.length; i++) {
				AdapterGroupVO gvo = allAdapterGroupMap.get(adapterGroupNames[i]);
				String adapterGroupName = gvo.getName();
				String processCode      = gvo.getBatchProcessCode();
				String organCode        = gvo.getBatchInstitutionCode();
				OutsideVO ovo = OutsideManager.getInstance().getOutsideInfo(processCode, organCode);
				String processName = ovo.getBatchName();
				String organName   = ovo.getOsdName(); 

				//해당 AdapterGroup의 전체 Adapter 객체 조회
				HashMap<String,AdapterVO> allAdapterMap = gvo.getAllAdapters();

				//Adapter 가 없으면 디폴트 값 설정
				if (allAdapterMap ==  null || allAdapterMap.size() == 0) {
					Map<String, Serializable> map = new HashMap<String, Serializable>();
					map.put("adptrBzwkGroupName", adapterGroupName);
					map.put("bjobBzwkDstcd"     , processCode     );
					map.put("processName"     , processName     );
					map.put("organName"     , organName     );
					map.put("osidInstiDstCd"    , organCode       );
					map.put("adptrBzwkName"     , "No Adapters"   );
					map.put("ip"                , ""              );
					map.put("port"              , ""              );
					map.put("maxConnectioncount", 0               );
					map.put("curConnectioncount", 0               );
					map.put("status"            , "N/A"           );
					retList.add(map);
					continue;
				}

				//Adapter 명으로 정렬
				Object[] adapterNames = allAdapterMap.keySet().toArray();
				Arrays.sort(adapterNames);

				//-------------------------------------------------------------------
				//Adapter 별 LOOP
				for (int k=0; k<adapterNames.length; k++) {
					AdapterVO avo = (AdapterVO) allAdapterMap.get(adapterNames[k]);
					String adapterName      = avo.getName();
					int    maxConnCnt       = avo.getContext().getMaxConnection();
					int    curConnCnt       = SocketAdapterManager.getInstance().getSocketServiceCount(adapterGroupName, adapterName);
					boolean isActive        = avo.isStarted();

					Map<String, Serializable> map = new HashMap<String, Serializable>();
					map.put("adptrBzwkGroupName", adapterGroupName          );
					map.put("bjobBzwkDstcd"     , processCode               );
					map.put("processName"     , processName     );
					map.put("organName"     , organName     );
					map.put("osidInstiDstCd"    , organCode                 );
					map.put("adptrBzwkName"     , adapterName               );
					map.put("ip"                , avo.getBatchServerIP()    );
					map.put("port"              , avo.getBatchServerPortNo());
					map.put("maxConnectioncount", maxConnCnt                );
					map.put("curConnectioncount", curConnCnt                );
					map.put("status"            , isActive? "기동중" : "중지"   );
					retList.add(map);
				}
			}
			return retList;
			
		}catch (Exception ex) {
			ex.printStackTrace();
			return null;
		}
	}
}