package com.codingchili.core.listener.transport;

import io.vertx.core.Future;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.handler.StaticHandler;

import java.util.Objects;
import java.util.function.Supplier;

import com.codingchili.core.configuration.RestHelper;
import com.codingchili.core.context.CoreContext;
import com.codingchili.core.listener.*;

import static com.codingchili.core.configuration.CoreStrings.*;

/**
 * HTTP/REST transport listener.
 */
public class RestListener implements CoreListener {
    private ListenerSettings settings = ListenerSettings.getDefaultSettings();
    private String path;
    private String regex;
    private CoreContext core;
    private CoreHandler handler;
    private Router router;


    @Override
    public void init(CoreContext core) {
        router = Router.router(core.vertx());
        router.route().handler(BodyHandler.create().setBodyLimit(settings.getMaxRequestBytes()));
        RestHelper.addHeaders(router, settings.isSecure());

        // enable routing for static resources.
        if (regex != null && path != null) {
            router.routeWithRegex(regex).handler(StaticHandler.create() // caching enabled by static handler.
                    //.setCachingEnabled(false) -- set in HttpOptions.
                    .setWebRoot(path));
        }

        router.route().handler(this::packet);
        handler.init(core);
        this.core = core;
    }

    /**
     * @param path  a directory from which to serve static resources.
     * @param regex a regular expression that maps request routes to the static handler.
     * @return fluent.
     */
    public RestListener setResources(String path, String regex) {
        Objects.requireNonNull(path);
        Objects.requireNonNull(regex);
        this.path = path;
        this.regex = regex;
        return this;
    }

    @Override
    public CoreListener settings(ListenerSettings settings) {
        this.settings = settings;
        return this;
    }

    @Override
    public CoreListener handler(CoreHandler handler) {
        this.handler = handler;
        return this;
    }

    @Override
    public void start(Future<Void> start) {
        core.vertx().createHttpServer(settings.getHttpOptions())
                .requestHandler(router)
                .listen(settings.getPort(), getBindAddress(), listen -> {
                    if (listen.succeeded()) {
                        settings.addListenPort(listen.result().actualPort());
                        handler.start(start);
                    } else {
                        start.fail(listen.cause());
                    }
                });
    }

    @Override
    public void stop(Future<Void> stop) {
        handler.stop(stop);
    }

    private void packet(RoutingContext context) {
        handler.handle(new RestRequest(context, settings));
    }

    @Override
    public String toString() {
        return handler.getClass().getSimpleName() + LOG_AT + handler.address() + " port :" +
                settings.getPort();
    }
}
@@ -56,370 +56,446 @@
 ort 
-io.vertx.core.Future;%0D%0Aimport io.vertx.ext.web.Router;%0D%0Aimport io.vertx.ext.web.RoutingContext;%0D%0Aimport io.vertx.ext.web.handler.BodyHandler;%0D%0Aimport io.vertx.ext.web.handler.StaticHandl
+com.codingchili.core.configuration.RestHelper;%0D%0Aimport com.codingchili.core.context.CoreContext;%0D%0Aimport com.codingchili.core.listener.CoreHandler;%0D%0Aimport com.codingchili.core.listener.CoreListen
 er;%0D%0A
-%0D%0A
 import 
-java.util.Objects;%0D%0Aimport java.util.function.Supplier;%0D%0A%0D%0Aimport com.codingchili.core.configuration.RestHelper;%0D%0Aimport com.codingchili.core.context.CoreContext;
+com.codingchili.core.listener.ListenerSettings;%0D%0Aimport io.vertx.core.Future;%0D%0Aimport io.vertx.core.Promise;%0D%0Aimport io.vertx.ext.web.Router;%0D%0Aimport io.vertx.ext.web.RoutingContext;%0D%0Aimport io.vertx.ext.web.handler.BodyHandler;%0D%0A
 %0D%0Aim
@@ -491,32 +491,39 @@
 dler;%0D%0A%0D%0Aimport 
+static 
 com.codingchili.
@@ -531,21 +531,41 @@
 ore.
-listener.*;%0D%0A
+configuration.CoreStrings.LOG_AT;
 %0D%0Aim
@@ -623,17 +623,30 @@
 Strings.
-*
+getBindAddress
 ;%0D%0A%0D%0A/**
@@ -835,46 +835,58 @@
 ate 
-String path;%0D%0A    private String regex
+final Promise%3CRouter%3E onRouter = Promise.promise()
 ;%0D%0A 
@@ -979,18 +979,16 @@
 ter;%0D%0A%0D%0A
-%0D%0A
     @Ove
@@ -1243,26 +1243,24 @@
 re());%0D%0A
-%0D%0A
         
 // enabl
@@ -1255,868 +1255,460 @@
     
-// enable routing for static resources.%0D%0A        if (regex != null && path != null) %7B%0D%0A            router.routeWithRegex(regex).handler(StaticHandler.create() // caching enabled by static handler.%0D%0A                    //.setCachingEnabled(false) -- set in HttpOptions.%0D%0A                    .setWebRoot(path));%0D%0A        %7D%0D%0A%0D%0A        router.route().handler(this::packet);%0D%0A        handler.init(core);%0D%0A        this.core = core;%0D%0A    %7D%0D%0A%0D%0A    /**%0D%0A     * @param path  a dir
+router.route().handler(this::packet);%0D%0A        handler.init(core);%0D%0A        this.core = core;%0D%0A%0D%0A        // invoke the callback when router is created from the context.%0D%0A        onRouter.complete(router);%0D%0A    %7D%0D%0A%0D%0A    /**%0D%0A     * @return exposes the router obj
 ect
+ f
 or
-y
  f
-rom which to serve static resources.%0D%0A     * @param regex a regular expression that maps request routes to the static handler.%0D%0A     * @return fluent.%0D%0A     */%0D%0A    public RestListener setResources(String path, String regex) %7B%0D%0A        Objects.requireNonNull(path);%0D%0A        Objects.requireNonNull(regex);%0D%0A        this.path = path;%0D%0A        this.regex = regex;%0D%0A        return this
+urther configuration, manual route setups, fallbacks%0D%0A     * and support for adding a static handler.%0D%0A     */%0D%0A    public Future%3CRouter%3E router() %7B%0D%0A        return onRouter.future()
 ;%0D%0A 

remove path/regex static routing from RestListener - now exposes the Router which is more powerful.