package btools.server;


import org.json.JSONObject;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;

public class RouteServerTest {
  private static final String host = "localhost";
  private static final String port = "17777";
  private static final String baseUrl = "http://" + host + ":" + port + "/";

  @BeforeClass
  public static void setupServer() throws IOException {
    File workingDir = new File(".").getCanonicalFile();
    File segmentDir = new File(workingDir, "../brouter-map-creator/build/resources/test/tmp/segments");
    File profileDir = new File(workingDir, "../misc/profiles2");
    File customProfileDir = workingDir;

    Runnable runnable = () -> {
      try {
        RouteServer.main(new String[]{segmentDir.getAbsolutePath(), profileDir.getAbsolutePath(), customProfileDir.getAbsolutePath(), port, "1"});
      } catch (Exception e) {
        e.printStackTrace();
      }
    };

    Thread thread = new Thread(runnable);
    thread.start();

    // Busy-wait for server startup
    URL requestUrl = new URL(baseUrl);
    HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
    for (int i = 10; i >= 0; i--) {
      try {
        httpConnection.setConnectTimeout(10);
        httpConnection.connect();
        break;
      } catch (ConnectException e) {
        if (i == 0) {
          throw e;
        }
      }
    }
  }

  @Test
  public void defaultRouteTrekking() throws IOException {
    URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.723037,50.000491|8.712737,50.002899&nogos=&profile=trekking&alternativeidx=0&format=geojson");

    HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
    httpConnection.connect();

    Assert.assertEquals(HttpURLConnection.HTTP_OK, httpConnection.getResponseCode());

    InputStream inputStream = httpConnection.getInputStream();
    JSONObject geoJson = new JSONObject(new String(inputStream.readAllBytes(), StandardCharsets.UTF_8));
    Assert.assertEquals("1204", geoJson.query("/features/0/properties/track-length"));
  }

  @Test
  public void overrideParameter() throws IOException {
    URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.723037,50.000491|8.712737,50.002899&nogos=&profile=trekking&alternativeidx=0&format=geojson&profile:avoid_unsafe=1");
    HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
    httpConnection.connect();

    Assert.assertEquals(HttpURLConnection.HTTP_OK, httpConnection.getResponseCode());

    InputStream inputStream = httpConnection.getInputStream();
    JSONObject geoJson = new JSONObject(new String(inputStream.readAllBytes(), StandardCharsets.UTF_8));
    Assert.assertEquals("1902", geoJson.query("/features/0/properties/track-length"));
  }

  @Test
  public void robots() throws IOException {
    URL requestUrl = new URL(baseUrl + "robots.txt");
    HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
    httpConnection.connect();

    Assert.assertEquals(HttpURLConnection.HTTP_OK, httpConnection.getResponseCode());

    String content = new String(httpConnection.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
    Assert.assertTrue(content.contains("Disallow: /"));
  }

  @Test
  public void invalidUrl() throws IOException {
    URL requestUrl = new URL(baseUrl + "invalid");
    HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
    httpConnection.connect();

    Assert.assertEquals(HttpURLConnection.HTTP_NOT_FOUND, httpConnection.getResponseCode());
  }

  @Test
  @Ignore("Broken implementation (uppercase / lowercase issue)")
  public void invalidReferrer() throws IOException {
    URL requestUrl = new URL(baseUrl + "brouter/%7C/%2C");
    HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
    httpConnection.setRequestProperty("Referer", "http://brouter.de/brouter-web/");
    httpConnection.connect();

    Assert.assertEquals(HttpURLConnection.HTTP_FORBIDDEN, httpConnection.getResponseCode());
  }
}

@@ -629,24 +629,46 @@
  IOException
+, InterruptedException
  %7B%0A    File 
@@ -1433,17 +1433,17 @@
 int i = 
-1
+2
 0; i %3E= 
@@ -1507,16 +1507,18 @@
 meout(10
+00
 );%0A     
@@ -1645,24 +1645,51 @@
 ;%0A        %7D%0A
+        Thread.sleep(100);%0A
       %7D%0A    

Increase startup timeout