/**
 * 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.oozie.server;

import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.ProvisionException;
import org.apache.hadoop.conf.Configuration;
import org.apache.oozie.server.guice.OozieGuiceModule;
import org.apache.oozie.service.ConfigurationService;
import org.apache.oozie.service.ServiceException;
import org.apache.oozie.service.Services;
import org.apache.oozie.util.ConfigUtils;
import org.eclipse.jetty.rewrite.handler.RewriteHandler;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
import org.eclipse.jetty.webapp.WebAppContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Objects;

/**
 *  Class to start Oozie inside an embedded Jetty server.
 */
public class EmbeddedOozieServer {
    private static final Logger LOG = LoggerFactory.getLogger(EmbeddedOozieServer.class);
    protected static final String OOZIE_HTTPS_TRUSTSTORE_FILE = "oozie.https.truststore.file";
    protected static final String OOZIE_HTTPS_TRUSTSTORE_PASS = "oozie.https.truststore.pass";
    protected static final String TRUSTSTORE_PATH_SYSTEM_PROPERTY = "javax.net.ssl.trustStore";
    protected static final String TRUSTSTORE_PASS_SYSTEM_PROPERTY = "javax.net.ssl.trustStorePassword";
    private static String contextPath;
    protected Server server;
    private int httpPort;
    private int httpsPort;
    private final WebAppContext servletContextHandler;
    private final ServletMapper oozieServletMapper;
    private final FilterMapper oozieFilterMapper;
    private JspHandler jspHandler;
    private Services serviceController;
    private SSLServerConnectorFactory sslServerConnectorFactory;
    private Configuration conf;
    private final RewriteHandler oozieRewriteHandler;
    private final ConstraintSecurityHandler constraintSecurityHandler;

    /**
     * Construct Oozie server
     * @param server jetty server to be embedded
     * @param jspHandler handler responsible for setting webapp context for JSP
     * @param serviceController controller for Oozie services; must be already initialized
     * @param sslServerConnectorFactory factory to create server connector configured for SSL
     * @param oozieRewriteHandler URL rewriter
     * @param servletContextHandler main web application context handler
     * @param oozieServletMapper maps servlets to URLs
     * @param oozieFilterMapper  maps filters
     * @param constraintSecurityHandler constraint security handler
     */
    @Inject
    public EmbeddedOozieServer(final Server server,
                               final JspHandler jspHandler,
                               final Services serviceController,
                               final SSLServerConnectorFactory sslServerConnectorFactory,
                               final RewriteHandler oozieRewriteHandler,
                               final WebAppContext servletContextHandler,
                               final ServletMapper oozieServletMapper,
                               final FilterMapper oozieFilterMapper,
                               final ConstraintSecurityHandler constraintSecurityHandler)
    {
        this.constraintSecurityHandler = constraintSecurityHandler;
        this.serviceController = Objects.requireNonNull(serviceController, "serviceController is null");
        this.jspHandler = Objects.requireNonNull(jspHandler, "jspHandler is null");
        this.sslServerConnectorFactory = Objects.requireNonNull(sslServerConnectorFactory,
                "sslServerConnectorFactory is null");
        this.server = Objects.requireNonNull(server, "server is null");
        this.oozieRewriteHandler = Objects.requireNonNull(oozieRewriteHandler, "rewriter is null");
        this.servletContextHandler = Objects.requireNonNull(servletContextHandler, "servletContextHandler is null");
        this.oozieServletMapper = Objects.requireNonNull(oozieServletMapper, "oozieServletMapper is null");
        this.oozieFilterMapper = Objects.requireNonNull(oozieFilterMapper, "oozieFilterMapper is null");
    }

    /**
     * Set up the Oozie server by configuring jetty server settings and starts Oozie services
     *
     * @throws URISyntaxException if the server URI is not well formatted
     * @throws IOException in case of IO issues
     * @throws ServiceException if the server could not start
     */
    public void setup() throws URISyntaxException, IOException, ServiceException {
        conf = serviceController.get(ConfigurationService.class).getConf();
        setContextPath(conf);
        httpPort = getConfigPort(ConfigUtils.OOZIE_HTTP_PORT);

        HttpConfiguration httpConfiguration = new HttpConfigurationWrapper(conf).getDefaultHttpConfiguration();

        ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory(httpConfiguration));
        connector.setPort(httpPort);
        connector.setHost(conf.get(ConfigUtils.OOZIE_HTTP_HOSTNAME));

        HandlerCollection handlerCollection = new HandlerCollection();
        setTrustStore();
        setTrustStorePassword();

        if (isSecured()) {
            httpsPort =  getConfigPort(ConfigUtils.OOZIE_HTTPS_PORT);
            ServerConnector sslConnector = sslServerConnectorFactory.createSecureServerConnector(httpsPort, conf, server);
            server.setConnectors(new Connector[]{connector, sslConnector});
            constraintSecurityHandler.setHandler(servletContextHandler);
            handlerCollection.addHandler(constraintSecurityHandler);
        }
        else {
            server.setConnectors(new Connector[]{connector});
        }

        servletContextHandler.setContextPath(contextPath);
        oozieServletMapper.mapOozieServlets();
        oozieFilterMapper.addFilters();

        servletContextHandler.setParentLoaderPriority(true);
        jspHandler.setupWebAppContext(servletContextHandler);

        addErrorHandler();

        handlerCollection.addHandler(servletContextHandler);
        handlerCollection.addHandler(oozieRewriteHandler);
        server.setHandler(handlerCollection);
    }

    /**
     * set the truststore path from the config file, if is not set by the user
     */
    private void setTrustStore() {
        if (System.getProperty(TRUSTSTORE_PATH_SYSTEM_PROPERTY) == null) {
            final String trustStorePath = conf.get(OOZIE_HTTPS_TRUSTSTORE_FILE);
            if (trustStorePath != null) {
                LOG.info("Setting javax.net.ssl.trustStore from config file");
                System.setProperty(TRUSTSTORE_PATH_SYSTEM_PROPERTY, trustStorePath);
            }
        } else {
            LOG.info("javax.net.ssl.trustStore is already set. The value from config file will be ignored");
        }
    }

    /**
     * set the truststore password from the config file, if is not set by the user
     */
    private void setTrustStorePassword() {
        if (System.getProperty(TRUSTSTORE_PASS_SYSTEM_PROPERTY) == null) {
            final String trustStorePassword = conf.get(OOZIE_HTTPS_TRUSTSTORE_PASS);
            if (trustStorePassword != null) {
                LOG.info("Setting javax.net.ssl.trustStorePassword from config file");
                System.setProperty(TRUSTSTORE_PASS_SYSTEM_PROPERTY, trustStorePassword);
            }
        } else {
            LOG.info("javax.net.ssl.trustStorePassword is already set. The value from config file will be ignored");
        }
    }

    private void addErrorHandler() {
        ErrorPageErrorHandler errorHandler = new ErrorPageErrorHandler();
        errorHandler.addErrorPage(HttpServletResponse.SC_BAD_REQUEST, "/error");
        errorHandler.addErrorPage(HttpServletResponse.SC_UNAUTHORIZED, "/error");
        errorHandler.addErrorPage(HttpServletResponse.SC_FORBIDDEN, "/error");
        errorHandler.addErrorPage(HttpServletResponse.SC_NOT_FOUND, "/error");
        errorHandler.addErrorPage(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "/error");
        errorHandler.addErrorPage(HttpServletResponse.SC_CONFLICT, "/error");
        errorHandler.addErrorPage(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "/error");
        errorHandler.addErrorPage(HttpServletResponse.SC_NOT_IMPLEMENTED, "/error");
        errorHandler.addErrorPage(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "/error");
        errorHandler.addErrorPage("java.lang.Throwable", "/error");
        servletContextHandler.setErrorHandler(errorHandler);
    }

    private int getConfigPort(String confVar) {
        String confHttpPort = conf.get(confVar);
        int port;
        try {
            port = Integer.parseInt(confHttpPort);
        }
        catch (final NumberFormatException nfe) {
            throw new NumberFormatException(String.format("Port number for '%s \"%s\" ('%s') is not an integer.",
                    confVar, confHttpPort, confHttpPort));
        }
        return port;
    }

    private boolean isSecured() {
        String isSSLEnabled = conf.get("oozie.https.enabled");
        LOG.info("Server started with oozie.https.enabled = " + isSSLEnabled);
        return isSSLEnabled != null && Boolean.valueOf(isSSLEnabled);
    }

    public static void setContextPath(Configuration oozieConfiguration) {
        String baseUrl = oozieConfiguration.get("oozie.base.url");
        String contextPath = baseUrl.substring(baseUrl.lastIndexOf("/"));
        LOG.info("Server started with contextPath = " + contextPath);
        EmbeddedOozieServer.contextPath = contextPath;
    }

    public static String getContextPath(Configuration oozieConfiguration) {
        if (contextPath != null) {
            return contextPath;
        }

        setContextPath(oozieConfiguration);
        return EmbeddedOozieServer.contextPath;
    }

    public void start() throws Exception {
        server.start();
        LOG.info("Server started.");
    }

    public void shutdown() throws Exception {
        LOG.info("Shutting down.");
        if (serviceController != null) {
            serviceController.destroy();
            LOG.info("Oozie services stopped.");
        }

        if (server != null) {
            server.stop();
            LOG.info("Server stopped.");
        }
    }

    public void join() throws InterruptedException {
        server.join();
    }

    public void addShutdownHook() {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                try {
                    shutdown();
                } catch (final Exception e) {
                    LOG.error(String.format("There were errors during shutdown. Error message: %s", e.getMessage()));
                }
            }
        });
    }

    public static void main(String[] args) throws Exception {
        final Injector guiceInjector = Guice.createInjector(new OozieGuiceModule());

        EmbeddedOozieServer embeddedOozieServer = null;
        try {
            embeddedOozieServer = guiceInjector.getInstance(EmbeddedOozieServer.class);
        }
        catch (final ProvisionException ex) {
            LOG.error(ex.getMessage());
            System.exit(1);
        }

        embeddedOozieServer.addShutdownHook();
        embeddedOozieServer.setup();
        try {
            embeddedOozieServer.start();
        } catch (final Exception e) {
            LOG.error(String.format("Could not start EmbeddedOozieServer! Error message: %s", e.getMessage()));
            System.exit(1);
        }
        embeddedOozieServer.join();
    }
}
