package io.airlift.jaxrs.testing;

import io.airlift.http.client.HttpStatus;
import io.airlift.http.client.Request;
import io.airlift.http.client.StringResponseHandler.StringResponse;
import io.airlift.http.client.testing.TestingHttpClient;
import org.testng.annotations.Test;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import java.net.URI;

import static io.airlift.http.client.Request.Builder.prepareGet;
import static io.airlift.http.client.StringResponseHandler.createStringResponseHandler;
import static java.lang.String.format;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;

@Test
public class TestJaxrsTestingHttpProcessor
{
    private static final TestingHttpClient HTTP_CLIENT =
            new TestingHttpClient(new JaxrsTestingHttpProcessor(URI.create("http://fake.invalid/"), new GetItResource()));

    @Test
    public void test()
    {
        Request request = prepareGet()
                .setUri(URI.create("http://fake.invalid/get-it/get/xyz"))
                .build();

        StringResponse response = HTTP_CLIENT.execute(request, createStringResponseHandler());

        assertEquals(response.getStatusCode(), HttpStatus.OK.code());
        assertEquals(response.getBody(), "Got xyz");
    }

    @Test
    public void testException()
    {
        Request request = prepareGet()
                .setUri(URI.create("http://fake.invalid/get-it/fail/testException"))
                .build();

        try {
            HTTP_CLIENT.execute(request, createStringResponseHandler());
            fail("expected exception");
        }
        catch (TestingException e) {
            assertEquals(e.getMessage(), "testException");
        }
    }

    @Test
    public void testUndefinedResource()
    {
        Request request = prepareGet()
                .setUri(URI.create("http://fake.invalid/unknown"))
                .build();

        StringResponse response = HTTP_CLIENT.execute(request, createStringResponseHandler());
        assertEquals(response.getStatusCode(), 404);
    }

    @Path("get-it")
    public static class GetItResource
    {
        @Path("get/{id}")
        @GET
        @Produces(MediaType.TEXT_PLAIN)
        public String getId(@PathParam("id") String id)
        {
            return format("Got %s", id);
        }

        @Path("fail/{message}")
        @GET
        @Produces(MediaType.TEXT_PLAIN)
        public String fail(@PathParam("message") String errorMessage)
        {
            throw new TestingException(errorMessage);
        }
    }

    private static class TestingException
            extends RuntimeException
    {
        public TestingException(String message)
        {
            super(message);
        }
    }
}

@@ -295,16 +295,48 @@
 rs.GET;%0A
+import javax.ws.rs.HeaderParam;%0A
 import j
@@ -445,16 +445,50 @@
 diaType;
+%0Aimport javax.ws.rs.core.Response;
 %0A%0Aimport
@@ -660,47 +660,8 @@
 er;%0A
-import static java.lang.String.format;%0A
 impo
@@ -1121,24 +1121,68 @@
 /get/xyz%22))%0A
+                .setHeader(%22X-Test%22, %22abc%22)%0A
             
@@ -1411,24 +1411,91 @@
 %22Got xyz%22);%0A
+        assertEquals(response.getHeader(%22X-Test-Out%22), %22Got abc%22);%0A
     %7D%0A%0A    @
@@ -2444,97 +2444,258 @@
 lic 
-String getId(@PathParam(%22id%22) String id)%0A        %7B%0A            return format(%22Got %25s%22, id
+Response getId(%0A                @HeaderParam(%22X-Test%22) String test,%0A                @PathParam(%22id%22) String id)%0A        %7B%0A            return Response.ok(%22Got %22 + id)%0A                    .header(%22X-Test-Out%22, %22Got %22 + test)%0A                    .build(
 );%0A 

Verify header support in JaxrsTestingHttpProcessor