package fr.synchrotron.soleil.ica.ci.service.multirepoproxy;

import fr.synchrotron.soleil.ica.proxy.utilities.HttpClientProxy;
import fr.synchrotron.soleil.ica.proxy.utilities.PUTHandler;
import io.netty.handler.codec.http.HttpResponseStatus;
import org.vertx.java.core.Handler;
import org.vertx.java.core.http.HttpServer;
import org.vertx.java.core.http.HttpServerRequest;
import org.vertx.java.core.http.RouteMatcher;
import org.vertx.java.core.json.JsonArray;
import org.vertx.java.core.json.JsonObject;
import org.vertx.java.platform.Verticle;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author Gregory Boissinot
 */
public class RepoProxyHttpEndpointVerticle extends Verticle {

    @Override
    public void start() {

        final JsonObject config = container.config();
        final int port = config.getInteger("proxyPort");
        final String proxyPath = config.getString("proxyPath");

        //GET
        final JsonArray repositories = config.getArray("repositories.get");
        final List<RepositoryObject> repos = buildRepoUrls(repositories);
        RouteMatcher routeMatcher = new RouteMatcher();
        routeMatcher.headWithRegEx(proxyPath + "/.*", new MutltiGETHandler(vertx, proxyPath, repos));
        routeMatcher.getWithRegEx(proxyPath + "/.*", new MutltiGETHandler(vertx, proxyPath, repos));

        //PUT
        final JsonObject putJsonObject = config.getObject("repo.put");
        final String repoHostPUT = putJsonObject.getString("host");
        final int repoPortPUT = putJsonObject.getInteger("port");
        final String repoURIPathPUT = putJsonObject.getString("uri");
        routeMatcher.putWithRegEx(proxyPath + "/.*", new PUTHandler(new HttpClientProxy(vertx, proxyPath, repoHostPUT, repoPortPUT, repoURIPathPUT)));


        //Other than HEAD, GET or PUT are not supported
        routeMatcher.allWithRegEx(proxyPath + "/.*", new Handler<HttpServerRequest>() {
            @Override
            public void handle(HttpServerRequest request) {
                request.response().setStatusCode(HttpResponseStatus.METHOD_NOT_ALLOWED.code());
                request.response().end();
            }
        });

        //No match pattern
        routeMatcher.noMatch(new Handler<HttpServerRequest>() {
            @Override
            public void handle(HttpServerRequest request) {
                request.response().setStatusCode(HttpResponseStatus.NOT_FOUND.code());
                request.response().end();
            }
        });

        final HttpServer httpServer = vertx.createHttpServer();
        httpServer.requestHandler(routeMatcher);
        httpServer.listen(port);

        container.logger().info("Webserver proxy started, listening on port:" + port);

    }

    private List<RepositoryObject> buildRepoUrls(JsonArray repositories) {
        List<RepositoryObject> result = new ArrayList<RepositoryObject>();
        for (Object repository : repositories) {
            JsonObject repositoryOject = (JsonObject) repository;

            final Map<String, Object> stringObjectMap = repositoryOject.toMap();
            for (Map.Entry<String, Object> stringObjectEntry : stringObjectMap.entrySet()) {
                final Map<String, Object> repoMap = (Map<String, Object>) stringObjectEntry.getValue();
                result.add(new RepositoryObject((String) repoMap.get("host"),
                        (int) repoMap.get("port"), (String) repoMap.get("uri")));
            }
        }
        return result;
    }
}

@@ -178,24 +178,96 @@
 PUTHandler;%0A
+import fr.synchrotron.soleil.ica.proxy.utilities.RequestHandlerWrapper;%0A
 import io.ne
@@ -309,16 +309,16 @@
 Status;%0A
-
 import o
@@ -1238,53 +1238,49 @@
     
-routeMatcher.headWithRegEx(proxyPath + %22/.*%22,
+final MutltiGETHandler mutltiGETHandler =
  new
@@ -1321,17 +1321,16 @@
 , repos)
-)
 ;%0A      
@@ -1344,19 +1344,20 @@
 Matcher.
-get
+head
 WithRegE
@@ -1377,21 +1377,17 @@
  %22/.*%22, 
-new M
+m
 utltiGET
@@ -1397,33 +1397,80 @@
 dler
-(vertx, proxyPath, repos)
+);%0A        routeMatcher.getWithRegEx(proxyPath + %22/.*%22, mutltiGETHandler
 );%0A%0A
@@ -2729,16 +2729,42 @@
 Handler(
+new RequestHandlerWrapper(
 routeMat
@@ -2768,16 +2768,17 @@
 Matcher)
+)
 ;%0A      

Use Request Haqndler Wrapper