package com.eactive.eai.rms.onl.adapter.sna;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.eactive.eai.rms.common.context.MonitoringContext;
import com.eactive.eai.rms.onl.adapter.AgentExecCommand;

@Service("snaConnectionListService")
public class SnaConnectionListService extends AgentExecCommand{

	private static final Logger logger = Logger.getLogger(SnaConnectionListService.class);
	
	@Autowired
    @Qualifier("monitoringContext")
    private MonitoringContext monitoringContext;
	
    public List executeSnaStatus(Map<String,Object> paramMap) {

        List list = new ArrayList();

        // 명령어의 경로를 얻는다.        
        String cmdPath = monitoringContext.getStringProperty(
                         MonitoringContext.SNA_STATUS_PATH,
                         ""); // /fsapp/eai/SNAAdapter/bin/

        /*if ((paramMap.get("snaStatusCmd").toString()).indexOf("grep") > -1) {
            paramMap.put("snaStatusCmd","SnaStatus -tA | grep -E 'DOWN|그룹'");
        }*/

        logger.info("SnaStatus cmdPath : " + cmdPath);
        // 명령어
        String cmd = cmdPath + paramMap.get("snaStatusCmd");

        //cmd = CharsetDecoderUtil.toKor(cmd);

        logger.info("SnaStatus Command Exec : " + cmd);

        String result = execCommand(cmd);

        int linePoint = 0;

        // 정보를 라인단위로 파싱하여
        linePoint = result.indexOf("\n");

        //================================================================================================================================================
        //어댑터 그룹(SNAAdapter_HOST_OUT) LU 그룹명 (SNAAdapter_HOST_OUT_001) LU 그룹 상태 (정상)
        //총 LU수 (175) UP LU수 (175) 사용 가능 LU수 (175) 수신 대기 LU수 (0) 송신 대기 LU수 (0) WCA 세션 수 (10)
        //송신 건수 (1319) 수신 건수 (8) TIMEOUT 건수 (0) 송신 실패 건수 (0) 수신 실패 건수 (0) 큐 대기 건수 (0) 큐 대기 최대 건수 (0)
        //================================================================================================================================================
        //  LU이름   LU모드    LU상태    LU세부상태   TRAN상태 백업LU  APP_ID  세션연결수 송신건수 수신건수 타임아웃 송신실패 수신실패   세션초기화시간
        //------------------------------------------------------------------------------------------------------------------------------------------------
        //TEN11001  SENDONLY      UP           -         READY      0    I81           1      309        0        0        0        0  2005.10.07 13:23:14
        //TEN11002  SENDONLY      UP           -         READY      0    I81           1      183        0        0        0        0  2005.10.07 13:23:08
        //TEN11003  SENDONLY      UP           -         READY      0    I81           1      135        0        0        0        0  2005.10.07 13:23:14
        //TEN11004  SENDONLY      UP           -         READY      0    I81           1      112        0        0        0        0  2005.10.07 13:23:08
        //TEN11005  SENDONLY      UP           -         READY      0    I81           1      102        0        0        0        0  2005.10.07 13:23:12
        //================================================================================================================================================

        String taskCode = ""; // 서비스 코드명
        String luGroup = ""; // Lu 그룹명

        while (linePoint > -1) {

            Map map = new HashMap();

            // 한 라인만을 읽어 온다.
            String line = result.substring(0, linePoint);
            result = result.substring(linePoint + 1);

            // 리스트 부분만
            if ((line.indexOf("======") < 0) && (line.indexOf("-----") < 0)
                    && (line.indexOf("총") < 0) && (line.indexOf("송신") < 0)
                    && (line.indexOf("[") != 0)) {
                //에러에 대한 예외처리 에러시 첫자가 '[' 로 온다.

                // 업무코드(서비스코드)와 LU그룹을 얻는부분
                if (line.indexOf("LU 그룹 상태") > -1) {

                    int point1 = line.indexOf("(");
                    int point2 = line.indexOf(")");

                    // 서비스코드
                    taskCode = line.substring(point1 + 1, point2);
                    line = line.substring(point2 + 1);

                    point1 = line.indexOf("(");
                    point2 = line.indexOf(")");

                    luGroup = line.substring(point1 + 1, point2);

                    linePoint = result.indexOf("\n");
                    continue;

                }

                logger.info("line : " + line);

                StringTokenizer st = new StringTokenizer(line);
                int stCount = 0;

                map.put("taskCode", taskCode);
                map.put("luGroup", luGroup);

                String sessionInitTime = "";

                while (st.hasMoreTokens()) {

                    String t = st.nextToken();
                    //System.out.println(t);

                    switch (stCount) {

                    case 0:
                        // Lu 이름
                        map.put("luName", t.trim());
                        break;
                    case 1:
                        // Lu 모드
                        map.put("luMode", t.trim());
                        map.put("luModeToolTip", getLuModeToolTip(t.trim()));
                        break;
                    case 2:
                        // Lu 상태
                        map.put("luState", t.trim());
                        map.put("luStateToolTip", getLuStateToolTip(t.trim()));
                        // 상태에 대한 이미지 셋팅
                        if ((t.trim()).equals("UP")) {
                            map.put("startStop", "1");  //start
                        } else {
                            map.put("startStop", "0");  //stop
                        }
                        break;
                    case 3:
                        // Lu 세부 상태
                        map.put("luDetailState", t.trim());
                        map.put("luDetailStateToolTip",
                            getLuDetailStateToolTip(t.trim()));
                        break;
                    case 4:
                        // TRAN 상태
                        map.put("tranState", t.trim());
                        map.put("tranStateToolTip",
                            getTranStateToolTip(t.trim()));
                        break;
                    case 5:
                        // 백업LU
                        map.put("backupLu", t.trim());
                        break;
                    case 6:
                        // APP_ID
                        map.put("appId", t.trim());
                        break;
                    case 7:
                        // Session 연결수
                        map.put("sessionCnt", t.trim());
                        break;
                    case 8:
                        // 송신 건수
                        map.put("sendCnt", t.trim());
                        break;
                    case 9:
                        // 수신 건수
                        map.put("receiveCnt", t.trim());
                        break;
                    case 10:
                        // 타임아웃 건수
                        map.put("timeOut", t.trim());
                        break;
                    case 11:
                        // 송신 실패 건수
                        map.put("sendFailCnt", t.trim());
                        break;
                    case 12:
                        // 수신 실패 건수
                        map.put("receiveFailCnt", t.trim());
                        break;
                    case 13:
                        // Session 초기화 시간 (년 월 일)
                        sessionInitTime = t.trim();
                        break;
                    case 14:
                        // Session 초기화 시간 (시 분 초)
                        map.put("sessionInitTime", sessionInitTime + " " + t.trim());
                               
                        break;
                    }
                    stCount++;

                } // end of while

                if (stCount < 13)
                    map.put("sessionInitTime", "");

                if (map.size() >= 10) {
                    list.add(map);
                }

            }

            linePoint = result.indexOf("\n");

        }

        return list;

    } // end of refresh
    
    /**
     * <pre>
     * 1. 기능 : Lu 모드에 대한 툴팁정보를 얻는다. 
     * </pre>
     * @author  : 이동철
     * @version : $Revision: 1.7 $
     * @since : rts 1.0
     * @param code
     * @return
     */
    private String getLuModeToolTip(String code) {

        String result = "";

        if (code.equals("SENDONLY")) {

            result = "전문 타입의 Non-Response 모드로 호스트로 데이터 송신만을 수행";

        } else if (code.equals("RECVONLY")) {

            result = "전문 타입의 Non-Response 모드로 호스트로부터 데이터 수신만을 수행";

        } else if (code.equals("SENDRECV")) {

            result = "전문 타입의 Response 모드로 호스트와 데이터 송수신 수행";

        } else if (code.equals("TERMINAL")) {

            result = "단말 타입의 Response 모드로 호스트와 데이터 송수신 수행";

        }

        return result;

    }
    
    /**
     * <pre>
     * 1. 기능 : Tran 상태에 대한 툴팁정보를 얻는다. 
     * </pre>
     * @author  : 이동철
     * @version : $Revision: 1.7 $
     * @since : rts 1.0
     * @param code
     * @return
     */
    private String getTranStateToolTip(String code) {

        String result = "";

        if (code.equals("NOTREADY")) {

            result = "Transaction을 수행할 수 없는 상태";

        } else if (code.equals("READY")) {

            result = "Transaction을 수행할 수 있는 상태";

        } else if (code.equals("SEND")) {

            result = "호스트로부터 데이터를 송신하고 있는 상태";

        } else if (code.equals("RECV")) {

            result = "호스트로부터 데이터를 수신 대기하고 있는 상태";

        }

        return result;

    }
    
    /**
     * <pre>
     * 1. 기능 : Lu 세부 상태에 대한 툴팁정보를 얻는다. 
     * </pre>
     * @author  : 이동철
     * @version : $Revision: 1.7 $
     * @since : rts 1.0
     * @param code
     * @return
     */
    private String getLuDetailStateToolTip(String code) {

        String result = "";

        if (code.equals("API_ERROR")) {

            result = "SNA Gateway 내부 장애가 발생한 상태";

        } else if (code.equals("NOT_DEF")) {

            result = "LU가 정의되지 않은 상태";

        } else if (code.equals("LINK_DOWN")) {

            result = "호스트와의 SNA Link가 Down된 상태";

        } else if (code.equals("NET_DOWN")) {

            result = "호스트와의 Network가 Down된 상태";

        } else if (code.equals("DISCONN")) {

            result = "호스트와의 LU 세션이 해제된 상태";

        }

        return result;

    }

    /**
     * <pre>
     * 1. 기능 : Lu 상태에 대한 툴팁정보를 얻는다. 
     * </pre>
     * @author  : 이동철
     * @version : $Revision: 1.7 $
     * @since : rts 1.0
     * @param code
     * @return
     */
    private String getLuStateToolTip(String code) {

        String result = "";

        if (code.equals("DOWN")) {

            result = "호스트와 세션이 해제된 상태";

        } else if (code.equals("TRY_INIT")) {

            result = "호스트와 세션을 연결하기 위한 자원 초기화 상태";

        } else if (code.equals("TRY_INITSELF")) {

            result = "호스트로 INIT-SELF 데이터를 송신하는 상태";

        } else if (code.equals("WAIT_BIND")) {

            result = "호스트로부터 BIND 데이터를 수신 대기하는 상태";

        } else if (code.equals("WAIT_SDT")) {

            result = "호스트로부터 SDT 데이터를 수신 대기하는 상태";

        } else if (code.equals("UP")) {

            result = "호스트와 LU-LU 세션이 연결된 상태";

        } else if (code.equals("TRY_TERMSELF")) {

            result = "호스트로 TERM-SELF 데이터를 송신하는 상태";

        } else if (code.equals("WAIT_UNBIND")) {

            result = "호스트로부터 UNBIND 데이터를 수신 대기하는 상태";

        } else if (code.equals("TRY_TERM")) {

            result = "호스트와 세션을 해제하기 위한 자원 해제 상태";

        } else if (code.equals("RECV_UNBIND")) {

            result = "호스트로부터 UNBIND를 수신한 상태";

        }

        return result;

    }
    
    /**
     * <pre>
     * 1. 기능 : Sna 명령어 실행
     * 2. 처리 개요 :
     *     - SnaStart, SnaStop 명령어 실행
     * 3. 주의사항 :
     * </pre>
     * @author  : 이동철
     * @version : $Revision: 1.8 $
     * @since : rts 1.0
     * @param form
     * @return
     */
    public List executeStartStop(HashMap<String,Object> paramMap) {

        // 명령어
        String cmd = paramMap.get("snaStatusCmd").toString();

        logger.info("SnaStartStop Cmd : " + cmd);

        return executeCmd(cmd);

    } // end of refresh
    

    /**
     * <pre>
     * 1. 기능 : 명령을 실행후 결과를 반환한다.
     * 2. 처리 개요 :
     *     - 명령어를 실행후 결과를 반환한다.
     * </pre>
     * @author  : 이동철
     * @version : $Revision: 1.8 $
     * @since : rts 1.0
     * @param cmd
     * @return
     */
    private List executeCmd(String cmd) {

        List list = new ArrayList();

        // 명령어의 경로를 얻는다.
        String cmdPath = monitoringContext.getStringProperty(
                         MonitoringContext.SNA_STATUS_PATH,
                         "/fsapp/eai/SNAAdapter/bin/");

        String command = cmdPath + cmd;

        String result = execCommand(command);

        Map map = new HashMap();
        if ((result.trim()).length() > 0) {
            map.put("msg", result.trim());
        } else {
            map.put("msg", "명령처리에 실패 하였습니다.");
        }

        list.add(map);

        return list;

    }

}
