package org.jboss.resteasy.test.client.resource;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.OPTIONS;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("")
public class TestResource {
    @HttpMethod("TRACE")
    @Target(value = ElementType.METHOD)
    @Retention(value = RetentionPolicy.RUNTIME)
    public @interface TRACE {
    }

    @HttpMethod("METHOD")
    @Target({ ElementType.METHOD })
    @Retention(RetentionPolicy.RUNTIME)
    public @interface METHOD {
    }

    @Path("get")
    @GET
    public Response get() {
        return Response.ok("get").build();
    }

    @GET
    @Path("sleep")
    @Produces("text/plain")
    public CompletionStage<String> sleep() {
        CompletableFuture<String> cs = new CompletableFuture<>();
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.submit(() -> {
            try {
                Thread.sleep(3000L);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            cs.complete("get");
        });
        return cs;
    }

    @Path("put")
    @PUT
    @Consumes(MediaType.TEXT_PLAIN)
    public Response put(String s) {
        return Response.ok(s).build();
    }

    @Path("post")
    @POST
    @Consumes(MediaType.TEXT_PLAIN)
    public Response post(String s) {
        return Response.ok(s).build();
    }

    @Path("delete")
    @DELETE
    public Response delete() {
        return Response.ok("delete").build();
    }

    @Path("head")
    @HEAD
    public Response head() {
        return Response.noContent().header("key", "head").build();
    }

    @Path("options")
    @OPTIONS
    public Response options() {
        return Response.ok("options").build();
    }

    @Path("trace")
    @TRACE
    public Response trace() {
        return Response.ok("trace").build();
    }

    @Path("method")
    @METHOD
    public Response method() {
        return Response.ok("method").build();
    }

    @Path("methodEntity")
    @METHOD
    public Response methodEntity(String s) {
        return Response.ok(s).build();
    }
}
