package com.eactive.eai.rms.onl.dashboard.controller;

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.common.service.EaiServerInfoService;
import com.eactive.eai.rms.onl.dashboard.dao.DashboardDAO;
import com.eactive.eai.rms.onl.dashboard.service.Dashboard2RepositoryService;
import com.eactive.eai.rms.onl.dashboard.service.DashboardService;
import com.eactive.eai.rms.onl.tracking.vo.MemStaticsVo;
import com.eactive.eai.rms.onl.vo.*;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.View;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;


@Controller
//@RequestMapping("/dashboard2.do")
public class NewDashboardMainController {
    private static final String FIELD_SEP = "," ;
    private static final String LINE_SEP = ";" ;
    
    private static final Logger logger = Logger.getLogger(NewDashboardMainController.class);
    
    
    /** The monitoring context. */
    @Autowired
    @Qualifier("monitoringContext")
    private transient MonitoringContext monitoringContext;

    /** The eai server info service. */
    @Autowired
    @Qualifier("eaiServerInfoService")    
    private EaiServerInfoService eaiServerInfoService;

    /** The dashboard service. */
    @Autowired
    @Qualifier("dashboardService")
    private DashboardService dashboardService;
    
    @Autowired
    @Qualifier("dashboard2RepositoryService")
    private Dashboard2RepositoryService dashboard2Repository;
    
    @Autowired
    @Qualifier("dashboardDao")
    private DashboardDAO dashboardDao;
    
	@RequestMapping(path = "/dashmain3.do")
	public String dashmain3(HttpServletRequest request) {
		return "dashmain3";
	}

    @RequestMapping(path = "/dashboard2.do", params = "cmd=main")
    public View mainProc(ModelMap modelMap, HttpServletRequest request, HttpServletResponse response, String cmd, String type) {        
        try {
        	// 한글처리 관련
        	response.setContentType("text/xml;charset=utf-8"); 
        	response.setHeader("Cache-Control", "no-cache"); 

        	PrintWriter pw = response.getWriter();
        	
        	List<Map<String, String>> list = null ;
        	StringBuffer sb = new StringBuffer();

    		String service = ServletRequestUtils.getStringParameter(request, "service", "");
        	
        	String tradeTarget = (String)request.getSession().getAttribute(MonitoringContext.RMS_TRADE_COUNT_TARGET);
        	if( tradeTarget == null || "".equals(tradeTarget) ) {
        		tradeTarget = "ALL" ;
        	}
        	
        	logger.debug("mainProc[" + type + "]:" + service);
        	
        	if( (service.length() > 0) && 
        			DataSourceTypeManager.getDataSourceType(service) == null) {
        		logger.warn("New dashboard Skip mainProc unregistered Service : service=" + service +", cmd="+ cmd +", type="+ type);
        		return null;
        	}
        	DataSourceContextHolder.setDataSourceType(DataSourceTypeManager.getDataSourceType(service));
        		
    		if( "baseinfo".equals(type) ) {    	        
    	        sb.append( getTargetService());  // ALL
    		} else if( "serverinfo".equals(type) ) {
        		
        		// EAISVRINSTNM,EAISVRIP,EAISVRLSNPORT,HOSTNAME
    			// BATCH는 서버리스는 없음 new 만 해서 리턴함
    			
    			if (DataSourceTypeManager.BAT.equals(service)){
        			list = eaiServerInfoService.getBatServerIpList();
    			} else if (DataSourceTypeManager.BAP.equals(service)){
        			list = eaiServerInfoService.getBapServerIpList();
        		} else {
        			list = eaiServerInfoService.getEaiServerIpListDB();
        		}
    			
        		logger.debug("[" + service + "]serverinfo:" + list);
                if( list != null ) {
                	for( Map<String,String> map : list ) {
                		String inst = map.get("EAISVRINSTNM");
                		String ip   = map.get("EAISVRIP");
                		String port = map.get("EAISVRLSNPORT");
                		String host = map.get("HOSTNAME");
                		sb.append(inst).append(FIELD_SEP);
                		sb.append(ip).append(FIELD_SEP);
                		sb.append(port).append(FIELD_SEP);
                		sb.append(host).append(LINE_SEP);
                	}
                	//out.print(sb.toString());
                }
        	} else if( "hostinfo".equals(type) ) {
//        		list : [{HOSTNAME=I12245, FAILOVERSVRNM=ALL, WEBSERVERPORT=null, EAISVRLSNPORT=30513, EAISVRINSTNM=EAIISG_i21, EAISVRIP=192.168.120.245}, 
//                      {HOSTNAME=I12245, FAILOVERSVRNM=ALL, WEBSERVERPORT=null, EAISVRLSNPORT=30514, EAISVRINSTNM=EAIISG_i22, EAISVRIP=192.168.120.245}]
//              hostinfo : I12245, 1, 0,0,0,0,0,0,0, 00, 0,0,0, 0, 0,0,0,0,0,0,0
//        		hostinfo : 호스트명,hostAlive,adapterAlive,sna,socket,mq,http,ejb,tuxedo,instanceAlive,cpu,mem,disk,procTotal,realTimeAlive,sna,socket,mq,http,ejb,tuxedo
        		
        		if (DataSourceTypeManager.BAT.equals(service)){
        			list = eaiServerInfoService.getBatServerIpList();
        		} else if (DataSourceTypeManager.BAP.equals(service)){
        				list = eaiServerInfoService.getBapServerIpList(); 
        		} else {
        			list = eaiServerInfoService.getEaiServerIpListDB();
        		}
        		logger.debug("[" + service + "]list:" + list);
        		
        		if( list == null ) {
        			// 에러처리
        			logger.error("New dashboard host list is null ! : cmd=hostinfo, service=" + service);
        			return null ;
        		}
        		
        		String backHost = "" ;
    			for( Map<String,String> map : list ) {
            		String inst = map.get("EAISVRINSTNM");
            		String ip   = map.get("EAISVRIP");
            		//String port = map.get("EAISVRLSNPORT");
            		String host = map.get("HOSTNAME");
            		
            		if( logger.isDebugEnabled() ) {
            			logger.debug("inst=" + inst + ", ip=" + ip + ", host=" + host );
            		}

            		//boolean isAlive = false;
            		// host 별로 작성하기 위해서 backHost 저장 후 이전 호스트와 다를 경우만 처리 함 
            		if( ! backHost.equals(host) ) {
            			backHost = host;
            			
            			// 0. 호스트명
            	        sb.append(host).append(FIELD_SEP);

                		// 1. host 에 해당하는 서버의 서버다운 여부
            	        String hostAlive = null ;
            	        if(ip != null){
            	        	hostAlive = dashboard2Repository.getHostAlive(ip) ;
            	        }

            			sb.append(hostAlive).append(FIELD_SEP);
            			
            			List<Map<String, String>> instList = null ;
            			if (DataSourceTypeManager.BAT.equals(service)){
            				if(host != null) { //취약점소스 수정 2020.08.25
	                	        instList = eaiServerInfoService.getBatServerIpListByHostName( host);
            				}
            			}else if (DataSourceTypeManager.BAP.equals(service)){
        					if(host != null) { //취약점소스 수정 2020.08.25
        						instList = eaiServerInfoService.getBapServerIpListByHostName( host);
        					}
            			} else {
            				if(host != null) { //취약점소스 수정 2020.08.25
	                	        instList = eaiServerInfoService.getEaiServerIpListByHostName( host);  
            				}
            			}
            			logger.debug("[" + service + "]instList:" + instList);

                		// 2. 어댑터 상태 : 전체 어댑터중 장애 상태의 어댑터 또는, 경고 상태 어댑터가 있는가?
            			AdaptersVO vo = null;  //취약점소스 수정 2020.08.26
            			if(instList != null){
            				vo = dashboardService.findAdapterStatusTotalList(instList);
            			}
            	       

            	        //          0:에러, 1:부분정상, 2:정상
            	        int sna    = vo.getSna(3);
            	        int socket = vo.getSocket2(3);
            	        int http   = vo.getHttp(3);
            	        int ejb    = vo.getEjb(3);
            	        int mq     = vo.getMq(3);
            	        int tuxedo = vo.getTuxedo(3);
            	        
            			if (DataSourceTypeManager.BAT.equals(service)){
            	        	// TODO : 배치는 socket(소켓2) 만 사용한다.
            	        	if( socket==0 ) {
            	        		sb.append("0");
            	        	} else if( socket==1 ) {
            	        		sb.append("1");
            	        	} else if( socket==2 ) {
            	        		sb.append("2");
            	        	} else {
            	        		sb.append("3");
            	        	}
            	        } else {
            	        	sb.append(vo.getTotal(3));
            	        }
            	        sb.append(FIELD_SEP);
            	        sb.append(sna).append(FIELD_SEP);
            	        sb.append(socket).append(FIELD_SEP);
            	        sb.append(mq).append(FIELD_SEP);
            	        sb.append(http).append(FIELD_SEP);
            	        sb.append(ejb).append(FIELD_SEP);
            	        sb.append(tuxedo).append(FIELD_SEP);
            	        
            	        //일괄전송 192.168.68.41   ieaapdi1_svc   참고
                		// 3. 인스턴스 상태 :  인스턴스 상태가 RUNNING 인가?
            	        // 0: 중지, 2: 정상
            	        List<EAIEngineStatusVo> engineList = dashboardService.findEngineStatus(instList, true);
            	        String stat = "" ;
            	        for( EAIEngineStatusVo engineVo : engineList ) {
            	        	engineVo.getInstanceName();
            	        	engineVo.getHostName();
            	        	engineVo.getServerState(); // RUNNING
            	        	if( "2".equals( engineVo.getServerState() )) {
            	        		stat += "1" ;
            	        	} else {
            	        		stat += "0" ;
            	        	}
            	        }

                		// 4. cpu, memory, disk 점유율
                        HostStatusVo hostVo = null;
                        if(instList != null){//취약점소스 수정 2020.08.26
                        	 hostVo = dashboardService.findHostStatus(instList);
                        }
                       
                        
//                        if (DataSourceTypeManager.BAT.equals(service) || DataSourceTypeManager.BAP.equals(service)){ //메모리 정보가 있을경우  상태값 정상
//                        	if(hostVo != null)
//                        		stat = "1";
//                        }
                        
                        sb.append(stat).append(FIELD_SEP);
                       
                        
                        // cpu,mem,disk 값이 100 이상이면 자릿수가 깨지므로
                        // 최대값을 99로 제한한다. 
                        int cpu = hostVo.getCpu() ;
                        int mem = hostVo.getMemory() ;
                        int disk = hostVo.getDisk() ;
                        
                        if( cpu > 99 ) {
                        	cpu = 99 ;
                        }
                        if( mem > 99 ) {
                        	mem = 99 ;
                        }
                        if( disk > 99 ) {
                        	disk = 99 ;
                        }
                        
                        sb.append(cpu).append(FIELD_SEP);
                        sb.append(mem).append(FIELD_SEP);
                        sb.append(disk).append(FIELD_SEP);

                		// 4. Host별 거래처리건수
            			if (DataSourceTypeManager.BAT.equals(service)){
                        	String tmp = dashboard2Repository.getProcEaiBatch();
                        	if( tmp == null ) tmp = "0,0,0,0" ;
                        	String tmpProc[] = tmp.split(",");
                        	int batchProcSum = 0 ;
                        	if( tmpProc.length > 1 ) {
                        		//총 거래 = 정상송신 + 에러송신 + 대기송신
                        		int sendN = CommonUtil.getInt(tmpProc[0]);
                        		int sendE = CommonUtil.getInt(tmpProc[2]);
                        		int sendQ = CommonUtil.getInt(tmpProc[4]);
                        		batchProcSum = sendN + sendE + sendQ ;
                        	}
                    		sb.append(batchProcSum).append(FIELD_SEP);
                        } else {
                            MemStaticsVo mvo = dashboard2Repository.getMemTradeVoByHost(host, list);                        
                            sb.append(mvo.getProcTotal()).append(FIELD_SEP);
                        }

                		// 5. 24시업무대상어댑터 상태 : 전체 어댑터중 장애 상태의 어댑터 또는, 경고 상태 어댑터가 있는가?
            	        RealTimeAdaptersVO rtVO = null;  //취약점소스 수정 2020.08.26
            	        if(instList != null) {
            	        	rtVO = dashboardService.findRTAdapterStatusTotalList(instList);
            	        }
            	        //          0:에러, 1:부분정상, 2:정상
            	        sna    = rtVO.getSna(3);
            	        socket = rtVO.getSocket2(3);
            	        http   = rtVO.getHttp(3);
            	        ejb    = rtVO.getEjb(3);
            	        mq     = rtVO.getMq(3);
            	        tuxedo = rtVO.getTuxedo(3);
            	        
            			if (DataSourceTypeManager.BAT.equals(service)){
            	        	// TODO : 배치는 socket(소켓2) 만 사용한다.
            	        	if( socket==0 ) {
            	        		sb.append("0");
            	        	} else if( socket==1 ) {
            	        		sb.append("1");
            	        	} else if( socket==2 ) {
            	        		sb.append("2");
            	        	} else {
            	        		sb.append("3");
            	        	}
            	        } else {
            	        	sb.append(rtVO.getTotal(3));
            	        }
            	        sb.append(FIELD_SEP);
            	        sb.append(sna).append(FIELD_SEP);
            	        sb.append(socket).append(FIELD_SEP);
            	        sb.append(mq).append(FIELD_SEP);
            	        sb.append(http).append(FIELD_SEP);
            	        sb.append(ejb).append(FIELD_SEP);
            	        sb.append(tuxedo);
            	        
            	        sb.append(LINE_SEP);
            		}  // backhost if
    			}  // end for
//    			("######" + sb.toString());
    			logger.info("hostinfo:[" + sb.toString() + "]");
    			
        	} else if( "traninfo".equals(type) ) {
        		// DB 에서 주기적으로 조회하여 지정한 테이블에 업데이트 하고,
        		// 업데이트된 결과를 조회하는 로직으로 처리하자. ( 테이블 설계 및 신청 필요 ) 
        		// 내부,대외,공동,DMZ,합계,일괄전송
        		// 서비스,거래처리,증가,timeout,증가,에러,증가

        		HashMap<String, MemStaticsVo> memStaticsVos = new HashMap<String, MemStaticsVo>();
        		for(DataSourceType dataSourceType : DataSourceTypeManager.getOnlineDataSourceTypes()){
        			DataSourceContextHolder.setDataSourceType(dataSourceType);
        			String typeName = dataSourceType.getName();
    				memStaticsVos.put(typeName, dashboard2Repository.getMemTradeVoByService(typeName));
        		}
        		
        		int procTotal = 0;
    			int timeoutTotal = 0;
    			int errorTotal = 0;
    			int syserrorTotal = 0;
    			
        		if( "ALL".equals(tradeTarget) ) {
        			for (String key : memStaticsVos.keySet()) {
        				MemStaticsVo memStaticsVo = memStaticsVos.get(key);
        				
        				sb.append((String) key).append(FIELD_SEP);
            			sb.append(memStaticsVo.getProcTotal()).append(FIELD_SEP);
            			sb.append(memStaticsVo.getTimeoutTotal()).append(FIELD_SEP);
            			sb.append(memStaticsVo.getErrorTotal()).append(FIELD_SEP);
            			sb.append(memStaticsVo.getSysErrorTotal());
            			sb.append(LINE_SEP);
            			
            			procTotal += memStaticsVo.getProcTotal();
            			timeoutTotal += memStaticsVo.getTimeoutTotal();
            			errorTotal += memStaticsVo.getErrorTotal();
            			syserrorTotal += memStaticsVo.getSysErrorTotal();
        			}
        		} else {
        			MemStaticsVo memStaticsVo = memStaticsVos.get(tradeTarget);
        			
        			sb.append(tradeTarget).append(FIELD_SEP);
        			sb.append(memStaticsVo.getProcTotal()).append(FIELD_SEP);
        			sb.append(memStaticsVo.getTimeoutTotal()).append(FIELD_SEP);
        			sb.append(memStaticsVo.getErrorTotal()).append(FIELD_SEP);
        			sb.append(memStaticsVo.getSysErrorTotal());
        			sb.append(LINE_SEP);
        			
        			procTotal = memStaticsVo.getProcTotal();
        			timeoutTotal = memStaticsVo.getTimeoutTotal();
        			errorTotal = memStaticsVo.getErrorTotal();
        			syserrorTotal += memStaticsVo.getSysErrorTotal();
        		}
        		
        		sb.append("TOTAL").append(FIELD_SEP);
    			sb.append(procTotal).append(FIELD_SEP);
    			sb.append(timeoutTotal).append(FIELD_SEP);
    			sb.append(errorTotal).append(FIELD_SEP);
    			sb.append(syserrorTotal);
    			sb.append(LINE_SEP);
    			
    			//일괄전송
        		String batchCount = DataSourceTypeManager.BAP + FIELD_SEP + dashboard2Repository.getProcBatch();
        		sb.append( batchCount );
    			sb.append(LINE_SEP);

    			//배치
        		String batchCount2 = DataSourceTypeManager.BAT + FIELD_SEP + dashboard2Repository.getProcEaiBatch();
        		sb.append( batchCount2 );
        		if( logger.isDebugEnabled() ) {
        			logger.debug( sb.toString() );
        		}
        		
        		// 상황실 근무자를 위해 매일 밤 23시58분 부터 거래건수 정보를 Export 한다.
        		String now = CommonUtil.getToday("") ;
        		int test = CommonUtil.getInt(now.substring(8,12)) ;
        		if( test > 2357 ) {
        			String strReport = sb.toString();
        			
        			for(DataSourceType dataSourceType : DataSourceTypeManager.getOnlineDataSourceTypes()){
        				strReport = strReport.replace(dataSourceType.getName(), dataSourceType.getText());
        			}

        			strReport = strReport.replace(DataSourceTypeManager.BAP, "일괄전송");
        			strReport = strReport.replace(DataSourceTypeManager.BAT, "배치");
        			
        			logger.debug("거래건수누계 : " +  strReport );
        		}
        		
        	} else if( "peakinfo".equals(type) ) {
        		String peakStat = ServletRequestUtils.getStringParameter(request, "peakstat", "tps");
        		
        		String tps ="";

        		if( "tps".equals(peakStat) ) { // tps
        			for (DataSourceType d : DataSourceTypeManager.getOnlineDataSourceTypes()){
        				tps += dashboard2Repository.getPeakTps(d.getName());
        				tps += ";";
        			}
        			DataSourceType bap = DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.BAP);
        			if(bap == null) {
        				tps += "0;";
        			}
        			else {
        				tps += dashboard2Repository.getPeakTps(bap.getName());
        				tps += ";";
        			}
        			
        			DataSourceType bat = DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.BAT);
        			if(bat == null) {
        				tps += "0;";
        			}
        			else {
        				tps += dashboard2Repository.getPeakTps(bat.getName());
        				tps += ";";
        			}
       			
        		} else { // trade
        			
        			for (DataSourceType d : DataSourceTypeManager.getOnlineDataSourceTypes()){
        				tps += dashboard2Repository.getPeakTrade(d.getName());
        				tps += ";";
        			}
        			DataSourceType bap = DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.BAP);
        			if(bap == null) {
        				tps += "0;";
        			}
        			else {
        				tps += dashboard2Repository.getPeakTrade(bap.getName());
        				tps += ";";
        			}
        			
        			DataSourceType bat = DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.BAT);
        			if(bat == null) {
        				tps += "0;";
        			}
        			else {
        				tps += dashboard2Repository.getPeakTrade(bat.getName());
        				tps += ";";
        			}
        		}

        		logger.warn("peakinfo(peakStat=" + peakStat + ") =>" + tps );
        		
        		if( logger.isDebugEnabled() ) {
        			logger.debug("peakinfo(peakStat=" + peakStat + ") =>" + tps );
        		}
        		
        		String [] lines = tps.split(";");
        		for( int i = 0 ; i < lines.length ; i++ ) {
    				String data[] = lines[i].split(",");
    				if( data.length > 3 ) {
        				sb.append(data[0]).append(FIELD_SEP);
        				sb.append(data[1]).append(FIELD_SEP);
        				sb.append(data[2]).append(FIELD_SEP);
        				sb.append(data[3]).append(LINE_SEP);        					
    				}
        		}
        		
        	} else if( "smsinfo".equals(type) ) {
                List<SmsVO> totalSmsList = new LinkedList<SmsVO>();
        		for (DataSourceType d : DataSourceTypeManager.getOnlineDataSourceTypes()){
        			DataSourceContextHolder.setDataSourceType(d);
                    List ipList = eaiServerInfoService.getEaiServerIpListDB();
                    List<SmsVO> smsList = dashboardService.findSmsList(ipList,d.getName());
                    totalSmsList.addAll(smsList);
        		}

                HashMap mapBack = new HashMap();
                List<String> tmpList = new ArrayList<String>(); 
                for ( SmsVO vo : totalSmsList ) {
                	//String svc = vo.getService();
                	//String name = ServiceType.get(svc).getName();
                	//String inst = vo.getInstanceName();
                	List<String> msgList = vo.getMessage();

                	for( String msg : msgList ) {
                		//  메시지 + @ + 서비스 + @ 인스턴스 ( 시간별로 sort 하기 위함 ) 
                		tmpList.add(msg ) ; //+ "@$@" + svc + "@$@" + inst );
                		mapBack.put(msg, vo);
                	}                	
                }
                
                Object sortList[] = tmpList.toArray();
                Arrays.sort(sortList);
                
                String smsBreaker = dashboardService.getSmsBreaker();
                if( "".equals(smsBreaker) ) {
                	smsBreaker = "0100 00:00:00" ;
                }
                
                if( logger.isDebugEnabled() ) {
                    logger.debug( "SMS_BREAKER=>[" + smsBreaker + "]" );                	
                }
                
                //월일
                String mmdd = CommonUtil.getToday("MMdd");
                int count = 10 ;
                for( int i = sortList.length - 1 ; i >= 0 ; i-- ) {
                	
                	if( count < 0 ) break;
                	
                	String msg = (String)sortList[i];
                	SmsVO voTmp = (SmsVO)mapBack.get(msg);
                	
                	String svc = voTmp.getService();
                	String name = "";
                	
                	logger.info("SMS MSG : " + msg );
                	
                	for(DataSourceType dataSourceType : DataSourceTypeManager.getOnlineDataSourceTypes()){
                		if (dataSourceType.getName().equals(svc)){
                			name = dataSourceType.getText();
                		}
                	}
                	
                	String inst = voTmp.getInstanceName();
                	
                	// 
                	if( msg == null || msg.length() < 17 ) {
                		continue;
                	}

                	// 당일 데이터가 아닌것은 제외한다.
//                	if( mmdd.compareTo(msg.substring(5,10).replace("-","")) > 0 ) {
            		if( mmdd.compareTo(msg.substring(0,4)) > 0 ) {
                		continue;
                	} 
                	
                	logger.info("SMS smsBreaker : " + smsBreaker );
                	
                	// Beaker time 보다 이전의 데이터는 제외한다.
                	if( msg != null && msg.length() > 13 ) {
                    	if ( smsBreaker.compareTo(msg.substring(0,13)) > -1 ) {
                    		//기준시간보다 이전이므로 제외합니다.
                    		continue;
                    	}                		
                	}
                	
                	
//                	Date dd = new Date();
//        	    	SimpleDateFormat dateF = new SimpleDateFormat("YYYY-MM-dd"); 
//        	    	String todate = "";
//        	    	Calendar cal = Calendar.getInstance();
//        	    	cal.setTime(dd);
//        	    	todate = dateF.format(cal.getTime());
                	
                	
                	logger.info("dashboard SMS_INFO ====>" + msg);

            		sb.append(name).append(FIELD_SEP);
            		sb.append(inst).append(FIELD_SEP);
            		sb.append(msg.substring(5,17)).append(FIELD_SEP);
            		sb.append(msg.substring(17)).append(LINE_SEP);
//            		if ( todate.compareTo(msg.substring(0,10)) > -1 ) { //당일시간만 찍히게 수정
//                	}
//            		else{
//                		sb.append("").append(FIELD_SEP);
//                		sb.append(msg).append(LINE_SEP);
//                		//sb.append(msg.substring(42)).append(LINE_SEP);
//                	}
            		
            		
                	count --;
                }
                
                logger.debug( "SMS_INFO====> [ " + sb.toString() + " ]" );
                logger.info( "SMS_INFO====> [ " + sb.toString() + " ]" );
    	} else if( "smsinit".equals(type) ) {
    		// monitoring/dashboard2.do?cmd=main&type=smsinit&initTime=00:00:00.000
    		String mmdd = CommonUtil.getToday("MMdd");
    		String initTime = ServletRequestUtils.getStringParameter(request, "initTime", CommonUtil.getToday("HH:mm:ss.SSS"));
    		
    		
    		if( initTime.length() == 12 || initTime.length() == 11 ) {
    			// MMdd hh:mm:ss
    			String lastTime = mmdd + " " + initTime.substring(0, 8);
    			dashboardService.setSmsBreaker( lastTime );
    		}
    		
    	}
        	
        	
        	// 자바스크립트 에서 split 처리할때 마지막에 구분자가 있음 배열이 하나 더 생기므로 trim 처리해서 보낸다.
			String outData = CommonUtil.rightTrim( sb.toString(), LINE_SEP );    			
			pw.print( outData );

       } catch ( Exception e ) {
    	   logger.error("mainProc error",e);
       }
        
        return null ;
    }

    
    @RequestMapping(path = "/dashboard2.do", params = "cmd=sub")
    public View subProc(ModelMap modelMap, HttpServletRequest request,
            HttpServletResponse response, String cmd, String type) {        
        try {

        	// 한글처리 관련
        	response.setContentType("text/xml;charset=utf-8"); 
        	response.setHeader("Cache-Control", "no-cache"); 
        	
            ServletOutputStream out = response.getOutputStream();
        	
        	StringBuffer sb = new StringBuffer();

    		String service = ServletRequestUtils.getStringParameter(request, "service", "");
    		String smstime = ServletRequestUtils.getStringParameter(request, "smstime", "");
    		
        	if((service.length() > 0) && 
        			DataSourceTypeManager.getDataSourceType(service) == null) {
        		logger.warn("New dashboard Skip subProc unregistered Service : service=" + service);
        		return null;
        	}
        	
        	String tradeTarget = (String)request.getSession().getAttribute(MonitoringContext.RMS_TRADE_COUNT_TARGET);
        	if( tradeTarget == null || "".equals(tradeTarget) ) {
        		tradeTarget = "ALL" ;
        	}

        	if( "traninfo".equals(type) ) {
        		// DB 에서 주기적으로 조회하여 지정한 테이블에 업데이트 하고,
        		// 업데이트된 결과를 조회하는 로직으로 처리하자. ( 테이블 설계 및 신청 필요 ) 
        		// 내부,대외,공동,DMZ,합계,일괄전송
        		// 서비스,거래처리,증가,timeout,증가,에러,증가
        		List<String> hostList = dashboard2Repository.getHostNames(service);
        		MemStaticsVo sumVo = new MemStaticsVo();
        		for( int i = 0 ; i < 4 ; i++ ) {
        			if( hostList != null && hostList.size() > i ) {
        				String host = hostList.get(i);
        				MemStaticsVo vo = dashboard2Repository.getMemTradeVoByHost(host);
        				if( vo == null ) {
            				sb.append( getSubTranLineData(tradeTarget, "NULL", vo, sumVo)).append(LINE_SEP);        					
        				} else {
            				sb.append( getSubTranLineData(tradeTarget, service, vo, sumVo)).append(LINE_SEP);        					
        				}
        			} else {
        				sb.append( getSubTranLineData(tradeTarget, "NULL", null, sumVo)).append(LINE_SEP);
        			}
        		}        		
        		sb.append( getSubTranLineData(tradeTarget, "TOTAL", null, sumVo)).append(LINE_SEP);
        	} else if( "smsinfo".equals(type) ) {
        		// 해당 서비스의 에러메시지 정보를 보낸다.
        		
                List serverList = eaiServerInfoService.getEaiServerIpListDB();
                List<SmsVO> smsList = dashboardService.findSmsList(serverList, service);

                HashMap mapBack = new HashMap();
                List<String> tmpList = new ArrayList<String>(); 
                for ( SmsVO vo : smsList ) {
                	//String svc = vo.getService();
                	//String name = ServiceType.get(svc).getName();
                	//String inst = vo.getInstanceName();
                	List<String> msgList = vo.getMessage();
                	
                	for( String msg : msgList ) {
                		//  메시지 + @ + 서비스 + @ 인스턴스 ( 시간별로 sort 하기 위함 ) 
                		tmpList.add(msg ) ; //+ "@$@" + svc + "@$@" + inst );
                		mapBack.put(msg, vo);
                	}                	
                }
                
                Object sortList[] = tmpList.toArray();
                Arrays.sort(sortList);
                
                String smsBreaker = dashboardService.getSmsBreaker();
                if( "".equals(smsBreaker) ) {
                	smsBreaker = "0100 00:00:00" ;
                }
                
                if( logger.isDebugEnabled() ) {
                    logger.debug( "SUB SMS_BREAKER=>[" + smsBreaker + "]" );                	
                }
                
                //월일
                String mmdd = CommonUtil.getToday("MMdd");
                int count = 2 ;
                for( int i = sortList.length - 1 ; i >= 0 ; i-- ) {
                	
                	if( count < 0 ) break;
                	
                	String msg = (String)sortList[i];
                	SmsVO voTmp = (SmsVO)mapBack.get(msg);
                	
                	String svc = voTmp.getService();
                	String name = "";
                	
                	for(DataSourceType dataSourceType : DataSourceTypeManager.getOnlineDataSourceTypes()){
                		if (dataSourceType.getName().equals(svc)){
                			name = dataSourceType.getText();
                		}
                	}
                	String inst = voTmp.getInstanceName();
                	
                	// 당일 데이터가 아닌것은 제외한다.
                	if( ! mmdd.equals( msg.substring(0,4) ) ) {
                		continue;
                	}
                	
                	// Beaker time 보다 이전의 데이터는 제외한다.
                	if( msg != null && msg.length() > 13 ) {
                    	if ( smsBreaker.compareTo(msg.substring(0,13)) > -1 ) {
                    		//"기준시간보다 이전이므로 제외합니다.
                    		continue;
                    	}                		
                	}

            		sb.append(name).append(FIELD_SEP);
            		sb.append(inst).append(FIELD_SEP);
            		sb.append(msg.substring(5,17)).append(FIELD_SEP);
            		sb.append(msg.substring(17)).append(LINE_SEP);
                	
                	count --;
                }        		
        		// instance,date,message ( 메시지 내부의 콤마,세미콜론 은 마침표,콜론으 로 replace 한다. )
        	} else if( "smserr".equals(type) ) {
         		String dsName = "" ;
         		
         		if( logger.isDebugEnabled() ) {
         			logger.debug( "type=smserr => dsName=" + dsName + ", schema=" + service + ", smstime=" + smstime  );
         		}
         		
         		Vector ret = getErrorInfo(service, smstime );
         		
         		for(int i=0; i< ret.size(); i++) {
         			String[] row = (String[])ret.get(i);
         			
         			if( logger.isDebugEnabled() ) {
         				logger.debug( row );
         			}         			
         			
         			//노드와 인스턴스 번호 추출
         			int nodeNo = 0;
         			int instNo = 0;

                	List<Map<String, String>> list = eaiServerInfoService.getEaiServerIpListDB();
        			logger.debug(list);
        			for( int idx=0; idx < list.size(); idx++ ) {
        				Map<String, String> map = list.get(idx);
                		String host = map.get("HOSTNAME");
                		logger.debug("nodeNo추출 :[" + host + "][" + row[10].trim() + "]");
                		if( host != null && (host.equals(row[10].trim()))) {  //취약점소스 수정 2020.08.25
                			nodeNo = idx+1;
                		}
        			}

        			List<Map<String, String>> instList = eaiServerInfoService.getEaiServerIpListByHostName( row[10].trim());
        			logger.debug(instList);
        			for( int idx=0; idx < instList.size(); idx++ ) {
        				Map<String, String> map = instList.get(idx);
                		String inst = map.get("EAISVRINSTNM");
                		logger.debug("instNo추출 :[" + inst + "][" + row[9].trim() + "]");
                		if( inst != null && (inst.equals(row[9].trim()))) { //취약점소스 수정 2020.08.25
                			instNo = idx+1;
                		}
        			}
         			
         			
         			for(int j=0; j<row.length; j++) {
	         			sb.append(row[j].replaceAll(FIELD_SEP, " ").replaceAll(LINE_SEP," "));
	         			if(j == (row.length-1) ) {
	         				sb.append(FIELD_SEP);
	         				sb.append(nodeNo);
	         				sb.append(FIELD_SEP);
	         				sb.append(instNo);
	         				sb.append(LINE_SEP);
	         			}
	         			else {
	         				sb.append(FIELD_SEP);
	         			}
         			}
         		}
        	} else if( "smsinit".equals(type) ) {
        		String mmdd = CommonUtil.getToday("MMdd");
        		String initTime = ServletRequestUtils.getStringParameter(request, "initTime", "");
        		
        		if( initTime.length() == 12 || initTime.length() == 11 ) {
        			// MMdd hh:mm:ss
        			String lastTime = mmdd + " " + initTime.substring(0, 8);
        			dashboardService.setSmsBreaker( lastTime );
        		}        		
        	}
     		
        	
			// 자바스크립트 에서 split 처리할때 마지막에 구분자가 있음 배열이 하나 더 생기므로 trim 처리해서 보낸다.
			String outData = CommonUtil.rightTrim( sb.toString(), LINE_SEP );    			
			out.print( outData );
       } catch ( Exception e ) {
          // e.printStackTrace();
    	  logger.error("subProc",e);
       }
        
        return null ;
    }
    
    private String getSubTranLineData( String target, String svc, MemStaticsVo vo, MemStaticsVo total ) {
    	StringBuffer sb = new StringBuffer();
    	
    	sb.append(svc).append(FIELD_SEP);
    	
    	if( "NULL".equals(svc) ) {
    		sb.append(0).append(FIELD_SEP);
    		sb.append(0).append(FIELD_SEP);
    		sb.append(0).append(FIELD_SEP);
    	} else if( "TOTAL".equals(svc) ) { 
    		sb.append(total.getProcTotal()).append(FIELD_SEP);
    		sb.append(total.getTimeoutTotal()).append(FIELD_SEP);
    		sb.append(total.getErrorTotal()).append(FIELD_SEP);
    	} else if( "ALL".equals(target) ) {
    		if(vo != null){
    			sb.append(vo.getProcTotal()).append(FIELD_SEP);
        		sb.append(vo.getTimeoutTotal()).append(FIELD_SEP);
        		sb.append(vo.getErrorTotal()).append(FIELD_SEP);
    		}else{
    			sb.append(0).append(FIELD_SEP);
        		sb.append(0).append(FIELD_SEP);
        		sb.append(0).append(FIELD_SEP);
    		}
    		total.add( vo );
    	} else {
    		if(vo != null){
	    		sb.append(vo.getProcTotal()).append(FIELD_SEP);
	    		sb.append(vo.getTimeoutTotal()).append(FIELD_SEP);
	    		sb.append(vo.getErrorTotal()).append(FIELD_SEP);
    		}else{
    			sb.append(0).append(FIELD_SEP);
        		sb.append(0).append(FIELD_SEP);
        		sb.append(0).append(FIELD_SEP);
    		}
    		
    		total.add( vo );    		
    	}
    	
    	return sb.toString();
    }
    
    
//    private String getTranLineData( String service, DbStaticsVo vo ) {
//		
//    	// 서비스,거래처리,timeout,에러				
//
//    	StringBuffer sb = new StringBuffer();    	
//		
//    	sb.append(service).append(FIELD_SEP);
//		sb.append(vo.getEaiMoniPrcssNoitm()).append(FIELD_SEP);
//		sb.append(vo.getEaiMoniToutNoitm()).append(FIELD_SEP);
//		sb.append(vo.getEaiMoniErrNoitm()).append(FIELD_SEP);
//		
//		return sb.toString();
//    }
    
    
    
//    private String getTranLineDataBatch( String service, int[] counts ) {
//    	StringBuffer sb = new StringBuffer();
//    	sb.append(service).append(FIELD_SEP);
//    	if( counts == null ) {
//    		for( int i = 0 ; i < 6 ; i++ ) {
//    			sb.append(0).append(FIELD_SEP);
//    		}
//    	} else {
//        	for( int i = 0 ; i < counts.length ; i++ ) {
//        		sb.append(counts[i]).append(FIELD_SEP);
//        	}    		
//    	}
//    	
//    	return sb.toString();
//    }
    
//	private Connection getConnection(String dataSourceName) throws Exception {
//		Connection con = null;
//		try {
//			InitialContext ic = new InitialContext();
//			DataSource dataSource = (DataSource) ic.lookup(dataSourceName);
//			con = dataSource.getConnection();
//			return con;
//		}
//		catch(Exception e) {
//			//e.printStackTrace();
//			logger.error("getConnection ",e);
//			throw e;
//		}
//	}
	
	private Vector getErrorInfo(String owner, String logTime ) throws Exception {
		
		String today = CommonUtil.getToday("yyyyMMdd");
		
		logTime = today + logTime.replaceAll("\\.", "").replaceAll(":", "");

		String beforeTime = CommonUtil.getDiffMinDate( logTime, -1, "");
				
		String tableName = CommonUtil.getLogErrTable(CommonUtil.getToday(""));
		
		return dashboardDao.getErrorInfo(owner, tableName, logTime, beforeTime);
		
	}
	
	private String getTargetService() {
        String local = "";
        try {
            InetAddress addr = InetAddress.getLocalHost();
            local = addr.getHostAddress();
        } catch ( UnknownHostException e ) {
        	logger.error(e);
        	//e.printStackTrace();
        }
        
        // 타겟서비스에 해당하는 DB 의 거래현황 데이터를 읽어서 해당DB 의 RM11 테이블에 집계데이터를 추가한다.
        // ALL : 온라인용 ( 전체 서비스 )
        // OUTSIDE : 테스트용  ( ZAUA - 192.168.175.82 )
        // COMMON  : 테스트용  ( ZAPA - 192.168.175.54 )
        // 현재 사용되고 있지 않은곳이 내부(ZADA) 이므로 일단 ALL 데이터는 ZADA 로 WRITE 한다.
        String targetSvc = "ALL" ;
        String target = monitoringContext.getStringProperty(MonitoringContext.RMS_TRADE_COUNT_TARGET, "");
        String arrTmp[] = target.split(",");
        if( arrTmp != null && arrTmp.length > 0 ) {
        	for( int i = 0 ; i < arrTmp.length ; i++ ) {
        		String arrTmp2[] = arrTmp[i].split("=");
        		if( arrTmp2 != null && arrTmp2.length == 2 && local.equals(arrTmp2[0]) ) {
        			targetSvc = arrTmp2[1];
        			break;
        		}
        	}
        }
        
        return targetSvc ;		
	}
}
