package jp;

import com.mortbay.Base.*;
import com.mortbay.Util.*;
import com.mortbay.HTTP.*;
import com.mortbay.HTTP.Handler.*;
import com.mortbay.HTTP.Configure.*;
import java.io.*;
import java.net.*;
import javax.servlet.*;
import java.util.*;

import Tools.Options;

/**
 * A Jetty configuration class that sets up a proxy with an {@link SfUserAgent}
 * installed to process all outgoing requests.
 */
public class ProxyConfig extends com.mortbay.HTTP.Configure.BaseConfiguration
{
	/**
	 * Create a configuration bound at the given host address and port.
	 */
    public ProxyConfig(Options opts)
         throws IOException
    {
        InetAddrPort addrPort= null;
		addrPort = new InetAddrPort(
			InetAddress.getByName(opts.get("address")),
			opts.getInt("port"));

        // Listen at a single port on the localhost
        addresses=new InetAddrPort[1];
        addresses[0]=new InetAddrPort(addrPort.getInetAddress(),
                                      addrPort.getPort());

        // Create single stack of HttpHandlers at "/"
        HttpHandler[] httpHandlers = new HttpHandler[3];

        httpHandlersMap=new PathMap();
        httpHandlersMap.put("http:",httpHandlers);
        httpHandlersMap.put("ftp:",httpHandlers);
        // httpHandlersMap.put("file:",httpHandlers);
		httpHandlersMap.put("/", httpHandlers);

        // handlers
        int h=0;
        httpHandlers[h++] = new LogHandler(true, true);

		Properties proxyProps = new Properties();
		proxyProps.put("certDir", opts.get("certDir"));
//		httpHandlers[h++] = new ProxyHandler(proxyProps);
//			// this installs a jp.ProxyHandler, the one we want.
        httpHandlers[h++] = new SfUserAgent(proxyProps);

        httpHandlers[h++] = new NotFoundHandler();      
    }

	static class ProxyOptions extends Options {
		public ProxyOptions(String[] args) { super(args); }
		public void defineOptions() {
			programName = "ProxyConfig";
			defineArgument(
				"certDir", true,
				"A directory that holds (will hold) keys and certificates",
				null);
			defineOption(
				"port", "Port number proxy server listens on", "8040");
			defineOption(
				"address", "Address to bind proxy server to", "0.0.0.0");
		}
	};

	/**
	 * Start the SfUserAgent proxy server.
	 */
    public static void main(String args[])
    {
        try{
			Options opts = new ProxyOptions(args);
            
            HttpConfiguration config = new ProxyConfig(opts);
            HttpServer httpServer = new HttpServer(config);

/*
			// Whip together my toy Servlet server
			// It has to be on a different port because the httpHandlerMap
			// architecture doesn't inspect the dest host part of the
			// query, only the path. So unless I want my servlet dir to appear
			// superimposed "over" every other site, I have to map it to
			// a different port. Now that I think about it, I'm not sure
			// how the "http:" matches above actually ever match anything --
			// they're compared to the resourcePath of the incoming request,
			// which begins *after* the protocol://server:port/ part.
			int port2 = addrPort.getPort()+1;
			System.out.println("Servlet server camping out at "+port2);
			HttpConfiguration config2 = new ServletServer(port2, "/", ".");
			HttpServer httpServer2 = new HttpServer(config2);
*/

			// Wait for the server I actually care about to stop
            httpServer.join();
        }
        catch(Exception e){
            Code.warning("Demo Failed",e);
            System.err.println("Usage - java com.mortbay.HTTP.Configure.ProxyConfig [ [host] port ]");
            System.exit(1);
        }
    }
};
