package com.wizzardo.http;

import com.wizzardo.epoll.SslConfig;
import com.wizzardo.epoll.readable.ReadableByteBuffer;
import com.wizzardo.http.mapping.UrlMapping;
import com.wizzardo.http.request.Header;
import com.wizzardo.http.request.Request;
import com.wizzardo.http.response.Response;
import com.wizzardo.http.response.Status;

import java.io.IOException;

/**
 * Created by wizzardo on 18.02.15.
 */
public class HttpServer<T extends HttpConnection> extends AbstractHttpServer<T> {
    private ReadableByteBuffer staticResponse = new Response()
            .appendHeader(Header.KEY_CONNECTION, Header.VALUE_KEEP_ALIVE)
            .appendHeader(Header.KEY_CONTENT_TYPE, Header.VALUE_HTML_UTF8)
            .setBody("It's alive!".getBytes())
            .buildStaticResponse();

    private byte[] serverName = "Server: wizzardo-http/0.1\r\n".getBytes();
    protected FiltersMapping filtersMapping;
    protected UrlMapping<Handler> urlMapping;
    protected ServerDate serverDate = new ServerDate();

    public HttpServer() {
        init();
    }

    public HttpServer(int port) {
        this(null, port);
    }

    public HttpServer(String host, int port) {
        this(host, port, null, 0);
    }

    public HttpServer(String host, int port, String context) {
        this(host, port, context, 0);
    }

    public HttpServer(String host, int port, int workersCount) {
        this(host, port, null, workersCount);
    }

    public HttpServer(String host, int port, String context, int workersCount) {
        this(host, port, context, workersCount, null);
    }

    public HttpServer(String host, int port, String context, int workersCount, SslConfig sslConfig) {
        super(host, port, workersCount);
        this.context = context;
        if (sslConfig != null)
            loadCertificates(sslConfig);

        init();
    }

    protected UrlMapping<Handler> createUrlMapping() {
        return new UrlMapping<>();
    }

    @Override
    public synchronized void start() {
        onStart();
        started = true;
        super.start();
    }

    protected void onStart() {
        urlMapping.getTemplatesHolder()
                .setHost(getHost())
                .setPort(getPort())
                .setContext(context)
                .setIsHttps(isSecured());

        urlMapping.setContext(context);
        filtersMapping.setContext(context);
    }

    protected void init() {
        urlMapping = createUrlMapping();
        filtersMapping = new FiltersMapping();
        urlMapping.append("/", (request, response) -> response.setStaticResponse(staticResponse.copy()));
    }

    public FiltersMapping getFiltersMapping() {
        return filtersMapping;
    }

    public UrlMapping<Handler> getUrlMapping() {
        return urlMapping;
    }

    @Override
    protected void handle(T connection) throws Exception {
        Request request = connection.getRequest();
        Response response = connection.getResponse();

        response.appendHeader(serverDate.getDateAsBytes());
        response.appendHeader(serverName);

//            System.out.println(request.method() + " " + request.path() + " " + request.protocol());
//            System.out.println(request.headers());

        if (!filtersMapping.before(request, response))
            return;

        response = handle(request, response);

        filtersMapping.after(request, response);
    }

    protected Response handle(Request request, Response response) throws IOException {
        Handler handler = urlMapping.get(request);
        if (handler != null)
            response = handler.handle(request, response);
        else
            response.setStatus(Status._404).setBody(request.path() + " not found");
        return response;
    }
}

@@ -997,24 +997,61 @@
 erverDate();
+%0A    protected boolean debug = false;
 %0A%0A    public
@@ -1974,32 +1974,135 @@
 ing%3C%3E();%0A    %7D%0A%0A
+    public HttpServer%3CT%3E debug(boolean enabled) %7B%0A        debug = enabled;%0A        return this;%0A    %7D%0A%0A
     @Override%0A  
@@ -3206,18 +3206,82 @@
 Name);%0A%0A
-//
+        if (debug) %7B%0A            System.out.println(%22request: %22);%0A
         
@@ -3376,10 +3376,58 @@
 ));%0A
-//
+            System.out.println(request.params());%0A
     
@@ -3468,24 +3468,34 @@
 .headers());
+%0A        %7D
 %0A%0A        if
@@ -3652,24 +3652,143 @@
  response);%0A
+        if (debug) %7B%0A            System.out.println(%22response: %22);%0A            System.out.println(response);%0A        %7D%0A
     %7D%0A%0A    p

add debug field