package com.wizzardo.http;

import com.wizzardo.http.request.Request;
import com.wizzardo.http.response.Response;
import com.wizzardo.http.response.Status;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * Created by wizzardo on 16.04.15.
 */
public class RestHandler implements Handler {

    protected Handler get;
    protected Handler post;
    protected Handler put;
    protected Handler delete;

    private byte[] allow;

    @Override
    public Response handle(Request request, Response response) throws IOException {
        switch (request.method()) {
            case GET:
                return handle(request, response, get);
            case PUT:
                return handle(request, response, put);
            case POST:
                return handle(request, response, post);
            case DELETE:
                return handle(request, response, delete);
        }
        return response.setStatus(Status._405);
    }

    protected Response handle(Request request, Response response, Handler handler) throws IOException {
        if (handler == null)
            return provideAllowHeader(response).setStatus(Status._405);
        else
            return handler.handle(request, response);
    }

    protected Response provideAllowHeader(Response response) {
        if (allow != null)
            response.appendHeader(allow);
        return response;
    }

    public RestHandler setGetHandler(Handler get) {
        this.get = get;
        generateAllowHeader();
        return this;
    }

    public RestHandler setPostHandler(Handler post) {
        this.post = post;
        generateAllowHeader();
        return this;
    }

    public RestHandler setPutHandler(Handler put) {
        this.put = put;
        generateAllowHeader();
        return this;
    }

    public RestHandler setDeleteHandler(Handler delete) {
        this.delete = delete;
        generateAllowHeader();
        return this;
    }

    public RestHandler get(Handler get) {
        return setGetHandler(get);
    }

    public RestHandler post(Handler post) {
        return setPostHandler(post);
    }

    public RestHandler put(Handler put) {
        return setPutHandler(put);
    }

    public RestHandler delete(Handler delete) {
        return setDeleteHandler(delete);
    }

    private void generateAllowHeader() {
        StringBuilder sb = new StringBuilder("Allow: ");
        boolean comma;

        comma = buildAllowHeaderString(sb, get, "GET", false);
        comma = buildAllowHeaderString(sb, post, "POST", comma);
        comma = buildAllowHeaderString(sb, put, "PUT", comma);
        comma = buildAllowHeaderString(sb, delete, "DELETE", comma);

        if (sb.length() > 7)
            allow = sb.append("\r\n").toString().getBytes(StandardCharsets.UTF_8);
        else
            allow = null;
    }

    private boolean buildAllowHeaderString(StringBuilder sb, Handler handler, String name, boolean comma) {
        if (handler != null) {
            if (comma)
                sb.append(", ");
            else
                comma = true;
            sb.append(name);
        }
        return comma;
    }
}

@@ -428,34 +428,190 @@
 te;%0A
-%0A    private byte%5B%5D allow;
+    protected final Handler options = (request, response) -%3E provideAllowHeader(response);%0A%0A    private byte%5B%5D allow;%0A%0A    public RestHandler() %7B%0A        generateAllowHeader();%0A    %7D
 %0A%0A  
@@ -1054,24 +1054,109 @@
 e, delete);%0A
+            case OPTIONS:%0A                return handle(request, response, options);%0A
         %7D%0A  
@@ -1562,38 +1562,14 @@
     
-if (allow != null)%0A           
+return
  res
@@ -1599,33 +1599,8 @@
 w);%0A
-        return response;%0A
     
@@ -2691,24 +2691,88 @@
 T%22, false);%0A
+        comma = buildAllowHeaderString(sb, get, %22HEAD%22, comma);%0A
         comm
@@ -2956,25 +2956,24 @@
 comma);%0A
-%0A
         
 if (sb.l
@@ -2968,33 +2968,72 @@
     
-if (sb.length() %3E 7)%0A    
+comma = buildAllowHeaderString(sb, options, %22OPTIONS%22, comma);%0A%0A
     
@@ -3111,47 +3111,8 @@
 8);%0A
-        else%0A            allow = null;%0A
     

improve rest-handler