// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gitiles;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.gitiles.TestGitilesUrls.URLS;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.base.Function;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Maps;

import org.eclipse.jgit.http.server.ServletUtils;
import org.eclipse.jgit.internal.storage.dfs.DfsRepository;

import java.io.BufferedReader;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.Principal;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/** Simple fake implementation of {@link HttpServletRequest}. */
public class FakeHttpServletRequest implements HttpServletRequest {
  public static final String SERVLET_PATH = "/b";

  public static FakeHttpServletRequest newRequest() {
    return new FakeHttpServletRequest(
        URLS.getHostName(null),
        80,
        "",
        SERVLET_PATH);
  }

  public static FakeHttpServletRequest newRequest(DfsRepository repo) {
    FakeHttpServletRequest req = newRequest();
    req.setAttribute(ServletUtils.ATTRIBUTE_REPOSITORY, repo);
    return req;
  }

  private final Map<String, Object> attributes;
  private final ListMultimap<String, String> headers;

  private ListMultimap<String, String> parameters;
  private String hostName;
  private int port;
  private String method;
  private String contextPath;
  private String servletPath;
  private String path;

  private FakeHttpServletRequest(String hostName, int port, String contextPath,
      String servletPath) {
    this.hostName = checkNotNull(hostName, "hostName");
    checkArgument(port > 0);
    this.port = port;
    this.method = "GET";
    this.contextPath = checkNotNull(contextPath, "contextPath");
    this.servletPath = checkNotNull(servletPath, "servletPath");
    attributes = Maps.newConcurrentMap();
    parameters = LinkedListMultimap.create();
    headers = LinkedListMultimap.create();
  }

  @Override
  public Object getAttribute(String name) {
    return attributes.get(name);
  }

  @Override
  public Enumeration<String> getAttributeNames() {
    return Collections.enumeration(attributes.keySet());
  }

  @Override
  public String getCharacterEncoding() {
    return UTF_8.name();
  }

  @Override
  public int getContentLength() {
    return -1;
  }

  @Override
  public String getContentType() {
    return null;
  }

  @Override
  public ServletInputStream getInputStream() {
    throw new UnsupportedOperationException();
  }

  @Override
  public String getLocalAddr() {
    return "1.2.3.4";
  }

  @Override
  public String getLocalName() {
    return hostName;
  }

  @Override
  public int getLocalPort() {
    return port;
  }

  @Override
  public Locale getLocale() {
    return Locale.US;
  }

  @Override
  public Enumeration<Locale> getLocales() {
    return Collections.enumeration(Collections.singleton(Locale.US));
  }

  @Override
  public String getParameter(String name) {
    return Iterables.getFirst(parameters.get(name), null);
  }

  private static final Function<Collection<String>, String[]> STRING_COLLECTION_TO_ARRAY =
      new Function<Collection<String>, String[]>() {
        @Override
        public String[] apply(Collection<String> values) {
          return values.toArray(new String[0]);
        }
      };

  @Override
  public Map<String, String[]> getParameterMap() {
    return Collections.unmodifiableMap(
        Maps.transformValues(parameters.asMap(), STRING_COLLECTION_TO_ARRAY));
  }

  @Override
  public Enumeration<String> getParameterNames() {
    return Collections.enumeration(parameters.keySet());
  }

  @Override
  public String[] getParameterValues(String name) {
    return STRING_COLLECTION_TO_ARRAY.apply(parameters.get(name));
  }

  public void setQueryString(String qs) {
    ListMultimap<String, String> params = LinkedListMultimap.create();
    for (String entry : Splitter.on('&').split(qs)) {
      List<String> kv = Splitter.on('=').limit(2).splitToList(entry);
      try {
        params.put(URLDecoder.decode(kv.get(0), UTF_8.name()),
            kv.size() == 2 ? URLDecoder.decode(kv.get(1), UTF_8.name()) : "");
      } catch (UnsupportedEncodingException e) {
        throw new IllegalArgumentException(e);
      }
    }
    parameters = params;
  }

  @Override
  public String getProtocol() {
    return "HTTP/1.1";
  }

  @Override
  public BufferedReader getReader() {
    throw new UnsupportedOperationException();
  }

  @Override
  @Deprecated
  public String getRealPath(String path) {
    throw new UnsupportedOperationException();
  }

  @Override
  public String getRemoteAddr() {
    return "5.6.7.8";
  }

  @Override
  public String getRemoteHost() {
    return "remotehost";
  }

  @Override
  public int getRemotePort() {
    return 1234;
  }

  @Override
  public RequestDispatcher getRequestDispatcher(String path) {
    throw new UnsupportedOperationException();
  }

  @Override
  public String getScheme() {
    return port == 443 ? "https" : "http";
  }

  @Override
  public String getServerName() {
    return hostName;
  }

  @Override
  public int getServerPort() {
    return port;
  }

  @Override
  public boolean isSecure() {
    return port == 443;
  }

  @Override
  public void removeAttribute(String name) {
    attributes.remove(name);
  }

  @Override
  public void setAttribute(String name, Object value) {
    attributes.put(name, value);
  }

  @Override
  public void setCharacterEncoding(String env) throws UnsupportedOperationException {
    throw new UnsupportedOperationException();
  }

  @Override
  public String getAuthType() {
    return null;
  }

  @Override
  public String getContextPath() {
    return contextPath;
  }

  @Override
  public Cookie[] getCookies() {
    return new Cookie[0];
  }

  @Override
  public long getDateHeader(String name) {
    throw new UnsupportedOperationException();
  }

  @Override
  public String getHeader(String name) {
    return Iterables.getFirst(headers.get(name), null);
  }

  @Override
  public Enumeration<String> getHeaderNames() {
    return Collections.enumeration(headers.keySet());
  }

  @Override
  public Enumeration<String> getHeaders(String name) {
    return Collections.enumeration(headers.get(name));
  }

  @Override
  public int getIntHeader(String name) {
    return Integer.parseInt(getHeader(name));
  }

  @Override
  public String getMethod() {
    return method;
  }

  public void setMethod(String m) {
    method = m;
  }

  @Override
  public String getPathInfo() {
    return path;
  }

  public void setPathInfo(String path) {
    this.path = checkNotNull(path);
  }

  @Override
  public String getPathTranslated() {
    return path;
  }

  @Override
  public String getQueryString() {
    return GitilesView.paramsToString(parameters);
  }

  @Override
  public String getRemoteUser() {
    return null;
  }

  @Override
  public String getRequestURI() {
    String uri = contextPath + servletPath + path;
    if (!parameters.isEmpty()) {
      uri += "?" + GitilesView.paramsToString(parameters);
    }
    return uri;
  }

  @Override
  public StringBuffer getRequestURL() {
    return null;
  }

  @Override
  public String getRequestedSessionId() {
    return null;
  }

  @Override
  public String getServletPath() {
    return servletPath;
  }

  @Override
  public HttpSession getSession() {
    throw new UnsupportedOperationException();
  }

  @Override
  public HttpSession getSession(boolean create) {
    throw new UnsupportedOperationException();
  }

  @Override
  public Principal getUserPrincipal() {
    throw new UnsupportedOperationException();
  }

  @Override
  public boolean isRequestedSessionIdFromCookie() {
    throw new UnsupportedOperationException();
  }

  @Override
  public boolean isRequestedSessionIdFromURL() {
    throw new UnsupportedOperationException();
  }

  @Override
  @Deprecated
  public boolean isRequestedSessionIdFromUrl() {
    throw new UnsupportedOperationException();
  }

  @Override
  public boolean isRequestedSessionIdValid() {
    throw new UnsupportedOperationException();
  }

  @Override
  public boolean isUserInRole(String role) {
    throw new UnsupportedOperationException();
  }
}
