package com.link_intersystems.net.http;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;

/**
 * @author René Link {@literal <rene.link@link-intersystems.com>}
 */
public class DefaultHttpRequestTest {

    private HttpMockServer httpMockServer;
    private HttpRequestFactory requestFactory;

    @BeforeEach
    void setUp() throws IOException {
        httpMockServer = new HttpMockServer();
        requestFactory = new DefaultHttpRequestFactory();
        requestFactory.setReadTimeout(Duration.of(1, ChronoUnit.SECONDS));
    }

    @Test
    void get() throws IOException, URISyntaxException {
        URL baseURL = httpMockServer.getBaseUrl();
        URL requestUrl = baseURL.toURI().resolve(new URI("/somePath")).toURL();
        httpMockServer.whenRequestPath(requestUrl.getPath()).respond(200);

        HttpRequest httpRequest = requestFactory.get(requestUrl);
        httpRequest.addHeader("Accept", "application/json");
        HttpResponse httpResponse = httpRequest.prepare().execute();

        assertEquals(200, httpResponse.getResponseCode());

        HttpMockServer.ReceivedRequest latestRequest = httpMockServer.getLatestRequest();
        Map<String, String> headers = latestRequest.getHeaders();

        assertEquals("application/json", headers.get("Accept"));
    }

    @Test
    void post() throws IOException, URISyntaxException {
        URL baseURL = httpMockServer.getBaseUrl();
        URL requestUrl = baseURL.toURI().resolve(new URI("/somePath")).toURL();
        httpMockServer.whenRequestPath(requestUrl.getPath()).respond(200, "Response to Hello World".getBytes(StandardCharsets.UTF_8));

        HttpRequest httpRequest = requestFactory.post(requestUrl);
        httpRequest.addHeader("Accept", "application/json");
        PreparedRequest preparedRequest = httpRequest.prepare();
        preparedRequest.getOutputStream().write("Hello World".getBytes(StandardCharsets.UTF_8));
        HttpResponse httpResponse = preparedRequest.execute();

        assertEquals(200, httpResponse.getResponseCode());

        HttpMockServer.ReceivedRequest latestRequest = httpMockServer.getLatestRequest();
        Map<String, String> headers = latestRequest.getHeaders();

        assertEquals("application/json", headers.get("Accept"));
        byte[] content = latestRequest.getBody();

        assertArrayEquals("Hello World".getBytes(StandardCharsets.UTF_8), content);

        String contentAsString = httpResponse.getDecodedContent();
        assertEquals("Response to Hello World", contentAsString);
    }

    @Test
    void put() throws IOException, URISyntaxException {
        URL baseURL = httpMockServer.getBaseUrl();
        URL requestUrl = baseURL.toURI().resolve(new URI("/somePath")).toURL();
        httpMockServer.whenRequestPath(requestUrl.getPath()).respond(200, "Response to Hello World".getBytes(StandardCharsets.UTF_8));

        HttpRequest httpRequest = requestFactory.put(requestUrl);
        httpRequest.addHeader("Accept", "application/json");
        PreparedRequest preparedRequest = httpRequest.prepare();
        preparedRequest.getOutputStream().write("Hello World".getBytes(StandardCharsets.UTF_8));
        HttpResponse httpResponse = preparedRequest.execute();

        assertEquals(200, httpResponse.getResponseCode());

        HttpMockServer.ReceivedRequest latestRequest = httpMockServer.getLatestRequest();
        Map<String, String> headers = latestRequest.getHeaders();

        assertEquals("application/json", headers.get("Accept"));
        byte[] content = latestRequest.getBody();

        assertArrayEquals("Hello World".getBytes(StandardCharsets.UTF_8), content);

        String contentAsString = httpResponse.getDecodedContent();
        assertEquals("Response to Hello World", contentAsString);
    }

    @Test
    void delete() throws IOException, URISyntaxException {
        URL baseURL = httpMockServer.getBaseUrl();
        URL requestUrl = baseURL.toURI().resolve(new URI("/somePath")).toURL();
        httpMockServer.whenRequestPath(requestUrl.getPath()).respond(200, "Response to Hello World".getBytes(StandardCharsets.UTF_8));

        HttpRequest httpRequest = requestFactory.delete(requestUrl);
        httpRequest.addHeader("Accept", "application/json");
        PreparedRequest preparedRequest = httpRequest.prepare();
        preparedRequest.getOutputStream().write("Hello World".getBytes(StandardCharsets.UTF_8));
        HttpResponse httpResponse = preparedRequest.execute();

        assertEquals(200, httpResponse.getResponseCode());

        HttpMockServer.ReceivedRequest latestRequest = httpMockServer.getLatestRequest();
        Map<String, String> headers = latestRequest.getHeaders();

        assertEquals("application/json", headers.get("Accept"));
        byte[] content = latestRequest.getBody();

        assertArrayEquals("Hello World".getBytes(StandardCharsets.UTF_8), content);

        String contentAsString = httpResponse.getDecodedContent();
        assertEquals("Response to Hello World", contentAsString);
    }

    @AfterEach
    void tearDown() throws IOException {
        httpMockServer.close();
    }
}

@@ -4213,1256 +4213,8 @@
  %7D%0A%0A
-    @Test%0A    void delete() throws IOException, URISyntaxException %7B%0A        URL baseURL = httpMockServer.getBaseUrl();%0A        URL requestUrl = baseURL.toURI().resolve(new URI(%22/somePath%22)).toURL();%0A        httpMockServer.whenRequestPath(requestUrl.getPath()).respond(200, %22Response to Hello World%22.getBytes(StandardCharsets.UTF_8));%0A%0A        HttpRequest httpRequest = requestFactory.delete(requestUrl);%0A        httpRequest.addHeader(%22Accept%22, %22application/json%22);%0A        PreparedRequest preparedRequest = httpRequest.prepare();%0A        preparedRequest.getOutputStream().write(%22Hello World%22.getBytes(StandardCharsets.UTF_8));%0A        HttpResponse httpResponse = preparedRequest.execute();%0A%0A        assertEquals(200, httpResponse.getResponseCode());%0A%0A        HttpMockServer.ReceivedRequest latestRequest = httpMockServer.getLatestRequest();%0A        Map%3CString, String%3E headers = latestRequest.getHeaders();%0A%0A        assertEquals(%22application/json%22, headers.get(%22Accept%22));%0A        byte%5B%5D content = latestRequest.getBody();%0A%0A        assertArrayEquals(%22Hello World%22.getBytes(StandardCharsets.UTF_8), content);%0A%0A        String contentAsString = httpResponse.getDecodedContent();%0A        assertEquals(%22Response to Hello World%22, contentAsString);%0A    %7D
 %0A%0A  

Test passed locally but fails on github build.