package org.chenyang.http.impl;

import org.chenyang.http.HttpRequest;
import org.chenyang.http.HttpRequestFactory;
import org.chenyang.http.MethodNotSupportedException;
import org.chenyang.http.RequestLine;
import org.chenyang.http.annotation.Contract;
import org.chenyang.http.annotation.ThreadingBehavior;
import org.chenyang.http.message.BasicHttpEntityEnclosingRequest;
import org.chenyang.http.message.BasicHttpRequest;
import org.chenyang.http.util.Args;

@Contract(
   threading = ThreadingBehavior.IMMUTABLE
)
public class DefaultHttpRequestFactory implements HttpRequestFactory {
   public static final DefaultHttpRequestFactory INSTANCE = new DefaultHttpRequestFactory();
   private static final String[] RFC2616_COMMON_METHODS = new String[]{"GET"};
   private static final String[] RFC2616_ENTITY_ENC_METHODS = new String[]{"POST", "PUT"};
   private static final String[] RFC2616_SPECIAL_METHODS = new String[]{"HEAD", "OPTIONS", "DELETE", "TRACE", "CONNECT"};
   private static final String[] RFC5789_ENTITY_ENC_METHODS = new String[]{"PATCH"};

   private static boolean isOneOf(String[] methods, String method) {
      for(String method2 : methods) {
         if (method2.equalsIgnoreCase(method)) {
            return true;
         }
      }

      return false;
   }

   public HttpRequest newHttpRequest(RequestLine requestline) throws MethodNotSupportedException {
      Args.notNull(requestline, "Request line");
      String method = requestline.getMethod();
      if (isOneOf(RFC2616_COMMON_METHODS, method)) {
         return new BasicHttpRequest(requestline);
      } else if (isOneOf(RFC2616_ENTITY_ENC_METHODS, method)) {
         return new BasicHttpEntityEnclosingRequest(requestline);
      } else if (isOneOf(RFC2616_SPECIAL_METHODS, method)) {
         return new BasicHttpRequest(requestline);
      } else if (isOneOf(RFC5789_ENTITY_ENC_METHODS, method)) {
         return new BasicHttpEntityEnclosingRequest(requestline);
      } else {
         throw new MethodNotSupportedException(method + " method not supported");
      }
   }

   public HttpRequest newHttpRequest(String method, String uri) throws MethodNotSupportedException {
      if (isOneOf(RFC2616_COMMON_METHODS, method)) {
         return new BasicHttpRequest(method, uri);
      } else if (isOneOf(RFC2616_ENTITY_ENC_METHODS, method)) {
         return new BasicHttpEntityEnclosingRequest(method, uri);
      } else if (isOneOf(RFC2616_SPECIAL_METHODS, method)) {
         return new BasicHttpRequest(method, uri);
      } else if (isOneOf(RFC5789_ENTITY_ENC_METHODS, method)) {
         return new BasicHttpEntityEnclosingRequest(method, uri);
      } else {
         throw new MethodNotSupportedException(method + " method not supported");
      }
   }
}
