package net.zephyrizing.http_server_test.integration;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import net.zephyrizing.http_server.HttpServer;

import org.junit.Ignore;
import org.junit.Test;

import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;

public class SmokeTest {
    public class ServerThread extends Thread {
        Integer port;
        String directory;

        public ServerThread() { this(null, null); }
        public ServerThread(Integer port) { this(port, null); }
        public ServerThread(String directory) { this(null, directory); }
        public ServerThread(Integer port, String directory) {
            this.port = port;
            this.directory = directory;
        }

        @Override
        public void run() {
            PrintStream oldErr = System.err;
            PrintStream newErr = new PrintStream(new ByteArrayOutputStream());
            System.setErr(newErr);
            HttpServer.main(buildOptions());
            System.setErr(oldErr);
        }

        public String[] buildOptions() {
            List<String> opts = new ArrayList<String>();
            int i = 0;
            if (port != null) {
                opts.add("-p");
                opts.add(port.toString());
            }
            if (directory != null) {
                opts.add("-d");
                opts.add(directory);
            }
            return opts.toArray(new String[0]);
        }
    }


    @Test
    public void runDefaultServer() throws Exception {
        ServerThread server = new ServerThread();
        assertThat(Arrays.asList(server.buildOptions()), everyItem(notNullValue(String.class)));

        server.start();
        Thread.sleep(100);

        assertTrue(server.isAlive());

        server.interrupt();
    }

    @Test
    public void runServerWithPortArgument() throws Exception {
        ServerThread server = new ServerThread(10000);
        assertThat(Arrays.asList(server.buildOptions()), everyItem(notNullValue(String.class)));

        server.start();
        Thread.sleep(100);

        assertTrue(server.isAlive());

        server.interrupt();
    }

    @Test
    public void runServerWithDirectoryArgument() throws Exception {
        ServerThread server = new ServerThread(12000, "public");
        assertThat(Arrays.asList(server.buildOptions()), everyItem(notNullValue(String.class)));

        server.start();
        Thread.sleep(100);

        assertTrue(server.isAlive());

        server.interrupt();
    }

    @Test
    public void runServerAndGetResponse() throws Exception {
        int port = 14000;
        ServerThread server = new ServerThread(port, "public");
        assertThat(Arrays.asList(server.buildOptions()), everyItem(notNullValue(String.class)));

        server.start();
        Thread.sleep(100);

        try (Socket socket = new Socket("localhost", port);
             PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
             BufferedReader in = new BufferedReader(
                 new InputStreamReader(socket.getInputStream()));) {
            out.print("GET /.gitkeep HTTP/1.1\r\n");
            out.print("Host: localhost\r\n");
            out.print("\r\n");
            out.flush();

            String line = in.readLine();
            assertThat(line, equalTo("HTTP/1.1 200 OK"));

            line = in.readLine();
            assertThat(line, equalTo(""));

            line = in.readLine();
            assertThat(line, equalTo(null));
        }
        server.interrupt();
    }
}

@@ -109,32 +109,60 @@
 ayOutputStream;%0A
+import java.io.IOException;%0A
 import java.io.I
@@ -171,32 +171,32 @@
 utStreamReader;%0A
-
 import java.io.P
@@ -231,24 +231,53 @@
 rintWriter;%0A
+import java.net.InetAddress;%0A
 import java.
@@ -1194,24 +1194,46 @@
 rr(newErr);%0A
+            try %7B%0A    
             
@@ -1261,24 +1261,99 @@
 Options());%0A
+            %7D catch (InterruptedException e) %7B%0A            %7D finally %7B%0A    
             
@@ -1371,24 +1371,38 @@
 rr(oldErr);%0A
+            %7D%0A
         %7D%0A%0A 
@@ -1827,16 +1827,293 @@
 %0A    %7D%0A%0A
+    public void pingServer(int port) throws IOException %7B%0A        try (Socket s = new Socket(InetAddress.getLocalHost(), port);%0A             PrintWriter out = new PrintWriter(s.getOutputStream())) %7B%0A            out.append(%22%5Cr%5Cn%22).append(%22%5Cr%5Cn%22).append(%22%5Cr%5Cn%22);%0A        %7D%0A    %7D%0A
 %0A    @Te
@@ -2428,32 +2428,58 @@
 er.interrupt();%0A
+        pingServer(5000);%0A
     %7D%0A%0A    @Test
@@ -2534,32 +2534,58 @@
 ows Exception %7B%0A
+        int port = 10000;%0A
         ServerTh
@@ -2615,21 +2615,20 @@
 rThread(
-10000
+port
 );%0A     
@@ -2831,32 +2831,58 @@
 er.interrupt();%0A
+        pingServer(port);%0A
     %7D%0A%0A    @Test
@@ -2942,32 +2942,58 @@
 ows Exception %7B%0A
+        int port = 12000;%0A
         ServerTh
@@ -3023,21 +3023,20 @@
 rThread(
-12000
+port
 , %22publi
@@ -3253,24 +3253,50 @@
 nterrupt();%0A
+        pingServer(port);%0A
     %7D%0A%0A    @
@@ -3385,9 +3385,9 @@
  = 1
-4
+2
 000;
@@ -4278,32 +4278,32 @@
 ll));%0A        %7D%0A
-
         server.i
@@ -4310,20 +4310,46 @@
 nterrupt();%0A
+        pingServer(port);%0A
     %7D%0A%7D%0A

Fix SmokeTests