package co.mewf.minirs.route;

import java.io.IOException;
import java.io.Reader;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import co.mewf.minirs.internal.javax.ws.rs.core.MultivaluedHashMap;
import co.mewf.minirs.internal.javax.ws.rs.core.MultivaluedMap;
import co.mewf.minirs.rs.HttpMethod;

import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.io.CharStreams;

public class RouteRequest {
  private final Splitter PARAM_PAIR_SPLITTER = Splitter.on('&');
  private final Splitter PARAM_VALUE_SPLITTER = Splitter.on('=');

  private final HttpServletRequest req;
  private final MultivaluedMap<String, String> queryStringParams = new MultivaluedHashMap<>();
  private final MultivaluedMap<String, String> formParams = new MultivaluedHashMap<>();

  public RouteRequest(HttpServletRequest req) {
    this.req = req;

    if (HttpMethod.POST.equals(req.getMethod())) {
      try (Reader reader = req.getReader()) {
        String rawFormParams = CharStreams.toString(reader);
        if (!Strings.isNullOrEmpty(rawFormParams)) {
          for (String pair : PARAM_PAIR_SPLITTER.split(rawFormParams)) {
            List<String> keyValue = PARAM_VALUE_SPLITTER.splitToList(pair);
            formParams.add(keyValue.get(0), keyValue.get(1));
          }
        }
      } catch (IOException e) {
        throw Throwables.propagate(e);
      }
    }

    if (!Strings.isNullOrEmpty(req.getQueryString())) {
      for (String pair : PARAM_PAIR_SPLITTER.split(req.getQueryString())) {
        List<String> keyValue = PARAM_VALUE_SPLITTER.splitToList(pair);
        queryStringParams.add(keyValue.get(0), keyValue.get(1));
      }
    }
  }

  public String getPath() {
    return req.getRequestURI().substring(req.getContextPath().length());
  }

  public String getMethod() {
    return req.getMethod();
  }

  public String getFormParam(String name) {
    return formParams.getFirst(name);
  }

  public String getQueryParam(String name) {
    return queryStringParams.getFirst(name);
  }
}
