package org.nl.acs.socket;

import cn.hutool.core.util.StrUtil;
import org.nl.acs.auto.run.AbstractAutoRunnable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Component
public class SocketListenerAutoRun extends AbstractAutoRunnable implements SocketService {
    private static final Logger log = LoggerFactory.getLogger(SocketListenerAutoRun.class);
    private ServerSocket serverSocket = null;
    private ExecutorService threadPool = Executors.newCachedThreadPool();
    private Map<String, Socket> sockets = new HashMap();
    private Map<String, OutputStream> outputs = new HashMap();

    public SocketListenerAutoRun() {
    }

    public static void main(String[] args) throws Exception {
        SocketListenerAutoRun run = new SocketListenerAutoRun();
        run.before();
        run.autoRun();

        while (true) {
            Thread.sleep(1000L);
        }
    }

    @Override
    public String getCode() {
        return SocketListenerAutoRun.class.getSimpleName();
    }

    @Override
    public String getName() {
        return "socket监听服务";
    }

    @Override
    public boolean isOnline(String ip) {
        return this.sockets.containsKey(ip);
    }

    @Override
    public OutputStream getOutputStream(String ip) {
        return (OutputStream) this.outputs.get(ip);
    }

    @Override
    public void autoRun() throws Exception {
        while (true) {
            System.out.println("等待一个连接：");
            Socket socket = this.serverSocket.accept();
            String socket_key = socket.getInetAddress().getHostAddress();

            try {
                System.out.println("连入一个连接" + socket_key);
                InputStream is = socket.getInputStream();
                OutputStream out = socket.getOutputStream();
                this.clean(socket_key);
                this.addSocket(socket_key, socket);
                this.addOutput(socket_key, out);
                this.threadPool.execute(new ClientUDWReceive(this, socket_key, socket, is));
            } catch (Exception var5) {
                this.closeSocket(socket);
                this.remove(socket_key);
                log.warn("", var5);
            }
        }
    }

    @Override
    public void before() throws Exception {
        this.serverSocket = new ServerSocket(SocketProperties.server_port);
    }

    @Override
    public void after() {
        System.out.println("清理工作。。。。。");
        this.threadPool.shutdownNow();
        this.threadPool = Executors.newCachedThreadPool();
        this.sockets = new HashMap();
        this.outputs = new HashMap();
        this.closeSocket(this.serverSocket);
        this.serverSocket = null;
    }

    public synchronized void addSocket(String socket_key, Socket socket) {
        this.sockets.put(socket_key, socket);
    }

    public synchronized void addOutput(String socket_key, OutputStream out) {
        this.outputs.put(socket_key, out);
    }

    public synchronized void remove(String socket_key) {
        if (!StrUtil.isEmpty(socket_key)) {
            this.outputs.remove(socket_key);
            this.sockets.remove(socket_key);
        }

    }

    public synchronized void clean(String socket_key) {
        if (this.sockets.containsKey(socket_key)) {
            this.closeSocket((Socket) this.sockets.get(socket_key));
            this.remove(socket_key);
        }

    }

    protected void closeSocket(Socket socket) {
        try {
            if (socket != null && !socket.isClosed()) {
                socket.close();
            }
        } catch (Exception var3) {
        }

    }

    protected void closeSocket(ServerSocket socket) {
        try {
            if (socket != null && !socket.isClosed()) {
                socket.close();
            }
        } catch (Exception var3) {

        }

    }
}
