/*******************************************************************************
 * 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.ofbiz.jetty.container;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.mortbay.jetty.AbstractConnector;
import org.mortbay.jetty.NCSARequestLog;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.ajp.Ajp13SocketConnector;
import org.mortbay.jetty.bio.SocketConnector;
import org.mortbay.jetty.handler.RequestLogHandler;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.servlet.HashSessionManager;
import org.mortbay.jetty.servlet.SessionHandler;
import org.mortbay.jetty.webapp.WebAppContext;
import org.mortbay.thread.BoundedThreadPool;
import org.ofbiz.base.component.ComponentConfig;
import org.ofbiz.base.container.Container;
import org.ofbiz.base.container.ContainerConfig;
import org.ofbiz.base.container.ContainerException;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.SSLUtil;
import org.ofbiz.base.util.UtilValidate;


/**
 * JettyContainer - Container implementation for Jetty 6
 *
 */
public class JettyContainer implements Container {

    public static final String module = JettyContainer.class.getName();

    protected String configFile = null;
    private Map<String, Server> servers = new HashMap<String, Server>();

    /**
     * @see org.ofbiz.base.container.Container#init(java.lang.String[],java.lang.String)
     */
    public void init(String[] args, String configFile) {
        this.configFile = configFile;
    }

    private void initJetty() throws ContainerException {

        // configure JSSE properties
        SSLUtil.loadJsseProperties();

        // get the container
        ContainerConfig.Container jc = ContainerConfig.getContainer("jetty-container", configFile);

        // create the servers
        for (ContainerConfig.Container.Property property : jc.properties.values()) {
            servers.put(property.name, createServer(property));
        }

        // load the applications
        Collection<ComponentConfig> componentConfigs = ComponentConfig.getAllComponents();
        if (componentConfigs != null) {

            for (Object componentConfig : componentConfigs) {

                ComponentConfig component = (ComponentConfig) componentConfig;

                for (ComponentConfig.WebappInfo webappInfo : component.getWebappInfos()) {

                    List<String> virtualHosts = webappInfo.getVirtualHosts();
                    Map<String, String> initParameters = webappInfo.getInitParameters();

                    Server server = servers.get(webappInfo.server);

                    if (server == null) {
                        Debug.logWarning("Server with name [" + webappInfo.server + "] not found; not mounting [" + webappInfo.name + "]", module);
                    } else {

                        // set the root location (make sure we set the paths correctly)
                        String location = component.getRootLocation() + webappInfo.location;
                        location = location.replace('\\', '/');
                        if (location.endsWith("/")) {
                            location = location.substring(0, location.lastIndexOf("/"));
                        }

                        // load the application
                        String mountPoint = webappInfo.mountPoint;
                        if (mountPoint.endsWith("/*")) {
                            mountPoint = mountPoint.substring(0, mountPoint.lastIndexOf("/"));
                        }

                        WebAppContext context = new WebAppContext(location, mountPoint);
                        context.setAttribute("_serverId", webappInfo.server);
                        context.setLogUrlOnStart(true);

                         // set the session manager
                        HashSessionManager sm = new HashSessionManager();
                        context.setSessionHandler(new SessionHandler(sm));

                        // set the virtual hosts
                        if (UtilValidate.isNotEmpty(virtualHosts)) {
                            context.setVirtualHosts(virtualHosts.toArray(new String[virtualHosts.size()]));
                        }

                        // set the init parameters
                        if (UtilValidate.isNotEmpty(initParameters)) {
                            context.setInitParams(initParameters);
                        }

                        server.addHandler(context);
                    }
                }
            }
        }
    }

    private Server createServer(ContainerConfig.Container.Property serverConfig) throws ContainerException {

        Server server = new Server();

        // configure the connectors / loggers
        for (ContainerConfig.Container.Property props : serverConfig.properties.values()) {

            if ("send-server-version".equals(props.name)) {
                if ("false".equalsIgnoreCase(props.value)) {
                    server.setSendServerVersion(false);
                }
            } else if ("connector".equals(props.value)) {

                if ("http".equals(props.getProperty("type").value)) {

                    AbstractConnector connector = new SocketConnector();
                    setConnectorOptions(connector, props);
                    server.addConnector(connector);

                } else if ("https".equals(props.getProperty("type").value)) {

                    SslSocketConnector connector = new SslSocketConnector();
                    setConnectorOptions(connector, props);

                    if (props.getProperty("keystore") != null) {
                        connector.setKeystore(props.getProperty("keystore").value);
                    }
                    if (props.getProperty("password") != null) {
                        connector.setPassword(props.getProperty("password").value);
                    }
                    if (props.getProperty("key-password") != null) {
                        connector.setKeyPassword(props.getProperty("key-password").value);
                    }
                    if (props.getProperty("client-auth") != null) {
                        if ("need".equals(props.getProperty("client-auth").value)) {
                            connector.setNeedClientAuth(true);
                        } else if ("want".equals(props.getProperty("client-auth").value)) {
                            connector.setWantClientAuth(true);
                        }
                    }

                    server.addConnector(connector);

                } else if ("nio-http".equals(props.getProperty("type").value)) {

                    AbstractConnector connector = new SelectChannelConnector();
                    setConnectorOptions(connector, props);
                    server.addConnector(connector);

                } else if ("nio-https".equals(props.getProperty("type").value)) {

                    SslSelectChannelConnector connector = new SslSelectChannelConnector();
                    setConnectorOptions(connector, props);

                    if (props.getProperty("keystore") != null) {
                        connector.setKeystore(props.getProperty("keystore").value);
                    }
                    if (props.getProperty("password") != null) {
                        connector.setPassword(props.getProperty("password").value);
                    }
                    if (props.getProperty("key-password") != null) {
                        connector.setKeyPassword(props.getProperty("key-password").value);
                    }
                    if (props.getProperty("need-client-auth") != null) {
                        boolean needClientAuth = "true".equalsIgnoreCase(props.getProperty("need-client-auth").value);
                        connector.setNeedClientAuth(needClientAuth);
                    }

                    server.addConnector(connector);

                } else if ("ajp13".equals(props.getProperty("type").value)) {

                    AbstractConnector connector = new Ajp13SocketConnector();
                    setConnectorOptions(connector, props);
                    server.addConnector(connector);
                }

            } else if ("request-log".equals(props.value)) {

                RequestLogHandler requestLogHandler = new RequestLogHandler();

                NCSARequestLog requestLog = new NCSARequestLog();

                if (props.getProperty("filename") != null) {
                    requestLog.setFilename(props.getProperty("filename").value);
                }

                if (props.getProperty("append") != null) {
                    requestLog.setAppend("true".equalsIgnoreCase(props.getProperty("append").value));
                }

                if (props.getProperty("extended") != null) {
                    requestLog.setExtended("true".equalsIgnoreCase(props.getProperty("extended").value));
                }

                if (props.getProperty("timezone") != null) {
                    requestLog.setLogTimeZone(props.getProperty("timezone").value);
                }

                if (props.getProperty("date-format") != null) {
                    requestLog.setLogDateFormat(props.getProperty("date-format").value);
                }

                if (props.getProperty("retain-days") != null) {
                    int days = 90;
                    try {
                        days = Integer.parseInt(props.getProperty("retain-days").value);
                    } catch (NumberFormatException e) {
                        days = 90;
                    }
                    requestLog.setRetainDays(days);
                }

                requestLogHandler.setRequestLog(requestLog);
                server.addHandler(requestLogHandler);
            }
        }

        return server;
    }

    private void setConnectorOptions(AbstractConnector connector, ContainerConfig.Container.Property props) throws ContainerException {

        String systemHost = null;
        if ("default".equals(props.getProperty("type").value)) {
            systemHost = System.getProperty(props.name + ".host");
        }
        if (props.getProperty("host") != null && systemHost == null) {
            connector.setHost(props.getProperty("host").value);
        } else {
            String host = "0.0.0.0";
            if (systemHost != null) {
                host = systemHost;
            }
            connector.setHost(host);
        }

        String systemPort = null;
        if ("default".equals(props.getProperty("type").value)) {
            systemPort = System.getProperty(props.name + ".port");
        }
        if (props.getProperty("port") != null && systemPort == null) {
            int value = 8080;
            try {
                value = Integer.parseInt(props.getProperty("port").value);
            } catch (NumberFormatException e) {
                value = 8080;
            }
            if (value == 0) value = 8080;

            connector.setPort(value);
        } else {
            int port = 8080;
            if (systemPort != null) {
                try {
                    port = Integer.parseInt(systemPort);
                } catch (NumberFormatException e) {
                    port = 8080;
                }
            }
            connector.setPort(port);
        }

        if (props.getProperty("buffer-size") != null) {
            int value = 0;
            try {
                value = Integer.parseInt(props.getProperty("buffer-size").value);
            } catch (NumberFormatException e) {
                value = 0;
            }
            if (value > 0) {
                connector.setResponseBufferSize(value);
            }
        }

        if (props.getProperty("linger-time") != null) {
            int value = 0;
            try {
                value = Integer.parseInt(props.getProperty("linger-time").value);
            } catch (NumberFormatException e) {
                value = 0;
            }
            if (value > 0) {
                connector.setSoLingerTime(value);
            }
        }

        if (props.getProperty("low-resource-max-idle-time") != null) {
            int value = 0;
            try {
                value = Integer.parseInt(props.getProperty("low-resource-max-idle-time").value);
            } catch (NumberFormatException e) {
                value = 0;
            }
            if (value > 0) {
                connector.setLowResourceMaxIdleTime(value);
            }
        }


        BoundedThreadPool threadPool = new BoundedThreadPool();

        if (props.getProperty("min-threads") != null) {
            int value = 0;
            try {
                value = Integer.parseInt(props.getProperty("min-threads").value);
            } catch (NumberFormatException e) {
                value = 0;
            }
            if (value > 0) {
                threadPool.setMinThreads(value);
            }
        }

        if (props.getProperty("max-threads") != null) {
            int value = 0;
            try {
                value = Integer.parseInt(props.getProperty("max-threads").value);
            } catch (NumberFormatException e) {
                value = 0;
            }
            if (value > 0) {
                threadPool.setMaxThreads(value);
            }
        }

        if (props.getProperty("max-idle-time") != null) {
            int value = 0;
            try {
                value = Integer.parseInt(props.getProperty("max-idle-time").value);
            } catch (NumberFormatException e) {
                value = 0;
            }
            if (value > 0) {
                threadPool.setMaxIdleTimeMs(value);
            }
        }

        if (props.getProperty("low-threads") != null) {
            int value = 0;
            try {
                value = Integer.parseInt(props.getProperty("low-threads").value);
            } catch (NumberFormatException e) {
                value = 0;
            }
            if (value > 0) {
                threadPool.setLowThreads(value);
            }
        }

        connector.setThreadPool(threadPool);

    }

    /**
     * @see org.ofbiz.base.container.Container#start()
     */
    public boolean start() throws ContainerException {
        // start the server(s)
        this.initJetty();
        if (servers != null) {
            for (Server server : servers.values()) {
                try {
                    server.start();
                } catch (Exception e) {
                    Debug.logError(e, "Jetty Server Exception", module);
                    throw new ContainerException(e);
                }
            }
        }
        return true;
    }

    /**
     * @see org.ofbiz.base.container.Container#stop()
     */
    public void stop() throws ContainerException {
        if (servers != null) {
            for (Server server : servers.values()) {
                try {
                    server.stop();
                } catch (Exception e) {
                    Debug.logWarning(e, module);
                }
            }
        }
    }
}
