package com.eactive.eai.rms.onl.common.service;

import java.util.HashMap;
import java.util.List;

import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;
import org.springframework.context.ApplicationContext;

import com.eactive.eai.rms.common.context.MonitoringContext;
import com.eactive.eai.rms.common.datasource.DataSourceContextHolder;
import com.eactive.eai.rms.common.datasource.DataSourceType;
import com.eactive.eai.rms.common.datasource.DataSourceTypeManager;
import com.eactive.eai.rms.common.util.CommonUtil;
import com.eactive.eai.rms.onl.dashboard.service.Dashboard2RepositoryService;

public class PeakTpsUpdateDayJob implements Job {
    /**
     * Logger for this class
     */
	private static final Logger logger = Logger.getLogger(PeakTpsUpdateDayJob.class);
	
	private Dashboard2RepositoryService dashboard2Repository;

	private DashboardTargetService dashboardTargetService;


	// 매일 자정 15분 에 전일자 Peak TPS , 거래건수 정보를 업데이트 한다.
    //@ScheduleMethod(type = ScheduleType.CRON, cronExpression = "0 1174.5 0 * * ?")
	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
//        JobKey jobKey = context.getJobDetail().getKey();

		ApplicationContext appContext = null;
		try {
			appContext = (ApplicationContext)context.getScheduler().getContext().get("applicationContext");
		} catch (SchedulerException e) {
			logger.error("applicationContext get module error",e);
			return ;
		}  
		dashboard2Repository = (Dashboard2RepositoryService)appContext.getBean("dashboard2RepositoryService");	
		dashboardTargetService = (DashboardTargetService)appContext.getBean("DashboardTargetService");	
		runTps();
				
	}
    
    
    public void runTps() {    	
    	dashboard2Repository.reloadPeakTpsTrade();
    	
    	String today = CommonUtil.getToday("");
    	String yesterday = CommonUtil.getDiffHourDate(today, -24, "");
    	String start = yesterday.substring(0,8) + "000000" ;
//    	String end   = CommonUtil.getDiffMinDate(start, 10, "yyyyMMddHHmmss");
    	String stop  = today.substring(0,8) + "000000" ;
    	
    	logger.info( "** START PEAK TPS SCHEDULER ** : start=" + start + ", stop=" + stop ); 
    	
        
//        boolean debug = logger.isDebugEnabled();
        
		List<DataSourceType> services = DataSourceTypeManager.getOnlineDataSourceTypes();

//    	int peakProc[]  = {0,0,0,0} ;
    	int totalProc[] = {0,0,0,0,0} ;
    	int peakTps[]   = {0,0,0,0,0};
//    	int proc = 0 ;

    	boolean isUpdateTps = false ;
    	boolean isUpdateTrade = false ;
    	
    	// NSG,20091219,58422,125, ( 서비스,날짜,거래량,TPS, )
		int count = 0;
		
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
    	
		String maxcount = "";
		String totalcount = "";
		
		for( DataSourceType d : services ) {
			DataSourceContextHolder.setDataSourceType(d);
			HashMap<String, Object> procCountMap;
			
			try {
				procCountMap = dashboardTargetService.getProcCountWithSR02(yesterday.substring(0,8),d.getSchema());
				if(procCountMap != null){
					maxcount = String.valueOf(procCountMap.get("MAXCOUNT"));
					totalcount = String.valueOf(procCountMap.get("TOTCOUNT"));
					
					//totalcount 0보다 작을경우 0으로 치환 (정상처리시간 에러처리시간이 다를경우 (-) 나올수 있음  2020-06-29
					if(Integer.parseInt(totalcount) < 0){
						logger.warn("totalcount 0보다 작음 : " + totalcount);
						totalcount = "0";
					}
					
					peakTps[count] = Integer.parseInt(maxcount) / 600;
					totalProc[count] = Integer.parseInt(totalcount) ;
				} else {
					maxcount = "0";
					totalcount = "0";
				}
			} catch (Exception e1) {
				logger.error("PeakTpsUpdateDayJob runTps error ["+d.getName()+"] ",e1);
				continue;
			}
	    	
			if(logger.isInfoEnabled()) logger.info("1.service: " + d.getName() + "peakTps : "+peakTps[count] + " ,totalProc : "+totalProc[count]);
			
			if( isOverMaxTps( d.getName(), peakTps[count] ) ) {
	    		String setVal = getPeakTpsLine( d.getName(), yesterday, totalProc[count], peakTps[count] ) ;
	    		dashboard2Repository.setPeakTps( d.getName(), setVal );
	    		isUpdateTps = true ;
	    	}
	    	if( isOverMaxTrade( d.getName(), totalProc[count] ) ) {
	    		String setVal = getPeakTpsLine( d.getName(), yesterday, totalProc[count], peakTps[count] ) ;
	    		dashboard2Repository.setPeakTrade( d.getName(), setVal );
	    		isUpdateTrade = true ;
	    	}
	    	
	    	// 항상 저장한다.
	    	paramMap.clear();
	    	paramMap.put("baseInfo", "TPS");
        	paramMap.put("bzwkGroupName", d.getName());
        	paramMap.put("eaiGroupCoCd", "KB0");
        	paramMap.put("baseYMS", yesterday.substring(0,8));
        	paramMap.put("prcssNoitm", totalProc[count]);
        	paramMap.put("tpsNoitm", peakTps[count]);
        	try {
        		
        		if(logger.isInfoEnabled()) {
        			logger.info("insertPeakTpsHistory [" + d.getName() +" : prcssNoitm="+totalProc[count] + ", tpsNoitm="+peakTps[count]);
        		}
        		
        		if(logger.isInfoEnabled()) logger.info("INSERT paramMap : "+paramMap.toString());
				dashboardTargetService.insertPeakTpsHistory(paramMap);
			} catch (Exception e) {
				logger.warn("ONLINE - insertPeakTpsHistory Failed  bzwkGroupName=" + d.getName() 
					+ ", baseYMS=" + yesterday + ", total=" + totalProc[count] + ", peaktps=" + peakTps[count] , e);
				//e.printStackTrace();
			}
	    	count++;
		}
    	
    	// 일괄 총 거래건수
    	try {
    		DataSourceType bap = null;
    		bap = DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.BAP);
    		DataSourceContextHolder.setDataSourceType(bap);
    		if(bap != null){
            	int tmpBatch[] = dashboardTargetService.getBatchProcCountByDate(  yesterday.substring(0,8), false);
            	int curBatch = tmpBatch[0] + tmpBatch[1] ;
            	if(logger.isInfoEnabled()) logger.info("curBatch : "+curBatch);
            	if( isOverMaxTpsBatch(bap.getName(), curBatch) ) {
            		String setVal = getPeakTpsLine( bap.getName(), yesterday, curBatch, -1 );
            		dashboard2Repository.setPeakTps(bap.getName(), setVal );
            		isUpdateTps = true ;
            	}
            	if( isOverMaxTrade( bap.getName(), curBatch) ) {
            		String setVal = getPeakTpsLine( bap.getName(), yesterday, curBatch, -1 );
            		dashboard2Repository.setPeakTrade(bap.getName(), setVal);
            		isUpdateTrade = true ;
            	}
    		}
    		
        	
        	// EAI BATCH 총 거래건수
    		DataSourceType bat = null;
    		bat = DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.BAT);
    		DataSourceContextHolder.setDataSourceType(bat);
    		if(bat != null){
               	int tmpBatch2[] = dashboardTargetService.getBatchProcCountByDate( yesterday.substring(0,8), true);
            	int curBatch2 = tmpBatch2[1] ;
            	if(logger.isInfoEnabled()) logger.info("tmpBatch2  : "+tmpBatch2);
            	if( isOverMaxTpsBatch( bat.getName(), curBatch2) ) {
            		String setVal = getPeakTpsLine(  bat.getName(), yesterday, curBatch2, -1 );
            		dashboard2Repository.setPeakTps( bat.getName(), setVal );
            		isUpdateTps = true ;
            	}
            	if( isOverMaxTrade( bat.getName(), curBatch2) ) {
            		String setVal = getPeakTpsLine( bat.getName(), yesterday, curBatch2, -1 );
            		dashboard2Repository.setPeakTrade( bat.getName(), setVal);
            		isUpdateTrade = true ;
            	}
        	
	        	// 항상 저장한다.
		    	paramMap.clear();
		    	paramMap.put("baseInfo", "TPS");
	        	paramMap.put("bzwkGroupName", bat.getName());
	        	paramMap.put("eaiGroupCoCd", "KB0");
	        	paramMap.put("baseYMS", yesterday.substring(0,8));
	        	paramMap.put("prcssNoitm", curBatch2);
	        	paramMap.put("tpsNoitm", -1);
	        	try {
	        		
	        		//일괄에는  TSEAIRM15 테이블이 없음 2020.0615 주석처리
					//dashboardTargetService.insertPeakTpsHistory(paramMap);
				} catch (Exception e) {
					logger.warn("BATCH - insertPeakTpsHistory Failed  bzwkGroupName=" + bat.getName()
						+ ", baseYMS=" + yesterday + ", total=" + curBatch2, e);
					//e.printStackTrace();
				}
    		} //if
        	
    	} catch ( Exception e ) {
    		//e.printStackTrace();
    		logger.error("batch trade error",e);
    	}
    	
    	if( isUpdateTps ) {
    		DataSourceType ds = DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.MONITORING);
    		DataSourceContextHolder.setDataSourceType(ds);
    		
    		String key    = MonitoringContext.RMS_PEAK_TPS ;
    		String val = dashboard2Repository.getPeakTpsAll();
    		try {
    			dashboardTargetService.updatePeakTps( key, val );    			
    		} catch ( Exception e ) {
    			//e.printStackTrace();
    			logger.error("isUpdateTps error",e);
    		}
    		
    		logger.info( "PEAK TPS 정보가 갱신 되었습니다. =>"+key+"="+val);
    	}
    	
    	if( isUpdateTrade ) {
    		DataSourceType ds = DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.MONITORING);
    		DataSourceContextHolder.setDataSourceType(ds);
    		
    		String key    = MonitoringContext.RMS_PEAK_TRADE ;
    		String val    = dashboard2Repository.getPeakTradeAll();
    		if(logger.isInfoEnabled()) logger.info("isUpdateTrade  val: "+val);
    		try {
    			dashboardTargetService.updatePeakTps( key, val );    			
    		} catch ( Exception e ) {
    			//e.printStackTrace();
    		  logger.error("isUpdateTrade error",e);
    		}
    		
    		logger.info( "PEAK TRADE 정보가 갱신 되었습니다. =>"+key+"="+val);
    	}
    	
    	dashboard2Repository.reloadPeakTpsTrade();
		
    	logger.info( "** END PEAK TPS SCHEDULER ** : finish time=" + CommonUtil.getToday("") );
    		
    }
    
    private boolean isOverMaxTps( String service, int curTps ) {
    	try {
	    	String tmp = dashboard2Repository.getPeakTps(service);
	    	if(tmp != null){
	    	String arrTmp[] = tmp.split(",");
		    	if( arrTmp.length > 3 ) {
		    		int maxTps = CommonUtil.getInt(arrTmp[3]);
		    		logger.info("service : " + service + " ,maxTps : " + maxTps + " ,curTps : " + curTps);
		    		if( curTps > maxTps ) {
		    			return true ;
		    		}
		    	}    
	    	}
    	} catch(Exception e) {
    		logger.error("PeakTpsUpdateScheduler.isOverMaxTps Err[" + service + "] : " + e.getMessage());
    	}
    	
    	return false ;
    }
    
    private String getPeakTpsLine( String service, String yesterday, int peakTrade, int peakTps ) {
    	if( yesterday.length() > 8 ) {
    		yesterday = yesterday.substring(0,8);
    	}
    	
    	StringBuffer sb = new StringBuffer();
    	sb.append(service).append(",");
    	sb.append(yesterday).append(",");
    	sb.append(peakTrade).append(",");
    	if( peakTps < 0 ) {
    		// batch
    		sb.append("--");
    	} else {
    		sb.append(peakTps);
    	}
    	
    	return sb.toString();
    }

    private boolean isOverMaxTrade( String service, int curTrade ) {
    	
    	try{
	    	String tmp = dashboard2Repository.getPeakTrade(service);
	    	if(tmp != null){
	    		String arrTmp[] = tmp.split(",");
		    	if( arrTmp.length > 3 ) {
		    		int maxTrade = CommonUtil.getInt(arrTmp[2]);
		    		logger.info("service : " + service  + " ,maxTrade : " + maxTrade + " ,curTrade : " + curTrade);
		    		if( curTrade > maxTrade ) {
		    			return true ;
		    		}
		    	}
	    	}
	    	
		} catch(Exception e) {
			logger.error("PeakTpsUpdateScheduler.isOverMaxTrade Err[" + service + "] : " + e.getMessage());
		}
	    	
    	return false ;
    }

    private boolean isOverMaxTpsBatch( String service, int curTrade ) {
    	
    	try {
	    	String tmp = dashboard2Repository.getPeakTps(service);
	    	logger.info("isOverMaxTpsBatch curTrade : " + curTrade + " , tmp : " + tmp);
	    	if(tmp != null){
	    		String arrTmp[] = tmp.split(",");
		    	if( arrTmp.length > 3 ) {
		    		int maxTrade = CommonUtil.getInt(arrTmp[2]);
		    		if( curTrade > maxTrade ) {
		    			return true ;
		    		}
		    	}   
	    	}
	    	 	
		} catch(Exception e) {
			logger.error("PeakTpsUpdateScheduler.isOverMaxTpsBatch Err[" + service + "] : " + e.getMessage());
		}
    	
    	return false ;
    }



    
}
