package com.engine.web.tjbk;

import com.engine.tjbankSocket.SocketExecute;
import com.engine.tjbankSocket.impl.CWGLSocketExecute;
import com.engine.tjbankSocket.impl.GetToCountSocketExecute;
import com.engine.util.XMLUtils;
import org.apache.commons.lang.StringEscapeUtils;
import weaver.general.BaseBean;
import weaver.general.StringUtil;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TjbkServerSocket implements ServletContextListener {
    private SocketThread socketThread;

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        // TODO Auto-generated method stub
        if (socketThread != null && socketThread.isInterrupted()) {
            socketThread.closeServerSocket();
            socketThread.interrupt();
        }
    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        // TODO Auto-generated method stub
        // new BaseBean().writeLog("contextInitialized启动");
        ServletContext servletContext = arg0.getServletContext();
        if (socketThread == null) {
            socketThread = new SocketThread(null, servletContext);
            socketThread.start(); // servlet上下文初始化时启动socket服务端线程
        }
    }

}


class SocketThread extends Thread {

    private ServletContext servletContext;
    private ServerSocket serverSocket;
    private ExecutorService executorService; // 线程池
    public static Logger logger = LoggerFactory.getLogger("ESBSocket");

    public SocketThread(ServerSocket serverSocket, ServletContext servletContext) {
        this.servletContext = servletContext;
        // 从web.xml中context-param节点获取socket端口
        String port = this.servletContext.getInitParameter("socketPort");
        if (serverSocket == null) {
            try {
                this.serverSocket = new ServerSocket(Integer.parseInt(port));
                // 创建固定大小的线程池
                this.executorService = Executors.newFixedThreadPool(10);

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void run() {

        while (!this.isInterrupted()) { // 线程未中断执行循环
            try {

                Socket socket = serverSocket.accept();
                if (socket != null) {
                    logger.error("SocketThread线程启动");
                    // new ProcessSocketData(socket, this.servletContext).start();
                    executorService.submit(new ProcessSocketData(socket, servletContext));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void closeServerSocket() {
        try {
            if (serverSocket != null && !serverSocket.isClosed()) {
                serverSocket.close();
                executorService.shutdown();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class ProcessSocketData implements Runnable {

    private Socket socket;
    private ServletContext servletContext;
    private Logger logger = LoggerFactory.getLogger("ESBSocket");

    public ProcessSocketData() {
        super();
    }

    public ProcessSocketData(Socket socket, ServletContext servletContext) {
        this.socket = socket;
        this.servletContext = servletContext;

    }

    @Override
    public void run() {
        PrintWriter pw = null;
        BufferedReader in = null;
        Socket localSocket = this.socket;

        try {
//            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            logger.error("ServerSocket线程启动"+Thread.currentThread().getName());
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8);

            // PrintWriter pw = new PrintWriter(outputStreamWriter);
             pw = new PrintWriter(outputStreamWriter);
            InputStream inputStream = socket.getInputStream();
            // BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
             in = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
            char[] datalen=new char[8];//报文前八位为报文体总长度

            in.read(datalen,0,8);
            String lendata=new String (datalen);
            String clientIPAddress = localSocket.getInetAddress().getHostAddress();  // 获取客户端IP地址
            logger.error("Client connected from IP: " + clientIPAddress);
            logger.error("request.length:"+lendata);
            int length=Integer.parseInt(lendata);
            logger.error("报文长度"+length);
            // byte[] data=new byte[length];
            char[] data=new char[length];
            int datalength = in.read(data,0,length);
            String requestData = new String(data);
            logger.error("requestData",requestData);
            String s = "";
            if (!StringUtil.isEmpty(requestData.toString())) {
                logger.error("requestData",requestData);
                s = execute(requestData.toString());
            }
            // 执行自定义的请求解析方法，生成响应response
            pw.println(s);
            pw.flush(); // 刷新缓冲区
            // pw.close();
            // socket.close();
//            System.out.println(sb);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("error:"+e.getMessage());
        }finally {
            if (pw != null) {
                pw.close();
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    logger.error("error:"+e.getMessage());
                }
            }
            if (localSocket != null) {
                try {
                    localSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    logger.error("error:"+e.getMessage());
                }
            }
        }
    }
    private String execute(String XMLparam){

        try {
            logger.error("XMLparam=="+XMLparam);
            Map<String, String> paramMap = XMLUtils.parseXMLToMap(XMLparam);
            logger.error("paramMap=="+paramMap);
            StringEscapeUtils.unescapeXml(XMLparam);
            //目标系统代码
            String system_id = paramMap.get("system_id");
            // 请求方系统代码
            String requester_id = paramMap.get("requester_id");
            // 请求方机构代号
            String branch_id = paramMap.get("branch_id");
            logger.error("requester_id=="+requester_id);
            SocketExecute socketExecute = null;
            if ("0157".equals(requester_id)){
                logger.error("GetToCountSocketExecute-Start");
                socketExecute = new GetToCountSocketExecute();
                logger.error("GetToCountSocketExecute-end");
            }else if("0170".equals(requester_id)){
                logger.error("GetToCountSocketExecute-Start");
                socketExecute = new CWGLSocketExecute();
                logger.error("CWGLSocketExecute-end");
            }
            String execute = socketExecute.execute(paramMap);
            logger.error("socketExecute:return"+execute);
            return execute;
        }catch (Exception e) {
                e.printStackTrace();
                logger.error("error:"+e.getMessage());
                return "";
        }

    }



    // public void run() {
    //     try {
    //         (new BaseBean()).writeLog("ServerSocket线程启动");
    //         OutputStreamWriter outputStreamWriter = new OutputStreamWriter(this.socket.getOutputStream(), StandardCharsets.UTF_8);
    //         PrintWriter pw = new PrintWriter(outputStreamWriter);
    //         InputStream inputStream = this.socket.getInputStream();
    //         BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
    //         char[] datalen = new char[8];
    //         in.read(datalen, 0, 8);
    //         String lendata = new String(datalen);
    //         int length = Integer.parseInt(lendata);
    //         (new BaseBean()).writeLog("报文长度" + length);
    //         char[] data = new char[length];
    //         in.read(data, 0, length);
    //         String requestData = new String(data);
    //         (new BaseBean()).writeLog("requestData", requestData);
    //         String s = "";
    //         if (!StringUtil.isEmpty(requestData.toString())) {
    //             (new BaseBean()).writeLog("requestData", requestData);
    //             s = this.execute(requestData.toString());
    //         }
    //
    //         pw.println(s);
    //         pw.flush();
    //         pw.close();
    //         this.socket.close();
    //     } catch (IOException var12) {
    //         var12.printStackTrace();
    //         System.out.println(var12);
    //     }
    //
    // }
    //
    // private String execute(String XMLparam) {
    //     (new BaseBean()).writeLog(this.getClass().getName() + ":XMLparam==" + XMLparam);
    //     Map<String, String> paramMap = XMLUtils.parseXMLToMap(XMLparam);
    //     (new BaseBean()).writeLog(this.getClass().getName() + ":paramMap==" + paramMap);
    //     StringEscapeUtils.unescapeXml(XMLparam);
    //     String system_id = (String)paramMap.get("system_id");
    //     String requester_id = (String)paramMap.get("requester_id");
    //     String branch_id = (String)paramMap.get("branch_id");
    //     (new BaseBean()).writeLog(this.getClass().getName() + ":requester_id==" + requester_id);
    //     SocketExecute socketExecute = null;
    //     if ("0157".equals(requester_id)) {
    //         socketExecute = new GetToCountSocketExecute();
    //         (new BaseBean()).writeLog(this.getClass().getName() + ":GetToCountSocketExecute");
    //     } else if ("0170".equals(requester_id)) {
    //         socketExecute = new CWGLSocketExecute();
    //         (new BaseBean()).writeLog(this.getClass().getName() + ":CWGLSocketExecute");
    //     }
    //
    //     String execute = ((SocketExecute)socketExecute).execute(XMLparam);
    //     return execute;
    // }
}


