package com.eactive.eai.common.monitor;

import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.server.Keys;
import com.eactive.eai.common.util.DatetimeUtil;
import com.eactive.eai.common.util.Logger;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.HashMap;
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 MonitorWriteChecker extends TimerTask
{ 
    /** 
     * EAI FRAMEWORK DEFAULT FILE LOGGER
     */
    static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
    
    /** 
     * EAIServiceMonitor
     */
    private EAIServiceMonitor serviceMonitor;
    
    /**
     * EAIServiceMonitor에서 사용하는 Poprties Group의 Key
     */
    public static final String PROP_GROUP = "EAIServiceMonitor";

    /**
     * 주기적으로 write할 file의 위치
     */
    public static final String FILE_PATH = "file.write.path";
    
    /**
     * 파일로깅시 데이터를 구분하기 위한 구분자
     */									
    public static final String MASTER_DELIMITER = "file.write.master.delimiter";
    
    /**
     * 파일로깅시 데이터를 구분하기 위한 구분자
     */									
    public static final String SUB_DELIMITER = "file.write.sub.delimiter";

    
    
    /** 
    * 1. 기능 : Default 생성자
    * 2. 처리 개요 : 
    * 3. 주의사항 
    **/   
    public MonitorWriteChecker() {

    }
    
    /** 
    * 1. 기능 : MonitorChecker가 주기적으로 모니터링할 EAIServiceMonotir 설정
    * 2. 처리 개요 : 
    *     - MonitorChecker가 주기적으로 모니터링할 EAIServiceMonotir 설정
    * 3. 주의사항 
    *@param	monitor	주기적으로 모니터링할 EAIServiceMonotir
    **/   
    public void setEAIServiceMonitor(EAIServiceMonitor monitor) {
        this.serviceMonitor = monitor;    
    }
    
    /** 
    * 1. 기능 : 정해진시간에 초기화 수행
    * 2. 처리 개요 : 
    *     - DatetimeUtil로부터 현재 일자를 얻어 비교하여 일자가 변경된 경우 reset
    *     - 최근시간(10분 또는 1시간) 마다 reset
    * 3. 주의사항 
    **/   
    public void run()
    {
        String msg = "MonitorWriteChecker start..... ";
        if (logger.isInfo()) logger.info(msg);
        
       
        File dir = null;
        File f = null;
        FileWriter fw = null;
       
        Iterator monitorVo = this.serviceMonitor.getAllMonitorVO();
        MonitorVO mv = null;
        BufferedWriter bw = null;

        String date = DatetimeUtil.getCurrentDate();
        String wlServer = System.getProperty(Keys.SERVER_KEY);
        
        PropManager pmanager = PropManager.getInstance();
        String propPath = "";
        String master_delimiter = "";
        String sub_delimiter = "";
        
        try{
        
            master_delimiter = pmanager.getProperty(PROP_GROUP,MASTER_DELIMITER);
            sub_delimiter = pmanager.getProperty(PROP_GROUP,SUB_DELIMITER);
            propPath=pmanager.getProperty(PROP_GROUP, FILE_PATH);
            
            if (master_delimiter == null || master_delimiter.length()<=0 ){
            	master_delimiter = ":";
            }
            
            if (sub_delimiter == null || sub_delimiter.length()<=0 ){
            	sub_delimiter = "/";
            }
            
            //filepath를 프로퍼티에 설정 안했으면...
            if (propPath == null || propPath.equals("")){
            	propPath = ".";
            }
            
            String dirpath = propPath+"/"+wlServer;
            
	        dir = new File(dirpath);
	        if(!dir.exists()) {
	            dir.mkdirs();
	        } 
	        
	        String fileName = "MonitorVoData_"+date;
	        this.serviceMonitor.setfileName(dirpath+"/"+fileName);
	        this.serviceMonitor.setFilePath(propPath);
	        
	        f = new File(dir, fileName);
	        fw = new FileWriter(f);
	        bw = new BufferedWriter(fw);
	        
	        while(monitorVo.hasNext()){                
	        	//file write	
	        	//#eaiServiceCode/bwkCls/isSingle/ifType/groupCoCd:	-- key
	        	//100=2/200=2/300=2/400=2:  			-- 거래 count
	        	//100=2/200=2/300=2/400=2/900=2: 		-- error count
	        	//sumOfprocessTime/psvSumOfPssTime		-- eai처리시간, 수동처리시간
	        	
	        	mv = (MonitorVO) monitorVo.next();
	        	
	        	boolean isSingle = mv.getIsSingle(); 
	        	
	        	if(isSingle){//단일거래이면
	        		
	        		String[] countKey = mv.getAllPssCntKey();
	        		HashMap countMap = mv.getPssCnt();
	        		
	        		if (countKey.length >0 ){
	        			StringBuffer bf = new StringBuffer();
	        			
	        			bf.append(mv.getEaiServiceCode()).append(sub_delimiter);
	        			bf.append(mv.getBwkCls()).append(sub_delimiter);
	    	        	bf.append(isSingle).append(sub_delimiter);
//	    	        	bf.append(mv.getIfType()).append(master_delimiter);
	    	        	bf.append(mv.getIfType()).append(sub_delimiter);
	    	        	//그룹사코드 추가, 2010.11.16
	    	        	bf.append(mv.getGroupCoCd()).append(master_delimiter);

	    	        	
		        		for (int i=0;i<countKey.length-1; i++){
		        			bf.append(countKey[i]).append("=").append(countMap.get(countKey[i])).append(sub_delimiter);
		        		}
		        		bf.append(countKey[countKey.length-1]).append("=").append(countMap.get(countKey[countKey.length-1]));
		        		bf.append(master_delimiter);
	        		
	        		
		        		String[] errorKey = mv.getAllErrPssCntKey();
		        		HashMap errorMap = mv.getErrPssCnt();
	        		
	        	
		        		for(int j=0; j<errorKey.length-1; j++){
		        			bf.append(errorKey[j]).append("=").append(errorMap.get(errorKey[j])).append(sub_delimiter);
		        		}
		        		bf.append(errorKey[errorKey.length-1]).append("=").append(errorMap.get(errorKey[errorKey.length-1]));
		        		bf.append(master_delimiter);
	        		
	        		
		        		bf.append(mv.getSumOfprocessTime()).append(sub_delimiter);
			        	bf.append(mv.getPsvSumOfPssTime());
	
			        	logger.debug("MonitorWriteChecker ] file write data : "+bf.toString());
			        	bw.write(bf.toString());
			        	bw.newLine();
			        	bw.flush();
	        		}
	        		
	        	}else {		//복합거래이면 추가 로직 넣을것
	        		logger.debug("MonitorWriteChecker ] is not Single");
	        		
	        	}

	        }     
        }catch (Exception e){
        	logger.error("MonitorWriteChecker ] occur Exception", e);
        }finally {
        	try{
        		if (bw != null) bw.close();
        		if (fw != null) fw.close();
        	}catch (Exception ex){
        		logger.error("MonitorWriteChecker ] occur Exception", ex);
        	}
        }
        
    }
} 
