/*
 * Javalin - https://javalin.io
 * Copyright 2017 David Åse
 * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
 */

package io.javalin.performance;

import com.carrotsearch.junitbenchmarks.BenchmarkOptions;
import com.carrotsearch.junitbenchmarks.BenchmarkRule;
import com.carrotsearch.junitbenchmarks.Clock;
import com.mashape.unirest.http.Unirest;
import io.javalin.http.Context;
import io.javalin.Javalin;
import io.javalin.apibuilder.CrudHandler;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import static io.javalin.apibuilder.ApiBuilder.after;
import static io.javalin.apibuilder.ApiBuilder.before;
import static io.javalin.apibuilder.ApiBuilder.crud;
import static io.javalin.apibuilder.ApiBuilder.get;
import static io.javalin.apibuilder.ApiBuilder.path;

@BenchmarkOptions(benchmarkRounds = 40000, warmupRounds = 5000, concurrency = 4, clock = Clock.NANO_TIME)
public class StupidPerformanceTest {

    private static Javalin app;
    private static String origin;

    @Rule
    public TestRule benchmarkRun = new BenchmarkRule();

    @AfterClass
    public static void tearDown() {
        app.stop();
    }

    @BeforeClass
    public static void setup() {
        // Thread.sleep(7500) // uncomment if running with VisualVM
        app = Javalin.create()
            .routes(() -> {
                before(ctx -> ctx.header("X-BEFORE", "Before"));
                before(ctx -> ctx.status(200));
                get("/health", ctx -> ctx.result("OK"));
                crud("/users/:user-id", new GenericController());
                path("/nested/path", () -> {
                    crud("/messages/:message-id", new GenericController());
                });
                after(ctx -> ctx.header("X-AFTER", "After"));
            }).start(0);
        origin = "http://localhost:" + app.port();
    }

    @Test
    @Ignore("Just for running manually")
    public void testPerformanceMaybe() throws Exception {

        Unirest.get(origin + "/health").asString();
        Unirest.get(origin + "/health").asString();

        Unirest.get(origin + "/users").asString();
        Unirest.post(origin + "/users").asString();
        Unirest.get(origin + "/users/1").asString();
        Unirest.patch(origin + "/users/1").asString();
        Unirest.delete(origin + "/users/1").asString();

        Unirest.get(origin + "/nested/path/messages").asString();
        Unirest.post(origin + "/nested/path/messages").asString();
        Unirest.get(origin + "/nested/path/messages/1").asString();
        Unirest.patch(origin + "/nested/path/messages/1").asString();
        Unirest.delete(origin + "/nested/path/messages/1").asString();

        Unirest.get(origin + "/not-found").asString(); // slow because WebJars

    }

    static class GenericController implements CrudHandler {
        public void getAll(Context ctx) {
            ctx.result("ALL");
        }

        public void getOne(Context ctx, String resourceId) {
            ctx.result(resourceId);
        }

        public void create(Context ctx) {
            ctx.result("Created");
        }

        public void update(Context ctx, String resourceId) {
            ctx.result("Updated " + resourceId);
        }

        public void delete(Context ctx, String resourceId) {
            ctx.result("Deleted " + resourceId);
        }
    }

}

@@ -382,40 +382,8 @@
 st;%0A
-import io.javalin.http.Context;%0A
 impo
@@ -443,24 +443,56 @@
 rudHandler;%0A
+import io.javalin.http.Context;%0A
 import org.j
@@ -950,10 +950,10 @@
 s = 
-40
+35
 000,
@@ -1062,378 +1062,210 @@
     
-private static Javalin app;%0A    private static String origin;%0A%0A    @Rule%0A    public TestRule benchmarkRun = new BenchmarkRule();%0A%0A    @AfterClass%0A    public static void tearDown() %7B%0A        app.stop();%0A    %7D%0A%0A    @BeforeClass%0A    public static void setup() %7B%0A        // Thread.sleep(7500) // uncomment if running with VisualVM%0A        app = Javalin.create()%0A            
+@Rule%0A    public TestRule benchmarkRun = new BenchmarkRule();%0A%0A    private static String origin;%0A    private static Javalin app = Javalin.create(%0A        config -%3E config.showJavalinBanner = false%0A    )
 .rou
@@ -1272,32 +1272,24 @@
 tes(() -%3E %7B%0A
-        
         befo
@@ -1341,24 +1341,16 @@
         
- 
-       
 before(c
@@ -1373,32 +1373,185 @@
 (200));%0A        
+get(%22/my-path/:param/*%22, ctx -%3E ctx.result(ctx.pathParam(%22param%22)));%0A        get(%22/1234/:1/:2/:3/:4%22, ctx -%3E ctx.result(ctx.pathParamMap().toString()));%0A
         get(%22/he
@@ -1579,32 +1579,24 @@
 ult(%22OK%22));%0A
-        
         crud
@@ -1637,32 +1637,24 @@
 troller());%0A
-        
         path
@@ -1678,24 +1678,16 @@
 () -%3E %7B%0A
-        
         
@@ -1758,28 +1758,12 @@
     
-    
-    %7D);%0A        
+%7D);%0A
     
@@ -1816,26 +1816,150 @@
 ));%0A    
-        %7D)
+%7D);%0A%0A    @BeforeClass%0A    public static void setup() %7B%0A        // Thread.sleep(7500) // uncomment if running with VisualVM%0A        app
 .start(0
@@ -2173,32 +2173,33 @@
 h%22).asString();%0A
+%0A
         Unirest.
@@ -2205,38 +2205,110 @@
 .get(origin + %22/
-health
+my-path/my-param/123%22).asString();%0A        Unirest.get(origin + %22/1234/1/2/3/4
 %22).asString();%0A%0A
@@ -2976,33 +2976,88 @@
 g();
- // slow because WebJars%0A
+%0A%0A    %7D%0A%0A    @AfterClass%0A    public static void tearDown() %7B%0A        app.stop();
 %0A   

Refactor performance test