package com.tessier.continuity;

import org.apache.catalina.Container;
import org.apache.catalina.HttpRequest;
import org.apache.catalina.HttpResponse;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.Logger;
import org.apache.catalina.Request;
import org.apache.catalina.Response;
import org.apache.catalina.Service;
import org.apache.catalina.net.DefaultServerSocketFactory;
import org.apache.catalina.net.ServerSocketFactory;
import org.apache.catalina.util.LifecycleSupport;
import org.apache.catalina.util.StringManager;
import org.apache.catalina.Connector;

/** 
 * Implementation of a Connectinuity interior connector.
 *
 * @author Alex Leigh <aleigh@tessier.com>
 * @version $Revision: 1.2 $
 */

public final class CatalinaConnector 
  implements Lifecycle, Connector, Runnable {

    /**
     * The <code>Service</code> we are associated with (if any).
     */
    private Service service = null;

    /**
     * The secure connection flag that will be set on all requests received
     * through this connector.
     */
    private boolean secure = false;
 

    /**
     * The redirect port for non-SSL to SSL redirects.
     */
    private int redirectPort = 443;
    
   
    /**
     * The request scheme that will be set on all requests received
     * through this connector.
     */
    private String scheme = "http";

    /**
     * Descriptive information about this Connector implementation.
     */
    private static final String info =
        "com.tessier.continuity.CatalinaConnector/1.0"; 

    /**
     * The Container used for processing requests received by this Connector.
     */
    protected Container container = null;

    /**
     * The lifecycle event support for this component.
     */
    protected LifecycleSupport lifecycle = new LifecycleSupport(this);

 
    /**
     * The "enable DNS lookups" flag for this Connector.
     */
    private boolean enableLookups = false;
 
 
    /**
     * The server socket factory for this component.
     */
    private ServerSocketFactory factory = null;


    public void run() {
      System.out.println("CatalinaConnector: run() called.");
    }

    /**
     * Add a lifecycle event listener to this component.
     *
     * @param listener The listener to add
     */
    public void addLifecycleListener(LifecycleListener listener) {
        lifecycle.addLifecycleListener(listener);
    }

    /**
     * Get the lifecycle listeners associated with this lifecycle. If this
     * Lifecycle has no listeners registered, a zero-length array is returned.
     */
    public LifecycleListener[] findLifecycleListeners() {
        return lifecycle.findLifecycleListeners();
    }

    /**
     * Remove a lifecycle event listener from this component.
     *
     * @param listener The listener to add
     */
    public void removeLifecycleListener(LifecycleListener listener) {
        lifecycle.removeLifecycleListener(listener);
    }

    /**
     * Begin processing requests via this Connector.
     *
     * @exception LifecycleException if a fatal startup error occurs
     */
    public void start() throws LifecycleException {
      // This really does nothing since our requests are going to come
      // directly from Continuity.
    }

    /**
     * Terminate processing requests via this Connector.
     * 
     * @exception LifecycleException if a fatal shutdown error occurs
     */
    public void stop() throws LifecycleException {
    }

    /**
     * Return the Container used for processing requests received by this
     * Connector.
     */
    public Container getContainer() {
        return (container);
    }

    /**
     * Set the Container used for processing requests received by this
     * Connector.
     * 
     * @param container The new Container to use
     */
    public void setContainer(Container container) {
        this.container = container;
    }   

    /**
     * Return the "enable DNS lookups" flag.
     */
    public boolean getEnableLookups() {
        return (this.enableLookups);
    }

     /**
     * Set the "enable DNS lookups" flag.
     *
     * @param enableLookups The new "enable DNS lookups" flag value
     */
    public void setEnableLookups(boolean enableLookups) {
        this.enableLookups = enableLookups;
    }

    /**
     * Return the server socket factory used by this Container.
     */
    public ServerSocketFactory getFactory() {
        if (this.factory == null) {
            synchronized (this) {
                this.factory = new DefaultServerSocketFactory();
            }
        }
        return (this.factory);
    }

    /**
     * Set the server socket factory used by this Container.
     * 
     * @param factory The new server socket factory
     */
    public void setFactory(ServerSocketFactory factory) {
        this.factory = factory;
    }

    /**
     * Return descriptive information about this Connector implementation.
     */
    public String getInfo() {
        return (info);
    }        

    /**
     * Return the port number to which a request should be redirected if
     * it comes in on a non-SSL port and is subject to a security constraint
     * with a transport guarantee that requires SSL.
     */
    public int getRedirectPort() {
       
        return (this.redirectPort);
        
    }

    /**
     * Set the redirect port number.
     *
     * @param redirectPort The redirect port number (non-SSL to SSL)
     */
    public void setRedirectPort(int redirectPort) {
     
        this.redirectPort = redirectPort;
     
    }  

    /**
     * Return the scheme that will be assigned to requests received
     * through this connector.  Default value is "http".
     */
    public String getScheme() {

        return (this.scheme);
        
    }
     
       
    /**
     * Set the scheme that will be assigned to requests received through
     * this connector.
     * 
     * @param scheme The new scheme
     */
    public void setScheme(String scheme) {
    
        this.scheme = scheme;
        
    }

   
    /**
     * Return the secure connection flag that will be assigned to requests
     * received through this connector.  Default value is "false".
     */
    public boolean getSecure() {

        return (this.secure);
        
    }
     
       
    /**
     * Set the secure connection flag that will be assigned to requests 
     * received through this connector.
     * 
     * @param secure The new secure connection flag
     */
    public void setSecure(boolean secure) {
    
        this.secure = secure;
        
    }

    /**
     * Return the <code>Service</code> with which we are associated (if any).
     */
    public Service getService() {
     
        return (this.service);
    
    }
   
       
    /**
     * Set the <code>Service</code> with which we are associated (if any).
     *
     * @param service The service that owns this Engine
     */
    public void setService(Service service) {
     
        this.service = service;
    
    }

    /**
     * Create (or allocate) and return a Request object suitable for
     * specifying the contents of a Request to the responsible Container.
     */
    public Request createRequest() {
      ContHttpRequest req = new ContHttpRequest();
    
      req.setConnector(this);
      return req;
    }
       
    /**
     * Create (or allocate) and return a Response object suitable for
     * receiving the contents of a Response from the responsible Container.
     */
    public Response createResponse() {
      return null;       
    }

    public void initialize()
    throws LifecycleException {
      System.out.println("CatalinaConnector: initialize() called.");
    }
}

