package com.eactive.eai.common.monitor;

import com.eactive.eai.common.dao.DAOFactory;
import com.eactive.eai.common.errorcode.ErrorCodeHandler;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.logger.EAILogDAO;
import com.eactive.eai.common.message.IFType;
import com.eactive.eai.common.server.EAIServerManager;
import com.eactive.eai.common.util.ApplicationContextProvider;
import com.eactive.eai.common.util.DatetimeUtil;
import com.eactive.eai.common.util.Logger;

import java.util.Iterator;
import java.util.TimerTask;

/** 
* 1. 기능 : 일, 최근시간(10분 또는 1시간)에 따른 각 MonitorVO 초기화
* 2. 처리 개요 : 
*       - Timer에 의해 매일, 매 최근시간 반복적으로 초기화 수행
* 3. 주의사항 
*
* @author  : 
* @version : v 1.0.0
* @see : 관련 기능을 참조
* @since   : 
*  : 
*/
public class MonitorChecker extends TimerTask
{ 
    /** 
     * EAI FRAMEWORK DEFAULT FILE LOGGER
     */
    static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
    
    /** 
     * EAIServiceMonitor
     */
    private EAIServiceMonitor serviceMonitor;
    
    /** 
     * 일일 초기화를 위해 현재 날짜와 비교하기 위한 이전날짜
     */
    private String prevDate;
    private int resetCount;
    
    /** 
    * 1. 기능 : Default 생성자
    * 2. 처리 개요 : 
    * 3. 주의사항 
    **/   
    public MonitorChecker() {
            prevDate =  DatetimeUtil.getCurrentDate();
            resetCount = 0;
    }
    
    /** 
    * 1. 기능 : MonitorChecker가 주기적으로 모니터링할 EAIServiceMonotir 설정
    * 2. 처리 개요 : 
    *     - MonitorChecker가 주기적으로 모니터링할 EAIServiceMonotor 설정
    * 3. 주의사항 
    *@param	monitor	주기적으로 모니터링할 EAIServiceMonotir
    **/   
    public void setEAIServiceMonitor(EAIServiceMonitor monitor) {
        this.serviceMonitor = monitor;
        this.serviceMonitor.setMonitorDate(prevDate);
    }
    
    /** 
    * 1. 기능 : 정해진시간에 초기화 수행
    * 2. 처리 개요 : 
    *     - DatetimeUtil로부터 현재 일자를 얻어 비교하여 일자가 변경된 경우 reset
    *     - 최근시간(10분 또는 1시간) 마다 reset
    *     - 복원정보의 전전일자 데이터를 삭제한다.
    * 3. 주의사항 
    **/   
    public void run()
    {
        String msg = ErrorCodeHandler.getMessage("RICEAICMT001", new String[]{Thread.currentThread().getName()});
        if (logger.isInfo()) logger.info(ExceptionUtil.make("RICEAICMT001", msg));
        
        String date = DatetimeUtil.getCurrentDate();
       
        // 2009.12.23
        // 일자전환시 Map의 리스트를 모두 삭제한다.
        if(!(date.equals(prevDate))){
        	//this.serviceMonitor.resetAll();
        	this.serviceMonitor.clearAll();
        	resetCount++;
        	if (logger.isWarn()) {
        		logger.warn("MonitorChecker] DAILY_RESET_COUNT EXECUTED!");
        	}
        }
        
        // 2011.02.27
        // Error 처리로직 추가
    	String[] keys = this.serviceMonitor.getAllMonitorVOKey();
        MonitorVO mv = null;
        
        if(keys == null) {
        	if (logger.isWarn()) {
        		logger.warn("MonitorChecker] SKIP : MonitorVO List is NULL!");
        	}
        	return;
        }
        
        for(int i=0; i<keys.length; i++) {            
            // 2011.01.10 : Insert to DB
            try {
            	mv = this.serviceMonitor.getMonitorVO(keys[i]);
            	if(mv != null) {
            		insertStaticCount(mv);
            		mv.clearStatic();
            		mv.resetPeriod();
            	}
            }
            catch(Exception ex) {
            	if (logger.isWarn()) {
            		logger.warn("MonitorChecker] SKIP - STATIC INFO Logging Error ! - "+ ex.getMessage());
            	}
//            	ex.printStackTrace();
            }
        }
          
// COMMENTED 2008.12.11
// Do not delete previous date log file
//        if (!(date.equals(prevDate))){
//        	
//        	String wlServer = System.getProperty(Keys.SERVER_KEY);
//            
//            
//            try {
//            	String dirpath = this.serviceMonitor.getFilPath()+"/"+wlServer;
//	   	        String fileName = "MonitorVoData_"+prevDate;
//	   	        
//	   	        File f = new File(dirpath, fileName);
//	   	        
//	   	        
//	            if (f != null && f.exists()){
//	            	logger.debug("MonitorChecker ] clear fileName ["+fileName+"]");
//	            	f.delete();
//	            }else {
//	            	logger.debug("MonitorChecker ] file not exists ["+fileName+"]");
//	            }
//            }catch (Exception e){
//            	e.printStackTrace();
//            	logger.warn("MonitorChecker ] occure Exception at clear File");
//            }
//        }
        prevDate = date;
        this.serviceMonitor.setMonitorDate(prevDate);
    }

    public void insertStaticCount(MonitorVO vo) {
        //----------------------------------------------------------
        // 2011.01.13 Insert Memory Count
        // 10분거래건수, 화면번호별, 거래코드별, 기관명 건수
        //----------------------------------------------------------

        StatMonitorLogVO logVo = new StatMonitorLogVO();
        // 일자, 시간, 분
        String[] f = new String[3];
        String dFormat =  DatetimeUtil.getFormattedDate("yyyyMMddHHmm");
        f[0] = dFormat.substring(0,8);
        f[1] = dFormat.substring(8,10);
        f[2] = dFormat.substring(10,12);

        logVo.setYmd(f[0]);
        logVo.setHour(f[1]);
        logVo.setMin(f[2]);

        logVo.setBzwkDstcd(vo.getBwkCls());
        logVo.setSvcName(vo.getEaiServiceCode());


        // EAI서버인스턴스명
        String serverName = EAIServerManager.getInstance().getLocalServerName();

        logVo.setSevrInstncName(serverName);


        // EAI처리시간, EAI수동처리시간, 총처리시간
        logVo.setPrcssTtmVal((vo.getSumOfProcessTimeInPeriod()-vo.getPsvSumOfPssTimeInPeriod()));
        logVo.setPsvPrcssTtmVal(vo.getPsvSumOfPssTimeInPeriod());
        logVo.setTotalPrcssTtmVal(vo.getSumOfProcessTimeInPeriod());

        // 전체처리건수, 에러건수, 타임아웃건수, 정상건수
        long totCnt = 0;
        long errCnt = 0;
        long toCnt = 0;
        long succCnt = 0;

        char rType = ' ' ;
        String eaiServiceCode = vo.getEaiServiceCode();
        if( eaiServiceCode != null && eaiServiceCode.length() > 3 ) {
            rType = eaiServiceCode.charAt(eaiServiceCode.length()-3);
        }

        if(IFType.AA.equals(vo.getIfType())) {
            if( rType == 'S') {
                totCnt = Long.parseLong(vo.getPssCntInPeriod().get("100").toString())
                        + Long.parseLong(vo.getErrPssCntInPeriod().get("100").toString());
            } else {
                totCnt = Long.parseLong(vo.getPssCntInPeriod().get("300").toString())
                        + Long.parseLong(vo.getErrPssCntInPeriod().get("300").toString());
            }
            errCnt = Long.parseLong(vo.getErrPssCntInPeriod().get("900").toString());
            toCnt = Long.parseLong(vo.getErrPssCntInPeriod().get("9900").toString());
            succCnt = totCnt - (errCnt + toCnt);
        }
        // 2011.04.28 이동훈
        // SA 응답일 경우에는 건수를 0으로 한다.
        else if(IFType.SA.equals(vo.getIfType()) && rType == 'R') {
            errCnt = 0;
            toCnt = 0;
            succCnt = 0;
        }
        else {
            totCnt = Long.parseLong(vo.getPssCntInPeriod().get("100").toString())
                    +  Long.parseLong(vo.getErrPssCntInPeriod().get("100").toString());

            errCnt = Long.parseLong(vo.getErrPssCntInPeriod().get("400").toString())
                    + Long.parseLong(vo.getErrPssCntInPeriod().get("900").toString());
            toCnt = Long.parseLong(vo.getErrPssCntInPeriod().get("9400").toString());
            succCnt = totCnt - (errCnt + toCnt);
        }

        logVo.setWholPrcssNoitm(totCnt);
        logVo.setErrzNoitm(errCnt);
        logVo.setToutNoitm(toCnt);
        logVo.setNomalNoitm(succCnt);

        EAILogDAO dao = null;
        try {
            dao = ApplicationContextProvider.getContext().getBean(EAILogDAO.class);
        } catch(Exception e) {
            if (logger.isError()) logger.error("MonitorVO.insertStaticCount ERROR. - " + e.getMessage(),e);
        }

        if(dao == null) {
            return;
        }

        // 메모리 정보는 건수가 RESET 되므로 건수가 0보다 큰 경우만 DB에 저장
        // SA 응답인 경우는 로깅하도록 함. (SR05와 맞추기 위해)
        if(totCnt > 0 || (IFType.SA.equals(vo.getIfType()) && rType == 'R') ) {
            try {
                dao.addStaticLog(logVo);
            } catch(Exception e) {
                //if (logger.isError()) logger.error("MonitorVO.insertStaticCount ERROR. - " + e.getMessage(),e);
            }
        }

//		Iterator it_s = mScreenMap.keySet().iterator();
//		for(int i = 0; it_s.hasNext(); i++) {
//			String key = (String)it_s.next();
//			StatMonitorVO vo = (StatMonitorVO)mScreenMap.get(key);
//			logVo.setKey(key);
//			StatMonitorLogVO tmpLogVo = convertLogVO(logVo, vo, ifType, rType);
//
//			if(tmpLogVo.getWholPrcssNoitm() < 1 && !(IFType.SA.equals(ifType) && rType == 'R')) {
//				StringBuffer sb = new StringBuffer();
//				sb.append(vo.toString()+"\n");
//				sb.append(tmpLogVo.toString());
//			}
//
//			try {
//				dao.addStaticScreenLog(tmpLogVo);
//	        } catch(Exception e) {
//	            if (logger.isError()) logger.error("MonitorVO.insertStaticCount SCREEN ERROR. - "
//	            		+ tmpLogVo.toString() + "\n" + e.getMessage(),e);
//	        }
//		}

        Iterator it_t = vo.iteratorTranCdMap();
        for(int i = 0; it_t.hasNext(); i++) {
            String key = (String)it_t.next();
            StatMonitorVO smvo = vo.getTranCdMonitorVo(key);
            logVo.setKey(key);
            StatMonitorLogVO tmpLogVo = convertLogVO(logVo, smvo, vo.getIfType(), rType);
            try {
                dao.addStaticTranCdLog(tmpLogVo);
            } catch(Exception e) {
                
            }
        }

        Iterator it_a = vo.iteratorAdapterMap();
        for(int i = 0; it_a.hasNext(); i++) {
            String key = (String)it_a.next();
            StatMonitorVO smvo = vo.getAdapterMonitorVo(key);
            logVo.setKey(key);
            StatMonitorLogVO tmpLogVo = convertLogVO(logVo, smvo, vo.getIfType(), rType);
            try {
                dao.addStaticAdapterLog(tmpLogVo);
            } catch(Exception e) {
                
            }
        }
    }

    private StatMonitorLogVO convertLogVO(StatMonitorLogVO logVo, StatMonitorVO statVo,
                                          String ifType, char rType) {
        long totCnt = 0;
        long errCnt = 0;
        long toCnt = 0;
        long succCnt = 0;

        logVo.setPrcssTtmVal((statVo.getSumOfprocessTime() - statVo.getPsvSumOfPssTime()));
        logVo.setPsvPrcssTtmVal(statVo.getPsvSumOfPssTime());
        logVo.setTotalPrcssTtmVal(statVo.getSumOfprocessTime());
        logVo.setKey(" ");
        if(IFType.AA.equals(ifType)) {
            if( rType == 'S') {
                totCnt = statVo.getCnt100() + statVo.getErr100();
            } else {
                totCnt = statVo.getCnt300() + statVo.getErr300();
            }
            errCnt = statVo.getErr900();
            toCnt = statVo.getTimeout900();
            succCnt = totCnt - (errCnt + toCnt);
        }
        // 2011.04.28 이동훈
        //SA 응답일 경우에는 건수를 0으로 한다.
        else if(IFType.SA.equals(ifType) && rType == 'R') {
            totCnt = 0;
            errCnt = 0;
            toCnt = 0;
            succCnt = 0;
        }
        else {
            totCnt =statVo.getCnt100() + statVo.getErr100();
            errCnt = statVo.getErr400() + statVo.getErr900();
            toCnt = statVo.getTimeout400();
            succCnt = totCnt - (errCnt + toCnt);
        }
        logVo.setWholPrcssNoitm(totCnt);
        logVo.setErrzNoitm(errCnt);
        logVo.setToutNoitm(toCnt);
        logVo.setNomalNoitm(succCnt);

        return logVo;
    }
} 
