package com.github.dreambrother.hackernews.http;

import com.github.dreambrother.hackernews.exceptions.InvalidRequestException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class PingServer {

    private static final Logger log = LoggerFactory.getLogger(PingServer.class);

    private static final String RESPONSE_TEMPLATE =
                    "HTTP/1.1 %s %n" +
                    "Content-Type: text/html;charset=utf-8%n" +
                    "Content-Length: %d%n%n" +
                    "%s";

    private HttpGetHandler handler;
    private int port;

    public void start() {
        Thread serverThread = new Thread(serverRunnable());
        serverThread.setDaemon(true);
        serverThread.start();
    }

    public void stop() {
        Thread.currentThread().interrupt();
    }

    private Runnable serverRunnable() {
        return new Runnable() {
            public void run() {
                try (ServerSocket serverSocket = new ServerSocket(port, 1, InetAddress.getLoopbackAddress())){
                    while (!Thread.currentThread().isInterrupted()) {
                        try (Socket clientSocket = serverSocket.accept()) {
                            handle(clientSocket);
                        }
                    }
                    log.info("Server was interrupted... shutdown now");
                } catch (IOException e) {
                    log.error("PingServer doesn't start", e);
                }
            }
        };
    }

    private void handle(Socket clientSocket) {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            String request = reader.readLine();

            log.debug("Handle request: {}", request);
            String body = handler.handle(getUrl(request));
            writeResponse("200 OK", body, clientSocket);
        } catch (IOException e) {
            log.warn("Cannot read from socket!");
        } catch (InvalidRequestException e) {
            writeResponse("400 BAD REQUEST", "", clientSocket);
        } catch (Exception ex) {
            writeResponse("500 INTERNAL SERVER ERROR", "", clientSocket);
        }
    }

    private void writeResponse(String code, String body, Socket to) {
        try {
            String fullResponse = String.format(RESPONSE_TEMPLATE, code, body.getBytes().length, body);
            to.getOutputStream().write(fullResponse.getBytes());
        } catch (IOException e) {
            log.warn("Cannot write to socket");
        }
    }

    private String getUrl(String request) {
        String[] splittedRequest = request.split(" ");
        if (splittedRequest.length < 2) {
            throw new InvalidRequestException("Invalid request " + request);
        }
        return splittedRequest[1];
    }

    public void setHandler(HttpGetHandler handler) {
        this.handler = handler;
    }

    public void setPort(int port) {
        this.port = port;
    }
}

@@ -753,16 +753,114 @@
  port;%0A%0A
+    private ServerSocket runningServerSocket;%0A    private volatile boolean isShutdowned = false;%0A%0A
     publ
@@ -1049,43 +1049,192 @@
     
-Thread.currentThread().interrupt();
+try %7B%0A            isShutdowned = true;%0A            runningServerSocket.close();%0A        %7D catch (IOException e) %7B%0A            log.error(%22Cannot close running server socket%22);%0A        %7D
 %0A   
@@ -1450,16 +1450,17 @@
 ress()))
+ 
 %7B%0A      
@@ -1477,54 +1477,75 @@
     
-while (!Thread.currentThread().isInterrupted()
+runningServerSocket = serverSocket;%0A                    while (true
 ) %7B%0A
@@ -1710,32 +1710,118 @@
               %7D%0A
+                %7D catch (IOException e) %7B%0A                    if (isShutdowned) %7B%0A    
                 
@@ -1849,17 +1849,13 @@
 was 
-interrupt
+stopp
 ed..
@@ -1892,34 +1892,25 @@
     
-%7D catch (IOException e) %7B%0A
+    %7D else %7B%0A    
     
@@ -1951,27 +1951,41 @@
 ver 
-doesn't start%22, e);
+error%22, e);%0A                    %7D
 %0A   

fix server shutdown