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


import java.io.InputStream;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;
import java.util.SimpleTimeZone;

import org.apache.commons.httpclient.DefaultMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
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.onl.manage.comm.unifbwk.UnifbwkManService;

public class IqmsAppCdMappingJob implements Job{
	
    private static final Logger logger = Logger.getLogger(IqmsAppCdMappingJob.class);
    
    @Autowired
    private UnifbwkManService unifbwkManService; 
    
    private transient MonitoringContext monitoringContext;
    
	// 매일 자정 15분 에 업무구분코드  정보를 업데이트 한다.
    @Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
    	
    	if(logger.isInfoEnabled()) logger.info("START IqmsAppCdMappingJob");
    //    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 ;
   		}  
		unifbwkManService = (UnifbwkManService)appContext.getBean("unifbwkManService");	
		monitoringContext    = (MonitoringContext)appContext.getBean("monitoringContext");	
    		
		 //URL 가져오기 프로퍼티 변경
        String eaiUrl = "";
        String appUrl = "";
        
    	//프로퍼티 가져오기 테스트
		try {
			//모니터링 데이터소스 셋팅
			eaiUrl = monitoringContext.getStringProperty(MonitoringContext.IQMS_EAI_URL);
			appUrl = monitoringContext.getStringProperty(MonitoringContext.IQMS_APP_URL);
			
			if(eaiUrl == null || appUrl == null) {
				throw new Exception("IQMS 연동 프파퍼티가 등록되지 않았습니다.");
			}
			
			eaiUrl = eaiUrl.replace("$DATE", getCurrentDate());
			appUrl = appUrl.replace("$DATE", getCurrentDate());
			
			logger.info("IQMS eaiUrl : "+eaiUrl);
			logger.info("IQMS appUrl : "+appUrl);
	    	
	        List<String> rsList = new ArrayList<String>();
	        String[] arr = null;
			HashMap<String, String> dataMap = new HashMap<String, String>();
        
			//EAI  URL 호출
			rsList = iqmsUrlCall(eaiUrl);
			
			for(DataSourceType d : DataSourceTypeManager.getOnlineDataSourceTypes() ) {
				if(logger.isInfoEnabled()) logger.info("DataSourceTypeManager d : "+d);
		  		DataSourceContextHolder.setDataSourceType(d);
		  		for(String listtmp : rsList){
	  				if(listtmp.startsWith("DATA")){
	  					listtmp += "E";
	  					arr = listtmp.split("#[|]@");
	  					dataMap = new HashMap<>();
  						dataMap.put("eaiBzwkDstcd", arr[3]); //EAI업무구분코드
  						dataMap.put("bzwkDsticName", arr[4]); //업무구분명
  	  					dataMap.put("applCd", arr[5]);  //어플리케이션코드값
  	  					dataMap.put("bzwkDsticDesc", arr[6]); //업무구분설명
  	  					//부서명, 팀명 TSEAIRM02 USERID 와 조인해서 부여주기로.. 김소희차장님 요청
						dataMap.put("trackAsisKey1Name", arr[15]); //부서명
	  					dataMap.put("trackAsisKey2Name", arr[16]); //팀명
	  					dataMap.put("rsEmpName", arr[11]);//담당자명
	  					dataMap.put("rsPblpsncntpcTnt", arr[14]); //담당자연락처내용 (USERID)
						dataMap.put("groupCoCd", "KB0"); //그룹회사코드
						dataMap.put("discardDate", arr[9]);//폐기년월일
						dataMap.put("inputDstCd", "EAI");//입력구분값 2020.02.20 컬럼추가
	  					//if(logger.isInfoEnabled()) logger.info("EAI eaiBzwkDstcd : "+dataMap.get("eaiBzwkDstcd").toString());
	  					dataProcessEai(dataMap,d);
	  				}
	  			}
				
		  	}
			
			//APP URL 호출
			HashMap<String, String> appDataMap = new HashMap<String, String>();
			String[] appDataArr = null;
			rsList = new ArrayList<String>();
			rsList = iqmsUrlCall(appUrl);
			
			for( DataSourceType d : DataSourceTypeManager.getOnlineDataSourceTypes() ) {
		  		DataSourceContextHolder.setDataSourceType(d);
				for(String listtmp : rsList){
		  				if(listtmp.startsWith("DATA")){
		  					listtmp += "E";
		  					appDataArr = listtmp.split("#[|]@");
		  					appDataMap.put("eaiBzwkDstcd", appDataArr[3]); //EAI업무구분코드   
	  						appDataMap.put("bzwkDsticName", appDataArr[4]); //업무구분명
	  						appDataMap.put("applCd", appDataArr[3]);        //어플리케이션코드값
	  						appDataMap.put("bzwkDsticDesc", appDataArr[4]); //업무구분설명
	  						//부서명, 팀명 TSEAIRM02 USERID 와 조인해서 부여주기로.. 김소희차장님 요청
	  						appDataMap.put("rsEmpName", appDataArr[7]);     //담당자명
	  						appDataMap.put("rsPblpsncntpcTnt", appDataArr[6]); //담당자연락처내용   (USERID)
	  						appDataMap.put("groupCoCd", "KB0");			//그룹회사코드
	  						appDataMap.put("discardDate", appDataArr[10]); //폐기년월일	
	  						appDataMap.put("inputDstCd", "APP");//입력구분값 2020.02.20 컬럼추가
		  					
		  					dataProcess(appDataMap,d);
		  					
		  				}
		  			}
				
			}
			
			if(logger.isInfoEnabled()) logger.info("END IqmsAppCdMappingJob");
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			logger.error("IQMS error : ",e);
		}
		
				
	}
	
	public List<String> iqmsUrlCall(String url) throws Exception{

    	MultiThreadedHttpConnectionManager cm = new MultiThreadedHttpConnectionManager();
        cm.setConnectionStaleCheckingEnabled(false);
        cm.setMaxConnectionsPerHost(10);
        cm.setMaxTotalConnections(1);

        HttpClientParams params = new HttpClientParams();
        params.setSoTimeout(10 * 1000);
        HttpClient client = new HttpClient(params, cm); 
        //---------------------------------------------
        if(logger.isInfoEnabled()) logger.info("iqmsUrlCall "+url);
        PostMethod method = new PostMethod(url);
        DefaultMethodRetryHandler retryhandler = new DefaultMethodRetryHandler();
        retryhandler.setRequestSentRetryEnabled(false);
        retryhandler.setRetryCount(3);
        method.setMethodRetryHandler(retryhandler);
        
        method.getParams().setSoTimeout(5000);
        //method.addParameter("p_date1", getCurrentDate());
        
        
        int status = -1;
        List<String> dataList = new ArrayList<String>();
        
        try {
            status = client.executeMethod(method);
           // byte[] responseBytes = method.getResponseBody();
            //System.out.println("method.getRequestCharSet() [" + method.getRequestCharSet() +"]");
            //System.out.println("method.getResponseCharSet() [" + method.getResponseCharSet() +"]");
            //System.out.println("responseMessage [" +new String(responseBytes, method.getResponseCharSet()) +"]");
            //if(logger.isInfoEnabled())logger.info("method.getResponseCharSet() [" + method.getResponseCharSet() +"]");
            //if(logger.isInfoEnabled())logger.info("responseMessage [" +new String(responseBytes, method.getResponseCharSet()) +"]");
            
            InputStream is = method.getResponseBodyAsStream();
      		Scanner scan = new Scanner(is);
      		String str = "";
      		
  			while(scan.hasNext()){
  				str = scan.nextLine();
  				dataList.add(str);
  			}
  			scan.close();
//            System.out.println("ISO8859_1       [" + new String(responseBytes, "ISO8859_1")  +"]");
//            System.out.println("utf-8          [" + new String(responseBytes, "utf-8") +"]");
        } catch(ConnectException ce) {
        	logger.error("Connection Exception : " + ce.toString() );
        } catch(SocketTimeoutException ste) { // HttpClient 3.1일 경우에 발생
        	logger.error("SocketTimeoutException : " + ste.toString() );
        } catch(Exception e) {
        	logger.error("iqmsUrlCall error : ",e);
            //e.printStackTrace();
            throw e;
        } finally {
            method.releaseConnection();
            if(status != HttpStatus.SC_OK) {
            	if(logger.isInfoEnabled()) logger.info("HttpStatus ["+status+"]");
            }
            
        }
        
        return dataList;
	}
	
	
	public void dataProcessEai(HashMap<String, String> paramMap,DataSourceType targetSchema) throws Exception
    {
		long cnt = 0;
		
		// EAI 일경우  INPUTDSTCD가 APP 코드는 UPDATE X
		paramMap.put("selectType", "APP");
		
		paramMap.put("schemaId", targetSchema.getSchema());
		//APP 코드 존재하는지 판단
		cnt = unifbwkManService.selectCnt(paramMap);
		
		if(cnt == 0) { //APP 코드 존재안함
			long eaiCnt = 0;
			//EAI코드 존재 판단
			paramMap.put("selectType", "EAI");
			eaiCnt = unifbwkManService.selectCnt(paramMap); 
			
			if(eaiCnt > 0){
				unifbwkManService.updateIqms(paramMap);
			}else{
				unifbwkManService.insertIqms(paramMap);
			}
		}
    }
	
	
	public void dataProcess(HashMap<String, String> paramMap,DataSourceType targetSchema) throws Exception
    {
		long cnt = 0;
		
		// APP기준 insert update
		paramMap.put("schemaId", targetSchema.getSchema());
		cnt = unifbwkManService.selectCnt(paramMap);
		
		if(cnt > 0) { //update
			unifbwkManService.updateIqms(paramMap);
		}else{ //insert
			unifbwkManService.insertIqms(paramMap);
		}
    }
	
	public String getCurrentDate()
    {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); //yyyyMMddHHmmssSSS
        sdf.setTimeZone(new SimpleTimeZone(9 * 60 * 60 * 1000, "KST"));
        return sdf.format(new java.util.Date(System.currentTimeMillis()));
    }
}
