/* Copyright (c) 2013-2014 Boundless and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Distribution License v1.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/org/documents/edl-v10.html
 *
 * Contributors:
 * Gabriel Roldan (Boundless) - initial implementation
 */
package org.locationtech.geogig.web;

import java.io.File;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Map;

import org.locationtech.geogig.api.Context;
import org.locationtech.geogig.api.DefaultPlatform;
import org.locationtech.geogig.api.GeoGIG;
import org.locationtech.geogig.api.GlobalContextBuilder;
import org.locationtech.geogig.api.Platform;
import org.locationtech.geogig.api.plumbing.ResolveGeogigURI;
import org.locationtech.geogig.cli.CLIContextBuilder;
import org.locationtech.geogig.rest.TaskStatusResource;
import org.locationtech.geogig.rest.osm.OSMRouter;
import org.locationtech.geogig.rest.postgis.PGRouter;
import org.locationtech.geogig.rest.repository.CommandResource;
import org.locationtech.geogig.rest.repository.FixedEncoder;
import org.locationtech.geogig.rest.repository.RepositoryProvider;
import org.locationtech.geogig.rest.repository.RepositoryRouter;
import org.restlet.Application;
import org.restlet.Component;
import org.restlet.Restlet;
import org.restlet.Router;
import org.restlet.data.Protocol;
import org.restlet.data.Request;
import org.restlet.data.Response;

import com.noelios.restlet.application.Decoder;

/**
 * Both an embedded jetty launcher
 */
public class Main extends Application {

    static {
        setup();
    }

    private RepositoryProvider repoProvider;

    public Main() {
        super();
    }

    public Main(GeoGIG geogig) {
        super();
        this.repoProvider = new SingleRepositoryProvider(geogig);
    }

    @Override
    public void setContext(org.restlet.Context context) {
        super.setContext(context);
        assert context != null;

        Map<String, Object> attributes = context.getAttributes();

        GeoGIG geogig;
        if (attributes.containsKey("geogig")) {
            geogig = (GeoGIG) attributes.get("geogig");
        } else {
            // revisit, not used at all
            // ServletContext sc = (ServletContext) dispatcher.getContext()
            // .getAttributes().get("org.restlet.ext.servlet.ServletContext");
            // String repo = sc.getInitParameter("repository");
            String repo = null;
            if (repo == null) {
                repo = System.getProperty("org.locationtech.geogig.web.repository");
            }
            if (repo == null) {
                return;
                // throw new IllegalStateException(
                // "Cannot launch geogig servlet without `repository` parameter");
            }
            geogig = loadGeoGIG(repo);
        }
        repoProvider = new SingleRepositoryProvider(geogig);
    }

    @Override
    public Restlet createRoot() {

        Router router = new Router() {

            @Override
            protected synchronized void init(Request request, Response response) {
                super.init(request, response);
                if (!isStarted()) {
                    return;
                }
                request.getAttributes().put(RepositoryProvider.KEY, repoProvider);
            }
        };
        Router repo = new RepositoryRouter();
        Router osm = new OSMRouter();
        Router postgis = new PGRouter();

        router.attach("/tasks", TaskStatusResource.class);
        router.attach("/tasks/{taskId}.{extension}", TaskStatusResource.class);
        router.attach("/tasks/{taskId}", TaskStatusResource.class);

        router.attach("/osm", osm);
        router.attach("/postgis", postgis);
        router.attach("/repo", repo);
        router.attach("/{command}.{extension}", CommandResource.class);
        router.attach("/{command}", CommandResource.class);

        org.restlet.Context context = getContext();
        // enable support for compressing responses if the client supports it.
        // NOTE: restlet 1.0.8 leaves a dangling thread on each request (see
        // EncodeRepresentation.getStream()
        // This problem is fixed in latest versions (2.x) of restlet. See the javadocs for
        // FixedEncoder for further detail
        // Encoder responseEncoder = new com.noelios.restlet.application.Encoder(context);
        FixedEncoder encoder = new FixedEncoder(context);
        encoder.setEncodeRequest(false);
        encoder.setEncodeResponse(true);
        encoder.setNext(router);

        Decoder decoder = new Decoder(context);
        decoder.setDecodeRequest(true);
        decoder.setDecodeResponse(false);
        decoder.setNext(encoder);

        return decoder;
    }

    static GeoGIG loadGeoGIG(String repo) {
        Platform platform = new DefaultPlatform();
        platform.setWorkingDir(new File(repo));
        Context inj = GlobalContextBuilder.builder.build();
        GeoGIG geogig = new GeoGIG(inj, platform.pwd());

        if (geogig.command(ResolveGeogigURI.class).call().isPresent()) {
            geogig.getRepository();
            return geogig;
        }

        return geogig;
    }

    static void startServer(String repo) throws Exception {
        GeoGIG geogig = loadGeoGIG(repo);
        org.restlet.Context context = new org.restlet.Context();
        Application application = new Main(geogig);
        application.setContext(context);
        Component comp = new Component();
        comp.getDefaultHost().attach(application);
        comp.getServers().add(Protocol.HTTP, 8182);
        comp.start();
    }

    static void setup() {
        GlobalContextBuilder.builder = new CLIContextBuilder();
    }

    public static void main(String[] args) throws Exception {
        LinkedList<String> argList = new LinkedList<String>(Arrays.asList(args));
        if (argList.size() == 0) {
            System.out.println("provide geogig repo path");
            System.exit(1);
        }
        String repo = argList.pop();
        startServer(repo);
    }

}

@@ -923,32 +923,89 @@
 StatusResource;%0A
+import org.locationtech.geogig.rest.geopkg.GeoPkgRouter;%0A
 import org.locat
@@ -3602,16 +3602,64 @@
 outer();
+%0A        Router geopackage = new GeoPkgRouter();
 %0A%0A      
@@ -3936,24 +3936,70 @@
 , postgis);%0A
+        router.attach(%22/geopkg%22, geopackage);%0A
         rout
@@ -5795,16 +5795,99 @@
 ation);%0A
+        System.err.printf(%22Starting server at port %25d for repo %25s%5Cn%22, 8182, repo);%0A
         
@@ -5948,24 +5948,64 @@
 mp.start();%0A
+        System.err.println(%22started.%22);%0A
     %7D%0A%0A    s

add geopkg router to web-app