/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.hcatalog.templeton;

import com.sun.jersey.api.core.PackagesResourceConfig;
import com.sun.jersey.spi.container.servlet.ServletContainer;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hdfs.web.AuthFilter;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.util.GenericOptionsParser;
import org.eclipse.jetty.rewrite.handler.RedirectPatternRule;
import org.eclipse.jetty.rewrite.handler.RewriteHandler;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.FilterMapping;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.slf4j.bridge.SLF4JBridgeHandler;

/**
 * The main executable that starts up and runs the Server.
 */
public class Main {
    public static final String SERVLET_PATH = "templeton";
    private static final Log LOG = LogFactory.getLog(Main.class);

    public static final int DEFAULT_PORT = 8080;

    private static volatile AppConfig conf;

    /**
     * Retrieve the config singleton.
     */
    public static synchronized AppConfig getAppConfigInstance() {
        if (conf == null)
            LOG.error("Bug: configuration not yet loaded");
        return conf;
    }

    public Main(String[] args) {
        init(args);
    }

    public void init(String[] args) {
        initLogger();
        conf = loadConfig(args);
        conf.startCleanup();
        LOG.debug("Loaded conf " + conf);
    }

    // Jersey uses java.util.logging - bridge to slf4
    private void initLogger() {
        java.util.logging.Logger rootLogger
            = java.util.logging.LogManager.getLogManager().getLogger("");
        for (java.util.logging.Handler h : rootLogger.getHandlers())
            rootLogger.removeHandler(h);

        SLF4JBridgeHandler.install();
    }

    public AppConfig loadConfig(String[] args) {
        AppConfig cf = new AppConfig();
        try {
            GenericOptionsParser parser = new GenericOptionsParser(cf, args);
            if (parser.getRemainingArgs().length > 0)
                usage();
        } catch (IOException e) {
            LOG.error("Unable to parse options: " + e);
            usage();
        }

        return cf;
    }

    public void usage() {
        System.err.println("usage: templeton [-Dtempleton.port=N] [-D...]");
        System.exit(1);
    }

    public void run() {
        int port = conf.getInt(AppConfig.PORT, DEFAULT_PORT);
        try {
            checkEnv();
            runServer(port);
            System.out.println("templeton: listening on port " + port);
            LOG.info("Templeton listening on port " + port);
        } catch (Exception e) {
            System.err.println("templeton: Server failed to start: " + e.getMessage());
            LOG.fatal("Server failed to start: " + e);
            System.exit(1);
        }
    }

    private void checkEnv() {
        checkCurrentDirPermissions();

    }

    private void checkCurrentDirPermissions() {
        //org.apache.commons.exec.DefaultExecutor requires
        // that current directory exists
        File pwd = new File(".");
        if (!pwd.exists()) {
            String msg = "Server failed to start: templeton: Current working directory '.' does not exist!";
            System.err.println(msg);
            LOG.fatal(msg);
            System.exit(1);
        }
    }

    public Server runServer(int port)
        throws Exception {

        //Authenticate using keytab
        if (UserGroupInformation.isSecurityEnabled()) {
            UserGroupInformation.loginUserFromKeytab(conf.kerberosPrincipal(),
                conf.kerberosKeytab());
        }

        // Create the Jetty server
        Server server = new Server(port);
        ServletContextHandler root = new ServletContextHandler(server, "/");

        // Add the Auth filter
        root.addFilter(makeAuthFilter(), "/*", FilterMapping.REQUEST);

        // Connect Jersey
        ServletHolder h = new ServletHolder(new ServletContainer(makeJerseyConfig()));
        root.addServlet(h, "/" + SERVLET_PATH + "/*");

        // Add any redirects
        addRedirects(server);

        // Start the server
        server.start();
        return server;
    }

    // Configure the AuthFilter with the Kerberos params iff security
    // is enabled.
    public FilterHolder makeAuthFilter() {
        FilterHolder authFilter = new FilterHolder(AuthFilter.class);
        if (UserGroupInformation.isSecurityEnabled()) {
            authFilter.setInitParameter("dfs.web.authentication.signature.secret",
                conf.kerberosSecret());
            authFilter.setInitParameter("dfs.web.authentication.kerberos.principal",
                conf.kerberosPrincipal());
            authFilter.setInitParameter("dfs.web.authentication.kerberos.keytab",
                conf.kerberosKeytab());
        }
        return authFilter;
    }

    public PackagesResourceConfig makeJerseyConfig() {
        PackagesResourceConfig rc
            = new PackagesResourceConfig("org.apache.hcatalog.templeton");
        HashMap<String, Object> props = new HashMap<String, Object>();
        props.put("com.sun.jersey.api.json.POJOMappingFeature", "true");
        props.put("com.sun.jersey.config.property.WadlGeneratorConfig",
            "org.apache.hcatalog.templeton.WadlConfig");
        rc.setPropertiesAndFeatures(props);

        return rc;
    }

    public void addRedirects(Server server) {
        RewriteHandler rewrite = new RewriteHandler();

        RedirectPatternRule redirect = new RedirectPatternRule();
        redirect.setPattern("/templeton/v1/application.wadl");
        redirect.setLocation("/templeton/application.wadl");
        rewrite.addRule(redirect);

        HandlerList handlerlist = new HandlerList();
        ArrayList<Handler> handlers = new ArrayList<Handler>();

        // Any redirect handlers need to be added first
        handlers.add(rewrite);

        // Now add all the default handlers
        for (Handler handler : server.getHandlers()) {
            handlers.add(handler);
        }
        Handler[] newlist = new Handler[handlers.size()];
        handlerlist.setHandlers(handlers.toArray(newlist));
        server.setHandler(handlerlist);
    }

    public static void main(String[] args) {
        Main templeton = new Main(args);
        templeton.run();
    }
}
