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

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;

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.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;

import com.eactive.eai.rms.common.context.MonitoringContext;
import com.eactive.eai.rms.common.util.CommonUtil;
import com.eactive.eai.rms.common.util.ItsmSmsSender;
import com.eactive.eai.rms.onl.manage.serviceinfo.firstaccount.FirstAccountService;

public class FirstAccountServerJob  implements Job {
    /**
    * Logger for this class
    */
	
    private static final Logger logger = Logger.getLogger(FirstAccountServerJob.class);
    
    @Autowired
    @Qualifier("firstAccountService")
    private FirstAccountService firstAccountService; 
    
    private transient MonitoringContext monitoringContext;
    
    @Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
    	
    	if(logger.isInfoEnabled()) logger.info("START FirstAccountServerJob");
        //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 ;
   		}  
   		
   		firstAccountService  = (FirstAccountService)appContext.getBean("firstAccountService");
   		monitoringContext    = (MonitoringContext)appContext.getBean("monitoringContext");	
		try {

			int port = Integer.parseInt(monitoringContext.getStringProperty(MonitoringContext.FIRSTACCOUNT_PORT,"8888"));
			ServerSocket serverSocket = null;
			int clientNumber = 0;
			try {
				serverSocket = new ServerSocket(port);
				if(logger.isInfoEnabled()) logger.info("Start FirstAccountServer Socket : " + port);
				while (true) {
					// client 접속 accept
					if(logger.isInfoEnabled()) logger.info("Start FirstAccountServer accept");
					Socket socket = serverSocket.accept();
					if(logger.isInfoEnabled()) logger.info("Start FirstAccountServer connect");
					
					Worker worker = new Worker(socket, clientNumber++);
					Thread t = new Thread(worker);
					t.start();
				}
			} catch (Exception e) {
				logger.warn("accept error" + e.getMessage());
			} finally {
				if (serverSocket != null)
					try {
						serverSocket.close();
					} catch (IOException e) {
						;
					}
			}
			if(logger.isInfoEnabled()) logger.info("FirstAccountServer Stopped.");
		
			
		}catch(Exception e){
			logger.error("FirstAccountServerJob error : ",e);
		}
    }
    
	private class Worker implements Runnable {
		private Socket socket;
		private int clientNumber;

		public Worker(Socket socket, int clientNumber) {
			this.socket = socket;
			this.clientNumber = clientNumber;
			if(logger.isInfoEnabled()) logger.info("New connection with client# " + this.clientNumber  + " at" + socket);
		}

		public void run() {
			InputStream in = null;

			try {
				in = socket.getInputStream();
				
				byte[] llBytes = new byte[4];

				in.read(llBytes);
				int llsize = Integer.parseInt(new String(llBytes));

				byte[] body = null;
				 if (0 <= llsize && llsize <= 4096) {
					 body = new byte[llsize];
				 }
				

				if(logger.isInfoEnabled()) logger.info("Start Server read header = " + llsize);

				in.read(body);
				if(logger.isInfoEnabled()) logger.info("Start Server read body = " + new String(body));
				

				String sendMsg = new String(body);
				if(logger.isInfoEnabled()) logger.info("sendMsg1 = " + sendMsg);
				// M/F에서 EAI로 전달할때 LL+;+계좌번호+;+계좌번호.. 형태라 처음 LL바이트 이후 ; 을 제거하는
				// 로직
				if (sendMsg.substring(0, 1).equals(";")) {
					sendMsg = sendMsg.substring(1);
				}

				if(logger.isInfoEnabled()) logger.info("sendMsg = " + sendMsg);

				if (!sendMsg.equals("1111")) {

					if(logger.isInfoEnabled()) logger.info("--------------------------------- 통제계좌 접수 -------------------------------"
							+ "\n" + sendMsg);

					// 정상적으로 동기화 하면 파일 Flag 를 변경한다
					 if(firstAccountService.syncWithFW(sendMsg)==0){
							if(true){
								String beforeMsg = firstAccountService.accountChkMsg();
								if(logger.isInfoEnabled()) logger.info("job beforeMsg : " + beforeMsg);
								
								firstAccountService.writeMsg(sendMsg);
								
								// 전송받은 값이 0000이고, 기존 값이 0000 이 아닐때 거래집중화 계좌 해제임
								if (sendMsg.equals("0000") && beforeMsg.equals("0000")) {
									if(logger.isInfoEnabled()) logger.info("일일 집중계좌 상태 체크 : " + sendMsg);
								} else if (sendMsg.equals("0000")) {
									if(logger.isInfoEnabled()) logger.info("거래집중화 초기화 완료" + sendMsg);
									 sendSMS("거래집중화 초기화 완료 :"+sendMsg+"|"+CommonUtil.getToday("MM월dd일HH시mm분ss초"));
								} else {
									if(logger.isInfoEnabled()) logger.info("거래집중화 계좌 발생" + sendMsg);
									 sendSMS("거래집중화 계좌 발생 :"+sendMsg+"|"+CommonUtil.getToday("MM월dd일HH시mm분ss초"));
								}
							}
					}else{
						sendSMS("거래집중화 계좌 발생하였으나 EAI 메모리 동기화 실패:"+sendMsg+"|"+CommonUtil.getToday("MM월dd일 HH시mm분ss초"));
					}
				} 
				else {
					if(logger.isInfoEnabled()) logger.info("통신망 전문 수신 완료.");
				}

			} catch (Exception e) {
				logger.warn("run error" + e.getMessage());
			} finally {
				if(in != null){ //취약점소스 수정 2020.08.27
					try {
						 in.close();
					} catch (IOException e) {
						logger.warn("IOException error" + e.getMessage());
					}
				}
				
				if (socket != null)
					try {
						socket.close();
					} catch (IOException e) {
						logger.warn("socket close error" + e.getMessage());
					}
			}
			if(logger.isInfoEnabled()) logger.info("Start Server Stopped.");
		}
	}
	
	public void sendSMS(String msg) {
		String sms_ip = monitoringContext.getStringProperty(MonitoringContext.ITSMPERM_IP,"");
		String sms_port = monitoringContext.getStringProperty(MonitoringContext.ITSMPERM_PORT,"");

		HashMap<String, String> map = new HashMap<>();
		map.put("ItsmPermIP", sms_ip);
		map.put("ItsmPermPORT", sms_port);
		ItsmSmsSender.sendGroupSMS(map,ItsmSmsSender.EAI_GRP_MODE, ItsmSmsSender.EAI_GRP_MODE, msg);
	}

	
			
}
