package com.vtence.molecule.examples.middlewares;

import com.vtence.molecule.Application;
import com.vtence.molecule.HttpStatus;
import com.vtence.molecule.Request;
import com.vtence.molecule.Response;
import com.vtence.molecule.middlewares.AbstractMiddleware;
import com.vtence.molecule.middlewares.ApacheCommonLogger;
import com.vtence.molecule.middlewares.DateHeader;
import com.vtence.molecule.middlewares.Failsafe;
import com.vtence.molecule.middlewares.FailureMonitor;
import com.vtence.molecule.middlewares.FilterMap;
import com.vtence.molecule.middlewares.HttpMethodOverride;
import com.vtence.molecule.middlewares.MiddlewareStack;
import com.vtence.molecule.middlewares.ServerHeader;
import com.vtence.molecule.routing.DynamicRoutes;
import com.vtence.molecule.simple.SimpleServer;
import com.vtence.molecule.util.ConsoleErrorReporter;

import java.io.IOException;
import java.util.logging.Logger;

import static com.vtence.molecule.middlewares.Router.draw;
import static java.lang.Integer.parseInt;

public class Middlewares {

    public static void main(String[] args) throws IOException {
        SimpleServer server = new SimpleServer(8080);

        server.run(new MiddlewareStack() {{
            // Add information about the server in the response header
            use(new ServerHeader("MyApp/1.0 molecule/0.2"));
            // Also include date and time of the response
            use(new DateHeader());
            // Log all accesses to the default JDK logger
            use(new ApacheCommonLogger(Logger.getAnonymousLogger()));
            // Eat up all internal server errors and respond with a 500 page
            use(new Failsafe());
            // Print internal server errors to the standard error stream
            use(new FailureMonitor(ConsoleErrorReporter.toStandardError()));
            // Support HTTP method override via the _method request parameter
            use(new HttpMethodOverride());

            FilterMap filters = new FilterMap();
            // All requests to /private halt with 403
            filters.map("/private", new AbstractMiddleware() {
                public void handle(Request request, Response response) throws Exception {
                    response.status(HttpStatus.FORBIDDEN);
                    response.body("This is a restricted area");
                }
            });
            // All requests with /orders prefix go through this filter
            filters.map("/orders", new AbstractMiddleware() {
                public void handle(Request request, Response response) throws Exception {
                    String username = "...";
                    request.attribute("username", username);
                    // Carry on with request processing
                    forward(request, response);
                }
            });
            use(filters);

            // All requests go through the following filter
            use(new AbstractMiddleware() {
                public void handle(Request request, Response response) throws Exception {
                    // The 'before' part
                    response.contentType("text/plain");
                    // Continue processing the request
                    forward(request, response);
                    // The 'after' part
                    System.out.println("User: " + request.attribute("username"));
                }
            });

            run(draw(new DynamicRoutes() {{
                get("/orders/:id").to(new Application() {
                    public void handle(Request request, Response response) throws Exception {
                        response.body("Order #" + parseInt(request.parameter("id")));
                    }
                });

                post("/orders").to(new Application() {
                    public void handle(Request request, Response response) throws Exception {
                        response.body("Submitted order: " + request.body());
                    }
                });

                // Access with either a PUT or a POST with _method=PUT
                put("/orders/:id").to(new Application() {
                    public void handle(Request request, Response response) throws Exception {
                        response.body(String.format("Revised order #%d: %s",
                                parseInt(request.parameter("id")), request.body()));
                    }
                });

                // Access with either a DELETE or a POST with _method=DELETE
                delete("/orders/:id").to(new Application() {
                    public void handle(Request request, Response response) throws Exception {
                        response.body("Cancelled order #" + parseInt(request.parameter("id")));
                    }
                });
            }}));
        }});
    }
}

@@ -310,24 +310,75 @@
 mmonLogger;%0A
+import com.vtence.molecule.middlewares.Compressor;%0A
 import com.v
@@ -1287,41 +1287,18 @@
 out 
-the
+our
  server
- in the response header
 %0A   
@@ -1957,16 +1957,216 @@
 ide());%0A
+            // Compress response content using gzip or deflate when acceptable by the client%0A            use(new Compressor());%0A%0A            // A filter map applies middleware depending on the request
 %0A       
@@ -2533,24 +2533,73 @@
 ted area%22);%0A
+                    // Stop the processing chain%0A
             
@@ -2658,22 +2658,16 @@
 th /
-orders
  prefix 
 go t
@@ -2666,23 +2666,85 @@
 fix 
-go through this
+(i.e. all other requests) go through this dummy%0A            // authentication
  fil
@@ -2773,22 +2773,16 @@
 s.map(%22/
-orders
 %22, new A
@@ -2885,32 +2885,108 @@
 ows Exception %7B%0A
+                    // At this point we would perform proper authentication%0A
                 
@@ -3112,23 +3112,19 @@
 on with 
-request
+the
  process
@@ -3126,16 +3126,22 @@
 ocessing
+ chain
 %0A       
@@ -3261,52 +3261,66 @@
  // 
-All requests go through the following filter
+You can add your own middleware to wrap request processing
 %0A   
@@ -3574,14 +3574,23 @@
 // C
-ontinu
+arry on with th
 e pr
@@ -3598,27 +3598,21 @@
 cessing 
-the request
+chain
 %0A       
@@ -3716,67 +3716,37 @@
     
-System.out.println(%22User: %22 + reque
+response.
 st
-.
 at
-tribute(%22username%22)
+us(HttpStatus.OK
 );%0A 

Improve example on middlewares usage and add the new compressor