/*
 * HttpFactory.java
 *
 * ====================================================================
 *
 *  Copyright 2006 The Apache Software Foundation
 *
 *  Licensed 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * Created on May 25, 2006, 10:11 AM
 *
 */

package org.apache.axis2.transport.http.server;

import edu.emory.mathcs.backport.java.util.concurrent.BlockingQueue;
import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue;
import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService;
import edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor;
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
import java.io.IOException;
import javax.xml.namespace.QName;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.description.TransportInDescription;
import org.apache.axis2.engine.ListenerManager;
import org.apache.axis2.transport.http.HTTPWorkerFactory;
import org.apache.http.HttpServerConnection;
import org.apache.http.impl.DefaultHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;

/**
 * Factory used to configure and create the various instances required in http transports.
 * Either configure this class in axis2.xml, or in code via the setters, or subclass it and specialize some factory methods to gain more control.
 *
 * @author Chuck Williams
 */
public class HttpFactory {

    /** Name of axis2.xml port parameter for SimpleHTTPServer configuration */
    public static final String PARAMETER_PORT = "port";
    
    /** Name of axis2.xml hostname parameter for SimpleHTTPServer configuration */
    public static final String PARAMETER_HOST_ADDRESS = "hostname";

    /** Name of axis2.xml originServer parameter for SimpleHTTPServer configuration */
    public static final String PARAMETER_ORIGIN_SERVER = "originServer";

    /** Name of axis2.xml requestTimeout parameter for SimpleHTTPServer configuration */
    public static final String PARAMETER_REQUEST_SOCKET_TIMEOUT = "requestTimeout";

    /** Name of axis2.xml requestTcpNoDelay parameter for SimpleHTTPServer configuration */
    public static final String PARAMETER_REQUEST_TCP_NO_DELAY = "requestTcpNoDelay";

    /** Name of axis2.xml requestCoreThreadPoolSize parameter for SimpleHTTPServer configuration */
    public static final String PARAMETER_REQUEST_CORE_THREAD_POOL_SIZE = "requestCoreThreadPoolSize";

    /** Name of axis2.xml requestMaxThreadPoolSize parameter for SimpleHTTPServer configuration */
    public static final String PARAMETER_REQUEST_MAX_THREAD_POOL_SIZE = "requestMaxThreadPoolSize";

    /** Name of axis2.xml threadKeepAliveTime parameter for SimpleHTTPServer configuration */
    public static final String PARAMETER_THREAD_KEEP_ALIVE_TIME = "threadKeepAliveTime";

    /** Name of axis2.xml threadKeepAliveTimeUnit parameter for SimpleHTTPServer configuration */
    public static final String PARAMETER_THREAD_KEEP_ALIVE_TIME_UNIT = "threadKeepAliveTimeUnit";
    
    private ConfigurationContext configurationContext;
    private TransportInDescription httpConfiguration;
    private int port;
    private String hostAddress;
    private String originServer;
    private int requestSocketTimeout;
    private boolean requestTcpNoDelay;
    private int requestCoreThreadPoolSize;
    private int requestMaxThreadPoolSize;
    private long threadKeepAliveTime;
    private TimeUnit threadKeepAliveTimeUnit;
    
    private WorkerFactory requestWorkerFactory = null;
    
    private static final QName HTTP_NAME = new QName(Constants.TRANSPORT_HTTP);
    
    /** Create and configure a new HttpFactory */
    public HttpFactory(ConfigurationContext configurationContext) throws AxisFault {
        this.configurationContext = configurationContext;
        httpConfiguration = configurationContext.getAxisConfiguration().getTransportIn(HTTP_NAME);
        port = getIntParam(PARAMETER_PORT, 6060);
        hostAddress = getStringParam(PARAMETER_HOST_ADDRESS, null);
        originServer = getStringParam(PARAMETER_ORIGIN_SERVER, "Simple-Server/1.1");
        requestSocketTimeout = getIntParam(PARAMETER_REQUEST_SOCKET_TIMEOUT, 20000);
        requestTcpNoDelay = getBooleanParam(PARAMETER_REQUEST_TCP_NO_DELAY, true);
        requestCoreThreadPoolSize = getIntParam(PARAMETER_REQUEST_CORE_THREAD_POOL_SIZE, 25);
        requestMaxThreadPoolSize = getIntParam(PARAMETER_REQUEST_MAX_THREAD_POOL_SIZE, 150);
        threadKeepAliveTime = getLongParam(PARAMETER_THREAD_KEEP_ALIVE_TIME, 180L);
        threadKeepAliveTimeUnit = getTimeUnitParam(PARAMETER_THREAD_KEEP_ALIVE_TIME_UNIT, TimeUnit.SECONDS);
    }
    
    /** Create and configure a new HttpFactory */
    public HttpFactory(ConfigurationContext configurationContext, int port) throws AxisFault {
        this(configurationContext);
        this.port = port;
    }
    
    /** Create and configure a new HttpFactory */
    public HttpFactory(ConfigurationContext configurationContext, int port, WorkerFactory requestWorkerFactory) throws AxisFault {
        this(configurationContext, port);
        this.requestWorkerFactory = requestWorkerFactory;
    }

    private int getIntParam(String name, int def) {
        String config = getStringParam(name, null);
        if (config!=null)
            return Integer.parseInt(config);
        else 
            return def;
    }
    
    private long getLongParam(String name, long def) {
        String config = getStringParam(name, null);
        if (config!=null)
            return Long.parseLong(config);
        else 
            return def;
    }
    
    private boolean getBooleanParam(String name, boolean def) throws AxisFault {
        String config = getStringParam(name, null);
        if (config!=null) {
            if (config.equals("yes") || config.equals("true"))
                return true;
            else if (config.equals("no") || config.equals("false"))
                return false;
            else throw new AxisFault("Boolean value must be yes, true, no or false for parameter " + name + ":  " + config);
        }
        return def;
    }
    
    private TimeUnit getTimeUnitParam(String name, TimeUnit def) throws AxisFault {
        String config = getStringParam(name, null);
        if (config!=null)
            try {
                return (TimeUnit) TimeUnit.class.getField(config).get(null);
            } catch (Exception e) {
                throw new AxisFault(e);
            }
        return def;
    }
        
    private String getStringParam(String name, String def) {
        Parameter param = httpConfiguration.getParameter(name);
        if (param!=null) {
//            assert param.getParameterType() == Parameter.TEXT_PARAMETER;
            String config = (String) param.getValue();
            if (config!=null)
                return config;
        }
        return def;
    }
    
    /** Return the configured listener manager or create and configure one with configurationContext */
    public ListenerManager getListenerManager() {
        ListenerManager lm = configurationContext.getListenerManager();
        if (lm==null) {
            lm = new ListenerManager();
            lm.init(configurationContext);
        }
        return lm;
    }
    
    /** Create the executor used to launch the single requestConnectionListener */
    public ExecutorService newListenerExecutor(int port) {
        return new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue(),
                new DefaultThreadFactory(new ThreadGroup("Listener thread group"), "HttpListener-" + this.port));
    }
    
    /** Create the listener for request connections */
    public IOProcessor newRequestConnectionListener(HttpConnectionFactory factory, HttpConnectionManager manager, int port) throws IOException {
        return new DefaultConnectionListener(port, factory, manager);
    }
    
    /** Create a request connection */
    public HttpConnectionFactory newRequestConnectionFactory(HttpParams params) {
        return new DefaultHttpConnectionFactory(params);
    }
    
    /** Create and set the parameters applied to incoming request connections */
    public HttpParams newRequestConnectionParams() {
        HttpParams params = new DefaultHttpParams(); 
        params
            .setIntParameter(HttpConnectionParams.SO_TIMEOUT, requestSocketTimeout)
            .setBooleanParameter(HttpConnectionParams.TCP_NODELAY, requestTcpNoDelay) 
            .setIntParameter(HttpConnectionParams.MAX_LINE_LENGTH, 4000)
            .setIntParameter(HttpConnectionParams.MAX_HEADER_COUNT, 500)
            .setParameter(HttpProtocolParams.ORIGIN_SERVER, originServer);
        return params;
    }
    
    /** Create the connection manager used to launch request threads */
    public HttpConnectionManager newRequestConnectionManager(ExecutorService requestExecutor, WorkerFactory workerFactory, HttpParams params) {
        return new DefaultHttpConnectionManager(configurationContext, requestExecutor, workerFactory, params);
    }
    
    /** Create the executor use the manage request processing threads */
    public ExecutorService newRequestExecutor(int port) {
        return new ThreadPoolExecutor(requestCoreThreadPoolSize, requestMaxThreadPoolSize, threadKeepAliveTime, threadKeepAliveTimeUnit,
                                      newRequestBlockingQueue(),
                                      new DefaultThreadFactory(new ThreadGroup("Connection thread group"), "HttpConnection-" + port));
    }
    
    /** Create the queue used to hold incoming requests when requestCoreThreadPoolSize threads are busy.
     * Default is an unbounded queue.
     */
    public BlockingQueue newRequestBlockingQueue() {
        return new LinkedBlockingQueue();
    }
    
    /** Create the factory for request workers */
    public WorkerFactory newRequestWorkerFactory() {
        if (requestWorkerFactory!=null)
            return requestWorkerFactory;
        else
            return new HTTPWorkerFactory();
    }

    /** Create a request service processor to populate the response */
    public HttpServiceProcessor newRequestServiceProcessor(
            final HttpServerConnection connection, 
            final SessionManager sessionManager, 
            final Worker worker, 
            final IOProcessorCallback callback) {
        return new DefaultHttpServiceProcessor(connection, configurationContext, sessionManager, worker, callback);
    }
    
    // *****
    // Getters and Setters
    // *****

    /** Getter for configurationContext */
    public ConfigurationContext getConfigurationContext() {
        return configurationContext;
    }

    /** Getter for httpConfiguration */
    public TransportInDescription getHttpConfiguration() {
        return httpConfiguration;
    }

    /** Getter for port
      * return the port on which to listen for http connections (default = 6060)
     */
    public int getPort() {
        return port;
    }

    /** Setter for port */
    public void setPort(int port) {
        this.port = port;
    }

    /** Getter for hostAddress
     * @return the host address (or name) to be use in reply-to endpoint references, or null if not specified (default = null)
     */
    public String getHostAddress() {
        return hostAddress;
    }

    /** Setter for hostAddress */
    public void setHostAddress(String hostAddress) {
        this.hostAddress = hostAddress;
    }

    /** Getter for originServer
     * @return the Server header string for outgoing messages (default "Simple-Server/1.1")
     */
    public String getOriginServer() {
        return originServer;
    }

    /** Setter for originServer */
    public void setOriginServer(String originServer) {
        this.originServer = originServer;
    }

    /** Getter for requestSocketTimeout
     * @return the maximum time in millis to wait for data on a request socket (default 20000)
     */
    public int getRequestSocketTimeout() {
        return requestSocketTimeout;
    }

    /** Setter for requestSocketTimeout */
    public void setRequestSocketTimeout(int requestSocketTimeout) {
        this.requestSocketTimeout = requestSocketTimeout;
    }

    /** Getter for requestTcpNoDelay
     * return false iff Nagle's algorithm should be used to conserve bandwidth by minimizing segments
     *              at the cost of latency and performance (default true, i.e. maximize performance at
     *              the cost of bandwidth)
     */
    public boolean getRequestTcpNoDelay() {
        return requestTcpNoDelay;
    }

    /** Setter for requestTcpNoDelay */
    public void setRequestTcpNoDelay(boolean requestTcpNoDelay) {
        this.requestTcpNoDelay = requestTcpNoDelay;
    }

    /** Getter for RequestCoreThreadPoolSize
     * @return the size of the thread pool use to process requests assuming there is adequate queue space (default 25)
     */
    public int getRequestCoreThreadPoolSize() {
        return requestCoreThreadPoolSize;
    }

    /** Setter for RequestCoreThreadPoolSize */
    public void setRequestCoreThreadPoolSize(int requestCoreThreadPoolSize) {
        this.requestCoreThreadPoolSize = requestCoreThreadPoolSize;
    }

    /** Getter for requestMaxThreadPoolSize
     * @return the maximum size of the thread pool used to process requests if the queue fills up (default 150).
     *         Since the default queue is unbounded this parameter is meaningless unless you override newRequestBlockingQueue()
     */
    public int getRequestMaxThreadPoolSize() {
        return requestMaxThreadPoolSize;
    }

    /** Setter for requestMaxThreadPoolSize */
    public void setRequestMaxThreadPoolSize(int requestMaxThreadPoolSize) {
        this.requestMaxThreadPoolSize = requestMaxThreadPoolSize;
    }

    /** Getter for threadKeepAliveTime
     * @return how long a request processing thread in excess of the core pool size will be kept alive it if is inactive
     *         (default with threadKeepAliveTimeUnit to 180 seconds)
     */
    public long getThreadKeepAliveTime() {
        return threadKeepAliveTime;
    }

    /** Setter for threadKeepAliveTime */
    public void setThreadKeepAliveTime(long threadKeepAliveTime) {
        this.threadKeepAliveTime = threadKeepAliveTime;
    }

    /** Getter for threadKeepAliveTimeUnit
     * return the time unit for threadKeepAliveTime (default SECONDS)
     */
    public TimeUnit getThreadKeepAliveTimeUnit() {
        return threadKeepAliveTimeUnit;
    }

    /** Setter for threadKeepAliveTimeUnit */
    public void setThreadKeepAliveTimeUnit(TimeUnit threadKeepAliveTimeUnit) {
        this.threadKeepAliveTimeUnit = threadKeepAliveTimeUnit;
    }

}
