package onefcClient;


import java.util.Hashtable;
import java.net.URL;
import java.net.URLConnection;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.io.IOException;

import com.ibm.wbi.Editor;
import com.ibm.wbi.RequestEvent;
import com.ibm.wbi.RequestRejectedException;
import com.ibm.wbi.protocol.http.DocumentInfo;

import scone.netobjects.Access;
import scone.netobjects.AccessCache;
import scone.netobjects.AccessEvent;
import scone.netobjects.NetNode;
import scone.netobjects.NetNodeCache;

import com.ibm.wbi.Editor;
import com.ibm.wbi.MegInputStream;
import com.ibm.wbi.MegAbortEvent;
import com.ibm.wbi.RequestEvent;
import com.ibm.wbi.ServiceResult;
import com.ibm.wbi.RequestRejectedException;
import com.ibm.wbi.protocol.http.DocumentInfo;
import com.ibm.wbi.protocol.http.FetchUrl;
import com.ibm.wbi.protocol.http.HttpRequest;
import com.ibm.wbi.protocol.http.HttpRequestEditor;
import com.ibm.wbi.protocol.http.HttpRequestHeader;
import com.ibm.wbi.protocol.http.HttpResponseHeader;

/**
 * Adds onLoad-event to the BODY-Tag to remove popups if page is out of focus.<P>
 *
 * <code>onLoad</code> is called when page was loaded.<BR>
 *
 * @author Harald Weinreich
 */
public class OnefcRequestEditor extends HttpRequestEditor  {

    private Plugin _plugin;
    public static final String COPYRIGHT = "(C) Harald Weinreich & Toby Baier";
    private DocumentInfo documentInfo;
    private HttpRequestHeader  request;
    private String host 	= "";
    private String protocol = "";
    private String port 	= "";
    private RequestEvent requestEvent = null;
    
    /**
	 * Constructor with Plugin as parameter
	 */
	public OnefcRequestEditor(Plugin plugin) {
        _plugin = plugin;
    }
	
	
    public void handleRequest(RequestEvent e) throws RequestRejectedException {

    	requestEvent = e;
        documentInfo = (DocumentInfo) e.getRequestInfo(); // get RequestInfo
        request = documentInfo.getHttpRequestHeader();  // Get the request header

        // host = request.get("Referer");           // Get Refer(r)er
        host 	 = request.getServer();
        protocol = request.getProtocol();
        port  	 = request.getPort();
        Hashtable onefcServers = _plugin.getOnefcServers(); // get Already known servers... Do what you like with them...

        // if unknown:
        	String onefcReponse = testServer();
        	System.out.println("Rückgabe des Servers: "+onefcReponse);
        	// request.set("onefC-session-negotiation","getSessionServiceAddress");

        // else
        	// Get session ID from "onefcServers"
        	request.set("onefC-session-ID","XYZ");
        	
        // fertig!
        throw new RequestRejectedException();
    }

    /**
     * Issue a http "head" request to the server
     * Return the value of onefC-session-ID or onefC-session-negotiation
     **/
    private String testServer() {
    	String result = "";
	   	String urlString = protocol + "://" + host;
	    if (port!=null && !port.equals("") && !port.equals("80")) urlString += ":" + port;
	    urlString += "/";
	    urlString += _plugin.getTestAddress(); // Test address at server, where to send the head request.
		try {
	    	URL url = new URL(urlString);
	    	System.out.println();
	    	System.out.println( "Request:"+url );
	    	HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
	    	urlConnection.setDoOutput(true);
	    	urlConnection.setDoInput(true);
	    	urlConnection.setUseCaches(false);
    		//urlConnection.setDefaultUseCaches(false);
	    	urlConnection.setRequestProperty("onefC-session-negotiation","getSessionServiceAddress");
	    	urlConnection.setRequestMethod("HEAD");
	    	urlConnection.connect();
    		//     show first few header fields...
            for (int x=0; x<2 || urlConnection.getHeaderField(x)!=null; x++) {
    			String field = urlConnection.getHeaderField(x);
    			String key = urlConnection.getHeaderFieldKey(x);
    			if (key!=null) {
    				if (key.equals("onefC-session-ID") || key.equals("onefC-session-negotiation")) { result = field; }
	    			System.out.println( "Response: "+key + ": "+field);
    			} else { 
	    			System.out.println( "Response: "+field);
    			}
    		}
	    } 
	    catch (MalformedURLException e) { System.err.println("Malformed URL!"); } 
	    catch (ProtocolException e)		{ System.err.println("Wrong Protocol!"); } 
		catch (IOException e)           { System.err.println("IO Error!"); }
		catch (Exception e)           { System.err.println("Other fucking Error!"); }
	   	return result;
    }

    
    /**
     * Issue a head request to the server - doesn't work!
     **/
    private String testServerPerWBI_GehtNicht() {
    	String response = "";
    	String url = protocol + "://" + host;
    	if (port!=null && !port.equals("") && !port.equals("80")) url += ":" + port;
    	url += "/";
    	// generate a HEAD request for the root document of the server
    	String requestString ="";
    	requestString += "HEAD " + url + " HTTP/1.0\r\n";
    	requestString += "onefC-session-negotiation: getSessionServiceAddress\r\n";
    	requestString += "\r\n";
    	HttpRequest request = new HttpRequest(requestString);
    	DocumentInfo di = null;
    	try {
    		int maxDelay = 5000; // max 5000ms
    		ServiceResult sr = FetchUrl.fetch( requestEvent, request); //, (int) (1.25 * maxDelay) );
        // 	when we can read from the stream, we got a response.
    		di =  (DocumentInfo)sr.getRequestInfo((long)maxDelay);
    		if (di != null) {
    			HttpResponseHeader res = documentInfo.getHttpResponseHeader();  // Get the response header
    			HttpRequestHeader req = documentInfo.getHttpRequestHeader();  // Get the response header
    			System.out.println("XXX:"+req.get("host"));
    			System.out.println("XXX:"+res);
    			System.out.println("XXX:"+res.get("Server"));
    			System.out.println("XXX:"+res.get("Location"));
    			System.out.println("XXX:"+res.get("onefC-session-negotiation"));
    		} else {	
    			// di.getTransaction().abort(new MegAbortEvent(this, "Head Request Timeout"));
    		}
    	} catch (java.io.IOException e) {
    		// if (di!=null) is.close();
    		return response;
    	} catch (Exception e) {
    		System.out.println("Unexpected exception: " + e);
    		e.printStackTrace();
    		return response;
    	}
		return response;
    }

    
    
}
