package com.github.gquintana.beepbeep.http;

import com.github.gquintana.beepbeep.LineException;
import com.github.gquintana.beepbeep.TestConsumer;
import com.github.gquintana.beepbeep.pipeline.LineEvent;
import com.github.gquintana.beepbeep.pipeline.ScriptEvent;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;

import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.assertj.core.api.Assertions.assertThat;

public class HttpLineExecutorTest {
    @Rule
    public WireMockRule wireMock = new WireMockRule(WireMockConfiguration.wireMockConfig().port(8080));

    @Test
    @Ignore
    public void testGetGoogle() {
        // Given
        TestConsumer<ScriptEvent> consumer = new TestConsumer<>();
        HttpClientProvider httpClientProvider = new BasicHttpClientProvider("http://www.google.com");
        HttpLineExecutor processor = new HttpLineExecutor(httpClientProvider, consumer);
        // When
        String eol = System.lineSeparator();
        processor.consume(new LineEvent(null, 1, "GET /" + eol + "HEADER Accept text/html" + eol));
        // Then
        assertThat(consumer.events).hasSize(1);
        assertThat(consumer.events.get(0).toString()).startsWith("200,OK");
    }

    @Test
    public void testGet() {
        // Given
        wireMock.stubFor(get(urlMatching("/my/url")).withHeader("Accept", matching("application/json"))
            .willReturn(aResponse().withStatus(200).withHeader("Content-type", "application/json")
                .withBody("{\"body\":\"Hello world\"}")));
        TestConsumer<ScriptEvent> consumer = new TestConsumer<>();
        HttpClientProvider httpClientProvider = new BasicHttpClientProvider("http://localhost:8080/");
        HttpLineExecutor processor = new HttpLineExecutor(httpClientProvider, consumer);
        // When
        String eol = System.lineSeparator();
        processor.consume(new LineEvent(null, 1, "GET /my/url" + eol + "HEADER Accept application/json" + eol));
        // Then
        assertThat(consumer.events).hasSize(1);
        assertThat(consumer.events.get(0).toString()).contains("200,OK");
    }

    @Test
    public void testPost() {
        // Given
        String requestBody = "{\"body\":\"Hello world\"}";
        wireMock.stubFor(post(urlMatching("/my/url"))
            .withHeader("Accept", matching("application/json"))
            .withHeader("Content-Type", matching("application/json"))
            .withRequestBody(equalToJson(requestBody))
            .willReturn(aResponse().withStatus(201)
                .withHeader("Content-type", "application/json; charset=UTF-8")
                .withBody("{\"created\":\"true\"}")));
        TestConsumer<ScriptEvent> consumer = new TestConsumer<>();
        HttpClientProvider httpClientProvider = new BasicHttpClientProvider("http://localhost:8080/");
        HttpLineExecutor processor = new HttpLineExecutor(httpClientProvider, consumer);
        // When
        String eol = System.lineSeparator();
        processor.consume(new LineEvent(null, 1, "POST my/url" + eol
            + "HEADER Accept application/json" + eol
            + "HEADER Content-Type application/json" + eol +
            requestBody));
        // Then
        assertThat(consumer.events).hasSize(1);
        assertThat(consumer.events.get(0).toString()).contains("201,Created,{\"created\":\"true\"}");
    }

    @Test
    public void testEmpty() {
        // Given
        TestConsumer<ScriptEvent> consumer = new TestConsumer<>();
        HttpClientProvider httpClientProvider = new BasicHttpClientProvider("http://localhost:8080/");
        HttpLineExecutor processor = new HttpLineExecutor(httpClientProvider, consumer);
        // When
        String eol = System.lineSeparator();
        processor.consume(new LineEvent(null, 1, "# Comment" + eol
            + "" + eol
            + "\t# Comment" + eol));
        // Then
        assertThat(consumer.events).isEmpty();
    }

    @Test(expected = LineException.class)
    public void testParseFailure() {
        // Given
        TestConsumer<ScriptEvent> consumer = new TestConsumer<>();
        HttpClientProvider httpClientProvider = new BasicHttpClientProvider("http://localhost:8080/");
        HttpLineExecutor processor = new HttpLineExecutor(httpClientProvider, consumer);
        // When
        processor.consume(new LineEvent(null, 1, "FAIL /at/url"));
        // Then
        assertThat(consumer.events).isEmpty();
    }

    @Test(expected = LineException.class)
    public void test404Error() {
        // Given
        TestConsumer<ScriptEvent> consumer = new TestConsumer<>();
        HttpClientProvider httpClientProvider = new BasicHttpClientProvider("http://localhost:8080/");
        HttpLineExecutor processor = new HttpLineExecutor(httpClientProvider, consumer);
        // When
        processor.consume(new LineEvent(null, 1, "GET /unknown/url"));
        // Then
        assertThat(consumer.events).isEmpty();
    }

    @Test(expected = LineException.class)
    public void testConnectionError() {
        // Given
        TestConsumer<ScriptEvent> consumer = new TestConsumer<>();
        HttpClientProvider httpClientProvider = new BasicHttpClientProvider("http://unknown");
        HttpLineExecutor processor = new HttpLineExecutor(httpClientProvider, consumer);
        // When
        processor.consume(new LineEvent(null, 1, "GET /unknown/url"));
        // Then
        assertThat(consumer.events).isEmpty();
    }
}

@@ -720,20 +720,192 @@
 g().
-port(8080));
+dynamicPort());%0A%0A    private BasicHttpClientProvider getBasicHttpClientProviderOnWireMock() %7B%0A        return new BasicHttpClientProvider(%22http://localhost:%22+wireMock.port()+%22/%22);%0A    %7D
 %0A%0A  
@@ -1965,36 +1965,35 @@
 lientProvider = 
-new 
+get
 BasicHttpClientP
@@ -2003,33 +2003,19 @@
 ider
-(%22http://localhost:8080/%22
+OnWireMock(
 );%0A 
@@ -3072,36 +3072,35 @@
 lientProvider = 
-new 
+get
 BasicHttpClientP
@@ -3110,33 +3110,19 @@
 ider
-(%22http://localhost:8080/%22
+OnWireMock(
 );%0A 
@@ -3817,36 +3817,35 @@
 lientProvider = 
-new 
+get
 BasicHttpClientP
@@ -3855,33 +3855,19 @@
 ider
-(%22http://localhost:8080/%22
+OnWireMock(
 );%0A 
@@ -4415,36 +4415,35 @@
 lientProvider = 
-new 
+get
 BasicHttpClientP
@@ -4453,33 +4453,19 @@
 ider
-(%22http://localhost:8080/%22
+OnWireMock(
 );%0A 
@@ -4904,36 +4904,35 @@
 lientProvider = 
-new 
+get
 BasicHttpClientP
@@ -4942,33 +4942,19 @@
 ider
-(%22http://localhost:8080/%22
+OnWireMock(
 );%0A 

Use dynamic HTTP Port in WireMock