package com.ociweb.oe.greenlightning.api;


import com.ociweb.gl.api.Builder;
import com.ociweb.gl.api.GreenApp;
import com.ociweb.gl.api.GreenRuntime;
import com.ociweb.json.JSONType;
import com.ociweb.json.decode.JSONExtractor;
import com.ociweb.pronghorn.network.HTTPServerConfig;
import com.ociweb.pronghorn.network.config.HTTPHeaderDefaults;
import com.ociweb.pronghorn.util.AppendableProxy;
import com.ociweb.pronghorn.util.Appendables;

public class HTTPServer implements GreenApp
{
		
	private AppendableProxy console;
	private final String host;
	private final int port;
	private final int telemetryPort;
	private final boolean isTLS;
	
	public HTTPServer(String host, int port, Appendable console, int telemetryPort, boolean isTLS) {
		this.host = host;
		this.console = Appendables.proxy(console);
		this.port = port;
		this.telemetryPort = telemetryPort;
		this.isTLS = isTLS;
	}

	public HTTPServer(int port, Appendable console, int telemetryPort, boolean isTLS) {
		this.host = null;
		this.console = Appendables.proxy(console);
		this.port = port;
		this.telemetryPort = telemetryPort;
		this.isTLS = isTLS;
	}
	
    @Override
    public void declareConfiguration(Builder c) {
        
		HTTPServerConfig server = c.useHTTP1xServer(port)
		 .setHost(host)
		 .setTracks(2)
		 .setMaxResponseSize(1<<18);
		
		if (!isTLS) {
			server.useInsecureServer();
		}
		
		if (telemetryPort>0) {
			c.enableTelemetry(telemetryPort);
		}
		
		c.defineRoute(HTTPHeaderDefaults.COOKIE)
				                 .path("/testpageA?arg=#{myarg}")
		
				                ///TODO: urgent fix.. allso add lambda here for validation..
				    //             .path("/testpageA")////TODO: this should be possible  but not working why?
				                 
				                 .defaultInteger("myarg", 111)
				                 .associatedObject("myarg", Field.MYARG)
				                 .routeId(Struct.EMPTY_EXAMPLE);
		
		c.defineRoute().path("/testpageB").routeId(Struct.SMALL_EXAMPLE);
		c.defineRoute(HTTPHeaderDefaults.COOKIE)
				                  .path("/testpageC").routeId(Struct.LARGE_EXAMPLE);
		c.defineRoute().path("/testpageD").routeId(Struct.SPLIT_EXAMPLE);

		c.defineRoute()
		    .parseJSON()
		    	.stringField( "person.name", Field.PERSON_NAME)
		    	.integerField("person.age",  Field.PERSON_AGE)
		    .path("/testJSON")
			.routeId(Struct.JSON_EXAMPLE);
		
		c.defineRoute()
		     .path("/resources/${path}")
		     .routeId(Struct.RESOURCES_EXAMPLE);

		c.defineRoute()
	     	.path("/files/${path}")
	     	.routeId(Struct.FILES_EXAMPLE);

    }
    
    @Override
    public void declareBehavior(GreenRuntime runtime) {

        runtime.registerListener(new RestBehaviorEmptyResponse(runtime, console))
                 .includeRoutesByAssoc(Struct.EMPTY_EXAMPLE);
        
        runtime.registerListener(new RestBehaviorSmallResponse(runtime, console))
        		.includeRoutesByAssoc(Struct.SMALL_EXAMPLE);
        
        runtime.registerListener(new RestBehaviorLargeResponse(runtime, console))
        		 .includeRoutesByAssoc(Struct.LARGE_EXAMPLE);
                
        
        int threadsCount = 20;        
		long timeoutNS = 1_000_000_000;
		
	//	runtime.registerBlockingListener(()->new BlockingExample(), Field.CONNECTION_ID, threadsCount, timeoutNS);
        
        
        String topic = "httpData";

        runtime.registerListener(new RestBehaviorHandoff(runtime, topic))
        		 .includeRoutesByAssoc(Struct.SPLIT_EXAMPLE);
		
        runtime.registerListener(new RestBehaviorHandoffResponder(runtime, console))
                 .addSubscription(topic);
  
        runtime.registerListener(new RestBehaviorJsonResponce(runtime, console))
        		  .includeRoutesByAssoc(Struct.JSON_EXAMPLE);
        
    	runtime.addResourceServer("exampleSite")
		         .includeRoutesByAssoc(Struct.RESOURCES_EXAMPLE);

    	runtime.addFileServer("./src/main/resources/exampleSite") 
				 .includeRoutesByAssoc(Struct.FILES_EXAMPLE);
				        
        
        //NOTE .includeAllRoutes() can be used to write a behavior taking all routes

    }
   
}

@@ -1439,548 +1439,9 @@
 %09%09%7D%0A
-%09%09%0A%09%09c.defineRoute(HTTPHeaderDefaults.COOKIE)%0A%09%09%09%09                 .path(%22/testpageA?arg=#%7Bmyarg%7D%22)%0A%09%09%0A%09%09%09%09                ///TODO: urgent fix.. allso add lambda here for validation..%0A%09%09%09%09    //             .path(%22/testpageA%22)////TODO: this should be possible  but not working why?%0A%09%09%09%09                 %0A%09%09%09%09                 .defaultInteger(%22myarg%22, 111)%0A%09%09%09%09                 .associatedObject(%22myarg%22, Field.MYARG)%0A%09%09%09%09                 .routeId(Struct.EMPTY_EXAMPLE);%0A%09%09%0A%09%09c.defineRoute().path(%22/testpageB%22).routeId(Struct.SMALL_EXAMPLE);
 %0A
+
 %09%09c.
@@ -1658,16 +1658,18 @@
 eJSON()%0A
+  
 %09%09    %09.
@@ -1715,16 +1715,16 @@
 N_NAME)%0A
-
 %09%09    %09.
@@ -2012,24 +2012,520 @@
 S_EXAMPLE);%0A
+%09%09%0A%09%09c.defineRoute(HTTPHeaderDefaults.COOKIE)%0A%09%09%09%09                 .path(%22/testpageA?arg=#%7Bmyarg%7D%22)%0A%09%09%0A%09%09%09%09                ///TODO: urgent fix.. allso add lambda here for validation..%0A%09%09%09%09        //         .path(%22/testpageA%22)////TODO: this should be possible  but not working why?%0A%09%09%0A%09%09%09%09                 .refineInteger(%22myarg%22, Field.MYARG, 111)%0A%09%09%09%09                 %0A%09%09%09%09                 .routeId(Struct.EMPTY_EXAMPLE);%0A%09%09%0A%09%09c.defineRoute().path(%22/testpageB%22).routeId(Struct.SMALL_EXAMPLE);%0A%09%09
 %0A    %7D%0A    %0A

refine the test