package com.lts.cmd;

import com.lts.core.logger.Logger;
import com.lts.core.logger.LoggerFactory;

import java.io.IOException;
import java.net.BindException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 主要用于 curl
 *
 * @author Robert HG (254963746@qq.com) on 10/26/15.
 */
public class HttpCmdServer {

    private final Logger LOGGER = LoggerFactory.getLogger(HttpCmdServer.class);

    private final AtomicBoolean start = new AtomicBoolean(false);
    private HttpCmdAcceptor acceptor;
    private int port;
    private String bindAddr;
    private HttpCmdContext context;

    private HttpCmdServer(String bindAddr, int port) {
        this.port = port > 0 ? port : 8719;
        this.bindAddr = bindAddr;
        this.context = new HttpCmdContext();
    }

    public void start() throws HttpCmdException {
        try {
            if (start.compareAndSet(false, true)) {
                // 开启监听命令
                acceptor = new HttpCmdAcceptor(getServerSocket(), context);
                acceptor.start();
                LOGGER.info("Start succeed at port {}", port);
            }
        } catch (Exception t) {
            LOGGER.error("Start error at port {}", port, t);
            throw new HttpCmdException(t);
        }
    }

    private ServerSocket getServerSocket() throws IOException {
        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(port, 100);
            serverSocket.setReuseAddress(true);
        } catch (BindException e) {
            if (e.getMessage().contains("Address already in use")) {
                port = port + 1;
                serverSocket = getServerSocket();
            } else {
                throw e;
            }
        }
        return serverSocket;
    }

    public void stop() {
        if (acceptor != null) {
            acceptor.stop();
        }
    }

    public int getPort() {
        return port;
    }

    public void registerCommand(HttpCmdProc proc) {
        context.addCmdProcessor(proc);
    }

    public void registerCommands(HttpCmdProc... procs) {
        if (procs != null && procs.length > 0) {
            for (HttpCmdProc proc : procs) {
                this.registerCommand(proc);
            }
        }
    }

    /**
     * 保证一个jvm公用一个 HttpCmdServer
     */
    public static class Factory {

        private static HttpCmdServer httpCmdServer;

        public static HttpCmdServer getHttpCmdServer(String bindAddr, int port) {
            if (httpCmdServer != null) {
                return httpCmdServer;
            }
            synchronized (Factory.class) {
                if (httpCmdServer != null) {
                    return httpCmdServer;
                }
                httpCmdServer = new HttpCmdServer(bindAddr, port);
                return httpCmdServer;
            }
        }
    }

}

@@ -156,37 +156,8 @@
 on;%0A
-import java.net.InetAddress;%0A
 impo
@@ -611,16 +611,47 @@
 context;
+%0A    private int portFindTimes;
 %0A%0A    pr
@@ -1575,81 +1575,8 @@
 ) %7B%0A
-            if (e.getMessage().contains(%22Address already in use%22)) %7B%0A    
     
@@ -1600,20 +1600,16 @@
 rt + 1;%0A
-    
         
@@ -1662,14 +1662,33 @@
     
-%7D else
+if (portFindTimes++ %3E 50)
  %7B%0A 

Update HttpCmdServer.java