package com.jetdrone.vertx.yoke.test.middleware;

import com.jetdrone.vertx.yoke.Middleware;
import com.jetdrone.vertx.yoke.annotations.GET;
import com.jetdrone.vertx.yoke.annotations.Path;
import com.jetdrone.vertx.yoke.annotations.Produces;
import com.jetdrone.vertx.yoke.middleware.YokeRequest;
import com.jetdrone.vertx.yoke.test.Response;
import com.jetdrone.vertx.yoke.test.YokeTester;
import org.junit.Test;
import org.vertx.java.core.Handler;
import org.vertx.java.core.json.JsonObject;
import org.vertx.testtools.TestVerticle;

import java.util.regex.Pattern;

import static org.vertx.testtools.VertxAssert.*;

public class Router extends TestVerticle {

    @Path("/ws")
    public static class TestRouter {
        @GET
        public void get(YokeRequest request) {
            request.response().end("Hello ws!");
        }
    }

    @Test
    public void testAnnotatedRouter() {
        YokeTester yoke = new YokeTester(this);
        yoke.use(com.jetdrone.vertx.yoke.middleware.Router.from(new TestRouter()));

        yoke.request("GET", "/ws", new Handler<Response>() {
            @Override
            public void handle(Response resp) {
                assertEquals(200, resp.getStatusCode());
                assertEquals("Hello ws!", resp.body.toString());
                testComplete();
            }
        });
    }

    @Path("/ws")
    public static class TestRouter2 {
        @GET
        @Produces({"text/plain"})
        public void get(YokeRequest request) {
            request.response().end("Hello ws!");
        }
    }

    @Test
    public void testAnnotatedRouter2() {
        YokeTester yoke = new YokeTester(this);
        yoke.use(com.jetdrone.vertx.yoke.middleware.Router.from(new TestRouter2()));

        yoke.request("GET", "/ws", new Handler<Response>() {
            @Override
            public void handle(Response resp) {
                assertEquals(200, resp.getStatusCode());
                assertEquals("Hello ws!", resp.body.toString());
                testComplete();
            }
        });
    }

    @Test
    public void testRouterWithParams() {
        YokeTester yoke = new YokeTester(this);
        yoke.use(new com.jetdrone.vertx.yoke.middleware.Router() {{
            get("/api/:userId", new Middleware() {
                @Override
                public void handle(YokeRequest request, Handler<Object> next) {

                    assertNotNull(request.get("user"));
                    assertTrue(request.get("user") instanceof JsonObject);
                    request.response().end("OK");
                }
            });
            param("userId", new Middleware() {
                @Override
                public void handle(YokeRequest request, Handler<Object> next) {
                    assertEquals("1", request.params().get("userId"));
                    // pretend that we went on some DB and got a json object representing the user
                    request.put("user", new JsonObject("{\"id\":" + request.params().get("userId") + "}"));
                    next.handle(null);
                }
            });
        }});

        yoke.request("GET", "/api/1", new Handler<Response>() {
            @Override
            public void handle(Response resp) {
                assertEquals(200, resp.getStatusCode());
                assertEquals("OK", resp.body.toString());
                testComplete();
            }
        });
    }

    @Test
    public void testRouterWithRegExParamsFail() {
        YokeTester yoke = new YokeTester(this);
        yoke.use(new com.jetdrone.vertx.yoke.middleware.Router() {{
            get("/api/:userId", new Middleware() {
                @Override
                public void handle(YokeRequest request, Handler<Object> next) {
                    request.response().end("OK");
                }
            });
            param("userId", Pattern.compile("[1-9][0-9]"));
        }});

        // the pattern expects 2 digits
        yoke.request("GET", "/api/1", new Handler<Response>() {
            @Override
            public void handle(Response resp) {
                assertEquals(400, resp.getStatusCode());
                testComplete();
            }
        });
    }

    @Test
    public void testRouterWithRegExParamsPass() {
        YokeTester yoke = new YokeTester(this);
        yoke.use(new com.jetdrone.vertx.yoke.middleware.Router() {{
            get("/api/:userId", new Middleware() {
                @Override
                public void handle(YokeRequest request, Handler<Object> next) {
                    request.response().end("OK");
                }
            });
            param("userId", Pattern.compile("[1-9][0-9]"));
        }});

        // the pattern expects 2 digits
        yoke.request("GET", "/api/10", new Handler<Response>() {
            @Override
            public void handle(Response resp) {
                assertEquals(200, resp.getStatusCode());
                testComplete();
            }
        });
    }
}

@@ -5001,11 +5001,957 @@
 );%0A    %7D
+%0A%0A    @Test%0A    public void testTrailingSlashes() %7B%0A        final YokeTester yoke = new YokeTester(this);%0A        yoke.use(new com.jetdrone.vertx.yoke.middleware.Router() %7B%7B%0A            get(%22/api%22, new Middleware() %7B%0A                @Override%0A                public void handle(YokeRequest request, Handler%3CObject%3E next) %7B%0A                    request.response().end(%22OK%22);%0A                %7D%0A            %7D);%0A        %7D%7D);%0A%0A        yoke.request(%22GET%22, %22/api%22, new Handler%3CResponse%3E() %7B%0A            @Override%0A            public void handle(Response resp) %7B%0A                assertEquals(200, resp.getStatusCode());%0A%0A                yoke.request(%22GET%22, %22/api/%22, new Handler%3CResponse%3E() %7B%0A                    @Override%0A                    public void handle(Response resp) %7B%0A                        assertEquals(200, resp.getStatusCode());%0A                        testComplete();%0A                    %7D%0A                %7D);%0A            %7D%0A        %7D);%0A    %7D
 %0A%7D%0A

add tests to verify optional trailing slash