// Copyright (C) 2012 The Android Open Source Project
//
// 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.gerrit.httpd.restapi;

import static com.google.common.base.Charsets.UTF_8;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.math.RoundingMode.CEILING;
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static javax.servlet.http.HttpServletResponse.SC_CONFLICT;
import static javax.servlet.http.HttpServletResponse.SC_CREATED;
import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static javax.servlet.http.HttpServletResponse.SC_METHOD_NOT_ALLOWED;
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
import static javax.servlet.http.HttpServletResponse.SC_NOT_MODIFIED;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static javax.servlet.http.HttpServletResponse.SC_PRECONDITION_FAILED;

import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.common.io.BaseEncoding;
import com.google.common.math.IntMath;
import com.google.common.net.HttpHeaders;
import com.google.gerrit.audit.AuditService;
import com.google.gerrit.audit.HttpAuditEvent;
import com.google.gerrit.extensions.annotations.CapabilityScope;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.AcceptsCreate;
import com.google.gerrit.extensions.restapi.AcceptsPost;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.CacheControl;
import com.google.gerrit.extensions.restapi.DefaultInput;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
import com.google.gerrit.extensions.restapi.PreconditionFailedException;
import com.google.gerrit.extensions.restapi.RawInput;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestCollection;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.extensions.restapi.RestResource;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.extensions.restapi.TopLevelResource;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.httpd.WebSession;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.OptionUtil;
import com.google.gerrit.server.OutputFormat;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.MalformedJsonException;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.util.Providers;

import org.eclipse.jgit.util.TemporaryBuffer;
import org.eclipse.jgit.util.TemporaryBuffer.Heap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.zip.GZIPOutputStream;

import javax.annotation.Nullable;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RestApiServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;
  private static final Logger log = LoggerFactory
      .getLogger(RestApiServlet.class);

  /** MIME type used for a JSON response body. */
  private static final String JSON_TYPE = "application/json";
  private static final String FORM_TYPE = "application/x-www-form-urlencoded";

  /**
   * Garbage prefix inserted before JSON output to prevent XSSI.
   * <p>
   * This prefix is ")]}'\n" and is designed to prevent a web browser from
   * executing the response body if the resource URI were to be referenced using
   * a &lt;script src="...&gt; HTML tag from another web site. Clients using the
   * HTTP interface will need to always strip the first line of response data to
   * remove this magic header.
   */
  public static final byte[] JSON_MAGIC;

  static {
    JSON_MAGIC = ")]}'\n".getBytes(UTF_8);
  }

  public static class Globals {
    final Provider<CurrentUser> currentUser;
    final Provider<WebSession> webSession;
    final Provider<ParameterParser> paramParser;
    final AuditService auditService;

    @Inject
    Globals(Provider<CurrentUser> currentUser,
        Provider<WebSession> webSession,
        Provider<ParameterParser> paramParser,
        AuditService auditService) {
      this.currentUser = currentUser;
      this.webSession = webSession;
      this.paramParser = paramParser;
      this.auditService = auditService;
    }
  }

  private final Globals globals;
  private final Provider<RestCollection<RestResource, RestResource>> members;

  public RestApiServlet(Globals globals,
      RestCollection<? extends RestResource, ? extends RestResource> members) {
    this(globals, Providers.of(members));
  }

  public RestApiServlet(Globals globals,
      Provider<? extends RestCollection<? extends RestResource, ? extends RestResource>> members) {
    @SuppressWarnings("unchecked")
    Provider<RestCollection<RestResource, RestResource>> n =
        (Provider<RestCollection<RestResource, RestResource>>) checkNotNull((Object) members);
    this.globals = globals;
    this.members = n;
  }

  @Override
  protected final void service(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException {
    long auditStartTs = System.currentTimeMillis();
    res.setHeader("Content-Disposition", "attachment");
    res.setHeader("X-Content-Type-Options", "nosniff");
    int status = SC_OK;
    Object result = null;
    Multimap<String, String> params = LinkedHashMultimap.create();
    Object inputRequestBody = null;

    try {
      checkUserSession(req);

      List<IdString> path = splitPath(req);
      RestCollection<RestResource, RestResource> rc = members.get();
      checkAccessAnnotations(null, rc.getClass());

      RestResource rsrc = TopLevelResource.INSTANCE;
      ViewData viewData = new ViewData(null, null);
      if (path.isEmpty()) {
        if ("GET".equals(req.getMethod())) {
          viewData = new ViewData(null, rc.list());
        } else if (rc instanceof AcceptsPost && "POST".equals(req.getMethod())) {
          @SuppressWarnings("unchecked")
          AcceptsPost<RestResource> ac = (AcceptsPost<RestResource>) rc;
          viewData = new ViewData(null, ac.post(rsrc));
        } else {
          throw new MethodNotAllowedException();
        }
      } else {
        IdString id = path.remove(0);
        try {
          rsrc = rc.parse(rsrc, id);
          if (path.isEmpty()) {
            checkPreconditions(req, rsrc);
          }
        } catch (ResourceNotFoundException e) {
          if (rc instanceof AcceptsCreate
              && path.isEmpty()
              && ("POST".equals(req.getMethod())
                  || "PUT".equals(req.getMethod()))) {
            @SuppressWarnings("unchecked")
            AcceptsCreate<RestResource> ac = (AcceptsCreate<RestResource>) rc;
            viewData = new ViewData(null, ac.create(rsrc, id));
            status = SC_CREATED;
          } else {
            throw e;
          }
        }
        if (viewData.view == null) {
          viewData = view(rc, req.getMethod(), path);
        }
      }
      checkAccessAnnotations(viewData);

      while (viewData.view instanceof RestCollection<?,?>) {
        @SuppressWarnings("unchecked")
        RestCollection<RestResource, RestResource> c =
            (RestCollection<RestResource, RestResource>) viewData.view;

        if (path.isEmpty()) {
          if ("GET".equals(req.getMethod())) {
            viewData = new ViewData(null, c.list());
          } else if (c instanceof AcceptsPost && "POST".equals(req.getMethod())) {
            @SuppressWarnings("unchecked")
            AcceptsPost<RestResource> ac = (AcceptsPost<RestResource>) c;
            viewData = new ViewData(null, ac.post(rsrc));
          } else {
            throw new MethodNotAllowedException();
          }
          break;
        } else {
          IdString id = path.remove(0);
          try {
            rsrc = c.parse(rsrc, id);
            checkPreconditions(req, rsrc);
            viewData = new ViewData(null, null);
          } catch (ResourceNotFoundException e) {
            if (c instanceof AcceptsCreate
                && path.isEmpty()
                && ("POST".equals(req.getMethod())
                    || "PUT".equals(req.getMethod()))) {
              @SuppressWarnings("unchecked")
              AcceptsCreate<RestResource> ac = (AcceptsCreate<RestResource>) c;
              viewData = new ViewData(null, ac.create(rsrc, id));
              status = SC_CREATED;
            } else {
              throw e;
            }
          }
          if (viewData.view == null) {
            viewData = view(c, req.getMethod(), path);
          }
        }
        checkAccessAnnotations(viewData);
      }

      if (notModified(req, rsrc)) {
        res.sendError(SC_NOT_MODIFIED);
        return;
      }

      Multimap<String, String> config = LinkedHashMultimap.create();
      ParameterParser.splitQueryString(req.getQueryString(), config, params);
      if (!globals.paramParser.get().parse(viewData.view, params, req, res)) {
        return;
      }

      if (viewData.view instanceof RestModifyView<?, ?>) {
        @SuppressWarnings("unchecked")
        RestModifyView<RestResource, Object> m =
            (RestModifyView<RestResource, Object>) viewData.view;

        inputRequestBody = parseRequest(req, inputType(m));
        result = m.apply(rsrc, inputRequestBody);
      } else if (viewData.view instanceof RestReadView<?>) {
        result = ((RestReadView<RestResource>) viewData.view).apply(rsrc);
      } else {
        throw new ResourceNotFoundException();
      }

      if (result instanceof Response) {
        @SuppressWarnings("rawtypes")
        Response<?> r = (Response) result;
        status = r.statusCode();
        configureCaching(req, res, rsrc, r.caching());
      } else if (result instanceof Response.Redirect) {
        CacheHeaders.setNotCacheable(res);
        res.sendRedirect(((Response.Redirect) result).location());
        return;
      } else {
        CacheHeaders.setNotCacheable(res);
      }
      res.setStatus(status);

      if (result != Response.none()) {
        result = Response.unwrap(result);
        if (result instanceof BinaryResult) {
          replyBinaryResult(req, res, (BinaryResult) result);
        } else {
          replyJson(req, res, config, result);
        }
      }
    } catch (AuthException e) {
      replyError(req, res, status = SC_FORBIDDEN, e.getMessage(), e.caching());
    } catch (BadRequestException e) {
      replyError(req, res, status = SC_BAD_REQUEST, e.getMessage(), e.caching());
    } catch (MethodNotAllowedException e) {
      replyError(req, res, status = SC_METHOD_NOT_ALLOWED, "Method not allowed", e.caching());
    } catch (ResourceConflictException e) {
      replyError(req, res, status = SC_CONFLICT, e.getMessage(), e.caching());
    } catch (PreconditionFailedException e) {
      replyError(req, res, status = SC_PRECONDITION_FAILED,
          Objects.firstNonNull(e.getMessage(), "Precondition failed"), e.caching());
    } catch (ResourceNotFoundException e) {
      replyError(req, res, status = SC_NOT_FOUND, "Not found", e.caching());
    } catch (UnprocessableEntityException e) {
      replyError(req, res, status = 422,
          Objects.firstNonNull(e.getMessage(), "Unprocessable Entity"), e.caching());
    } catch (AmbiguousViewException e) {
      replyError(req, res, status = SC_NOT_FOUND, e.getMessage());
    } catch (MalformedJsonException e) {
      replyError(req, res, status = SC_BAD_REQUEST, "Invalid " + JSON_TYPE + " in request");
    } catch (JsonParseException e) {
      replyError(req, res, status = SC_BAD_REQUEST, "Invalid " + JSON_TYPE + " in request");
    } catch (Exception e) {
      status = SC_INTERNAL_SERVER_ERROR;
      handleException(e, req, res);
    } finally {
      globals.auditService.dispatch(new HttpAuditEvent(globals.webSession.get()
          .getSessionId(), globals.currentUser.get(), req.getRequestURI(),
          auditStartTs, params, req.getMethod(), inputRequestBody, status,
          result));
    }
  }

  private static boolean notModified(HttpServletRequest req, RestResource rsrc) {
    if (!"GET".equals(req.getMethod())) {
      return false;
    }

    if (rsrc instanceof RestResource.HasETag) {
      String have = req.getHeader(HttpHeaders.IF_NONE_MATCH);
      if (have != null) {
        return have.equals(((RestResource.HasETag) rsrc).getETag());
      }
    }

    if (rsrc instanceof RestResource.HasLastModified) {
      Timestamp m = ((RestResource.HasLastModified) rsrc).getLastModified();
      long d = req.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);

      // HTTP times are in seconds, database may have millisecond precision.
      return d / 1000L == m.getTime() / 1000L;
    }
    return false;
  }

  private static <T> void configureCaching(HttpServletRequest req,
      HttpServletResponse res, RestResource rsrc, CacheControl c) {
    if ("GET".equals(req.getMethod())) {
      switch (c.getType()) {
        case NONE:
        default:
          CacheHeaders.setNotCacheable(res);
          break;
        case PRIVATE:
          addResourceStateHeaders(res, rsrc);
          CacheHeaders.setCacheablePrivate(res,
              c.getAge(), c.getUnit(),
              c.isMustRevalidate());
          break;
        case PUBLIC:
          addResourceStateHeaders(res, rsrc);
          CacheHeaders.setCacheable(req, res,
              c.getAge(), c.getUnit(),
              c.isMustRevalidate());
          break;
      }
    } else {
      CacheHeaders.setNotCacheable(res);
    }
  }

  private static void addResourceStateHeaders(
      HttpServletResponse res, RestResource rsrc) {
    if (rsrc instanceof RestResource.HasETag) {
      res.setHeader(
          HttpHeaders.ETAG,
          ((RestResource.HasETag) rsrc).getETag());
    }
    if (rsrc instanceof RestResource.HasLastModified) {
      res.setDateHeader(
          HttpHeaders.LAST_MODIFIED,
          ((RestResource.HasLastModified) rsrc).getLastModified().getTime());
    }
  }

  private void checkPreconditions(HttpServletRequest req, RestResource rsrc)
      throws PreconditionFailedException {
    if ("*".equals(req.getHeader("If-None-Match"))) {
      throw new PreconditionFailedException("Resource already exists");
    }
  }

  private static Type inputType(RestModifyView<RestResource, Object> m) {
    Type inputType = extractInputType(m.getClass());
    if (inputType == null) {
      throw new IllegalStateException(String.format(
          "View %s does not correctly implement %s",
          m.getClass(), RestModifyView.class.getSimpleName()));
    }
    return inputType;
  }

  @SuppressWarnings("rawtypes")
  private static Type extractInputType(Class clazz) {
    for (Type t : clazz.getGenericInterfaces()) {
      if (t instanceof ParameterizedType
          && ((ParameterizedType) t).getRawType() == RestModifyView.class) {
        return ((ParameterizedType) t).getActualTypeArguments()[1];
      }
    }

    if (clazz.getSuperclass() != null) {
      Type i = extractInputType(clazz.getSuperclass());
      if (i != null) {
        return i;
      }
    }

    for (Class t : clazz.getInterfaces()) {
      Type i = extractInputType(t);
      if (i != null) {
        return i;
      }
    }

    return null;
  }

  private Object parseRequest(HttpServletRequest req, Type type)
      throws IOException, BadRequestException, SecurityException,
      IllegalArgumentException, NoSuchMethodException, IllegalAccessException,
      InstantiationException, InvocationTargetException, MethodNotAllowedException {
    if (isType(JSON_TYPE, req.getContentType())) {
      BufferedReader br = req.getReader();
      try {
        JsonReader json = new JsonReader(br);
        json.setLenient(true);

        JsonToken first;
        try {
          first = json.peek();
        } catch (EOFException e) {
          throw new BadRequestException("Expected JSON object");
        }
        if (first == JsonToken.STRING) {
          return parseString(json.nextString(), type);
        }
        return OutputFormat.JSON.newGson().fromJson(json, type);
      } finally {
        br.close();
      }
    } else if (("PUT".equals(req.getMethod()) || "POST".equals(req.getMethod()))
        && acceptsRawInput(type)) {
      return parseRawInput(req, type);
    } else if ("DELETE".equals(req.getMethod()) && hasNoBody(req)) {
      return null;
    } else if (hasNoBody(req)) {
      return createInstance(type);
    } else if (isType("text/plain", req.getContentType())) {
      BufferedReader br = req.getReader();
      try {
        char[] tmp = new char[256];
        StringBuilder sb = new StringBuilder();
        int n;
        while (0 < (n = br.read(tmp))) {
          sb.append(tmp, 0, n);
        }
        return parseString(sb.toString(), type);
      } finally {
        br.close();
      }
    } else if ("POST".equals(req.getMethod())
        && isType(FORM_TYPE, req.getContentType())) {
      return OutputFormat.JSON.newGson().fromJson(
          ParameterParser.formToJson(req),
          type);
    } else {
      throw new BadRequestException("Expected Content-Type: " + JSON_TYPE);
    }
  }

  private static boolean hasNoBody(HttpServletRequest req) {
    int len = req.getContentLength();
    String type = req.getContentType();
    return (len <= 0 && type == null)
        || (len == 0 && isType(FORM_TYPE, type));
  }

  @SuppressWarnings("rawtypes")
  private static boolean acceptsRawInput(Type type) {
    if (type instanceof Class) {
      for (Field f : ((Class) type).getDeclaredFields()) {
        if (f.getType() == RawInput.class) {
          return true;
        }
      }
    }
    return false;
  }

  private Object parseRawInput(final HttpServletRequest req, Type type)
      throws SecurityException, NoSuchMethodException,
      IllegalArgumentException, InstantiationException, IllegalAccessException,
      InvocationTargetException, MethodNotAllowedException {
    Object obj = createInstance(type);
    for (Field f : obj.getClass().getDeclaredFields()) {
      if (f.getType() == RawInput.class) {
        f.setAccessible(true);
        f.set(obj, new RawInput() {
          @Override
          public String getContentType() {
            return req.getContentType();
          }

          @Override
          public long getContentLength() {
            return req.getContentLength();
          }

          @Override
          public InputStream getInputStream() throws IOException {
            return req.getInputStream();
          }
        });
        return obj;
      }
    }
    throw new MethodNotAllowedException();
  }

  private Object parseString(String value, Type type)
      throws BadRequestException, SecurityException, NoSuchMethodException,
      IllegalArgumentException, IllegalAccessException, InstantiationException,
      InvocationTargetException {
    if (type == String.class) {
      return value;
    }

    Object obj = createInstance(type);
    Field[] fields = obj.getClass().getDeclaredFields();
    if (fields.length == 0 && Strings.isNullOrEmpty(value)) {
      return obj;
    }
    for (Field f : fields) {
      if (f.getAnnotation(DefaultInput.class) != null
          && f.getType() == String.class) {
        f.setAccessible(true);
        f.set(obj, value);
        return obj;
      }
    }
    throw new BadRequestException("Expected JSON object");
  }

  private static Object createInstance(Type type)
      throws NoSuchMethodException, InstantiationException,
      IllegalAccessException, InvocationTargetException {
    if (type instanceof Class) {
      @SuppressWarnings("unchecked")
      Class<Object> clazz = (Class<Object>) type;
      Constructor<Object> c = clazz.getDeclaredConstructor();
      c.setAccessible(true);
      return c.newInstance();
    }
    throw new InstantiationException("Cannot make " + type);
  }

  private static void replyJson(@Nullable HttpServletRequest req,
      HttpServletResponse res,
      Multimap<String, String> config,
      Object result)
      throws IOException {
    TemporaryBuffer.Heap buf = heap(Integer.MAX_VALUE);
    buf.write(JSON_MAGIC);
    Writer w = new BufferedWriter(new OutputStreamWriter(buf, UTF_8));
    Gson gson = newGson(config, req);
    if (result instanceof JsonElement) {
      gson.toJson((JsonElement) result, w);
    } else {
      gson.toJson(result, w);
    }
    w.write('\n');
    w.flush();
    replyBinaryResult(req, res, asBinaryResult(buf)
      .setContentType(JSON_TYPE)
      .setCharacterEncoding(UTF_8.name()));
  }

  private static Gson newGson(Multimap<String, String> config,
      @Nullable HttpServletRequest req) {
    GsonBuilder gb = OutputFormat.JSON_COMPACT.newGsonBuilder();

    enablePrettyPrint(gb, config, req);
    enablePartialGetFields(gb, config);

    return gb.create();
  }

  private static void enablePrettyPrint(GsonBuilder gb,
      Multimap<String, String> config,
      @Nullable HttpServletRequest req) {
    String pp = Iterables.getFirst(config.get("pp"), null);
    if (pp == null) {
      pp = Iterables.getFirst(config.get("prettyPrint"), null);
      if (pp == null && req != null) {
        pp = acceptsJson(req) ? "0" : "1";
      }
    }
    if ("1".equals(pp) || "true".equals(pp)) {
      gb.setPrettyPrinting();
    }
  }

  private static void enablePartialGetFields(GsonBuilder gb,
      Multimap<String, String> config) {
    final Set<String> want = Sets.newHashSet();
    for (String p : config.get("fields")) {
      Iterables.addAll(want, OptionUtil.splitOptionValue(p));
    }
    if (!want.isEmpty()) {
      gb.addSerializationExclusionStrategy(new ExclusionStrategy() {
        private final Map<String, String> names = Maps.newHashMap();

        @Override
        public boolean shouldSkipField(FieldAttributes field) {
          String name = names.get(field.getName());
          if (name == null) {
            // Names are supplied by Gson in terms of Java source.
            // Translate and cache the JSON lower_case_style used.
            try {
              name =
                  FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES.translateName(//
                      field.getDeclaringClass().getDeclaredField(field.getName()));
              names.put(field.getName(), name);
            } catch (SecurityException e) {
              return true;
            } catch (NoSuchFieldException e) {
              return true;
            }
          }
          return !want.contains(name);
        }

        @Override
        public boolean shouldSkipClass(Class<?> clazz) {
          return false;
        }
      });
    }
  }

  static void replyBinaryResult(
      @Nullable HttpServletRequest req,
      HttpServletResponse res,
      BinaryResult bin) throws IOException {
    final BinaryResult appResult = bin;
    try {
      if (bin.isBase64()) {
        bin = stackBase64(res, bin);
      }
      if (bin.canGzip() && acceptsGzip(req)) {
        bin = stackGzip(res, bin);
      }

      res.setContentType(bin.getContentType());
      long len = bin.getContentLength();
      if (0 <= len && len < Integer.MAX_VALUE) {
        res.setContentLength((int) len);
      } else if (0 <= len) {
        res.setHeader("Content-Length", Long.toString(len));
      }

      OutputStream dst = res.getOutputStream();
      try {
        bin.writeTo(dst);
      } finally {
        dst.close();
      }
    } finally {
      appResult.close();
    }
  }

  private static BinaryResult stackBase64(HttpServletResponse res,
      final BinaryResult src) throws IOException {
    BinaryResult b64;
    long len = src.getContentLength();
    if (0 <= len && len <= (7 << 20)) {
      b64 = base64(src);
    } else {
      b64 = new BinaryResult() {
        @Override
        public void writeTo(OutputStream out) throws IOException {
          OutputStream e = BaseEncoding.base64().encodingStream(
              new OutputStreamWriter(out, Charsets.ISO_8859_1));
          src.writeTo(e);
          e.flush();
        }
      };
    }
    res.setHeader("X-FYI-Content-Encoding", "base64");
    res.setHeader("X-FYI-Content-Type", src.getContentType());
    return b64.setContentType("text/plain").setCharacterEncoding("ISO-8859-1");
  }

  private static BinaryResult stackGzip(HttpServletResponse res,
      final BinaryResult src) throws IOException {
    BinaryResult gz;
    long len = src.getContentLength();
    if (256 <= len && len <= (10 << 20)) {
      gz = compress(src);
      if (len <= gz.getContentLength()) {
        return src;
      }
    } else {
      gz = new BinaryResult() {
        @Override
        public void writeTo(OutputStream out) throws IOException {
          GZIPOutputStream gz = new GZIPOutputStream(out);
          src.writeTo(gz);
          gz.finish();
          gz.flush();
        }
      };
    }
    res.setHeader("Content-Encoding", "gzip");
    return gz.setContentType(src.getContentType());
  }

  private ViewData view(
      RestCollection<RestResource, RestResource> rc,
      String method, List<IdString> path) throws ResourceNotFoundException,
      MethodNotAllowedException, AmbiguousViewException {
    DynamicMap<RestView<RestResource>> views = rc.views();
    final IdString projection = path.isEmpty()
        ? IdString.fromUrl("/")
        : path.remove(0);
    if (!path.isEmpty()) {
      // If there are path components still remaining after this projection
      // is chosen, look for the projection based upon GET as the method as
      // the client thinks it is a nested collection.
      method = "GET";
    }

    List<String> p = splitProjection(projection);
    if (p.size() == 2) {
      RestView<RestResource> view =
          views.get(p.get(0), method + "." + p.get(1));
      if (view != null) {
        return new ViewData(p.get(0), view);
      }
      throw new ResourceNotFoundException(projection);
    }

    String name = method + "." + p.get(0);
    RestView<RestResource> core = views.get("gerrit", name);
    if (core != null) {
      return new ViewData(null, core);
    }

    Map<String, RestView<RestResource>> r = Maps.newTreeMap();
    for (String plugin : views.plugins()) {
      RestView<RestResource> action = views.get(plugin, name);
      if (action != null) {
        r.put(plugin, action);
      }
    }

    if (r.size() == 1) {
      Map.Entry<String, RestView<RestResource>> entry =
          Iterables.getOnlyElement(r.entrySet());
      return new ViewData(entry.getKey(), entry.getValue());
    } else if (r.isEmpty()) {
      throw new ResourceNotFoundException(projection);
    } else {
      throw new AmbiguousViewException(String.format(
        "Projection %s is ambiguous: ",
        name,
        Joiner.on(", ").join(
          Iterables.transform(r.keySet(), new Function<String, String>() {
            @Override
            public String apply(String in) {
              return in + "~" + projection;
            }
          }))));
    }
  }

  private static List<IdString> splitPath(HttpServletRequest req) {
    String path = req.getPathInfo();
    if (Strings.isNullOrEmpty(path)) {
      return Collections.emptyList();
    }
    List<IdString> out = Lists.newArrayList();
    for (String p : Splitter.on('/').split(path)) {
      out.add(IdString.fromUrl(p));
    }
    if (out.size() > 0 && out.get(out.size() - 1).isEmpty()) {
      out.remove(out.size() - 1);
    }
    return out;
  }

  private static List<String> splitProjection(IdString projection) {
    List<String> p = Lists.newArrayListWithCapacity(2);
    Iterables.addAll(p, Splitter.on('~').limit(2).split(projection.get()));
    return p;
  }

  private void checkUserSession(HttpServletRequest req)
      throws AuthException {
    CurrentUser user = globals.currentUser.get();
    if (isStateChange(req)) {
      if (user instanceof AnonymousUser) {
        throw new AuthException("Authentication required");
      } else if (!globals.webSession.get().isAccessPathOk(AccessPath.REST_API)) {
        throw new AuthException("Invalid authentication method. In order to authenticate, prefix the REST endpoint URL with /a/ (e.g. http://example.com/a/projects/).");
      }
    }
    user.setAccessPath(AccessPath.REST_API);
  }

  private static boolean isStateChange(HttpServletRequest req) {
    String method = req.getMethod();
    return !("GET".equals(method) || "HEAD".equals(method));
  }

  private void checkAccessAnnotations(ViewData viewData) throws AuthException {
    checkAccessAnnotations(viewData.pluginName, viewData.view.getClass());
  }

  private void checkAccessAnnotations(String pluginName, Class<?> clazz)
      throws AuthException {
    RequiresCapability rc = clazz.getAnnotation(RequiresCapability.class);
    if (rc != null) {
      CurrentUser user = globals.currentUser.get();
      CapabilityControl ctl = user.getCapabilities();
      String capability = rc.value();

     if (pluginName != null && !"gerrit".equals(pluginName)
         && (rc.scope() == CapabilityScope.PLUGIN
          || rc.scope() == CapabilityScope.CONTEXT)) {
        capability = String.format("%s-%s", pluginName, rc.value());
      } else if (rc.scope() == CapabilityScope.PLUGIN) {
        log.error(String.format(
            "Class %s uses @%s(scope=%s), but is not within a plugin",
            clazz.getName(),
            RequiresCapability.class.getSimpleName(),
            CapabilityScope.PLUGIN.name()));
        throw new AuthException("cannot check capability");
      }

      if (!ctl.canPerform(capability) && !ctl.canAdministrateServer()) {
        throw new AuthException(String.format(
            "Capability %s is required to access this resource",
            capability));
      }
    }
  }

  private static void handleException(Throwable err, HttpServletRequest req,
      HttpServletResponse res) throws IOException {
    String uri = req.getRequestURI();
    if (!Strings.isNullOrEmpty(req.getQueryString())) {
      uri += "?" + req.getQueryString();
    }
    log.error(String.format("Error in %s %s", req.getMethod(), uri), err);

    if (!res.isCommitted()) {
      res.reset();
      replyError(req, res, SC_INTERNAL_SERVER_ERROR, "Internal server error");
    }
  }

  public static void replyError(HttpServletRequest req,
      HttpServletResponse res, int statusCode, String msg) throws IOException {
    replyError(req, res, statusCode, msg, CacheControl.NONE);
  }

  public static void replyError(HttpServletRequest req,
      HttpServletResponse res, int statusCode, String msg,
      CacheControl c) throws IOException {
    res.setStatus(statusCode);
    configureCaching(req, res, null, c);
    replyText(null, res, msg);
  }

  static void replyText(@Nullable HttpServletRequest req,
      HttpServletResponse res, String text) throws IOException {
    if ((req == null || "GET".equals(req.getMethod())) && isMaybeHTML(text)) {
      replyJson(req, res, ImmutableMultimap.of("pp", "0"), new JsonPrimitive(text));
    } else {
      if (!text.endsWith("\n")) {
        text += "\n";
      }
      replyBinaryResult(req, res,
          BinaryResult.create(text).setContentType("text/plain"));
    }
  }

  private static final Pattern IS_HTML = Pattern.compile("[<&]");
  private static boolean isMaybeHTML(String text) {
    return IS_HTML.matcher(text).find();
  }

  private static boolean acceptsJson(HttpServletRequest req) {
    return req != null && isType(JSON_TYPE, req.getHeader(HttpHeaders.ACCEPT));
  }

  private static boolean acceptsGzip(HttpServletRequest req) {
    if (req != null) {
      String accepts = req.getHeader(HttpHeaders.ACCEPT_ENCODING);
      return accepts != null && accepts.indexOf("gzip") != -1;
    }
    return false;
  }

  private static boolean isType(String expect, String given) {
    if (given == null) {
      return false;
    } else if (expect.equals(given)) {
      return true;
    } else if (given.startsWith(expect + ",")) {
      return true;
    }
    for (String p : given.split("[ ,;][ ,;]*")) {
      if (expect.equals(p)) {
        return true;
      }
    }
    return false;
  }

  private static BinaryResult base64(BinaryResult bin)
      throws IOException {
    int max = 4 * IntMath.divide((int) bin.getContentLength(), 3, CEILING);
    TemporaryBuffer.Heap buf = heap(max);
    OutputStream encoded = BaseEncoding.base64().encodingStream(
        new OutputStreamWriter(buf, Charsets.ISO_8859_1));
    bin.writeTo(encoded);
    encoded.close();
    return asBinaryResult(buf);
  }

  private static BinaryResult compress(BinaryResult bin)
      throws IOException {
    TemporaryBuffer.Heap buf = heap(20 << 20);
    GZIPOutputStream gz = new GZIPOutputStream(buf);
    bin.writeTo(gz);
    gz.close();
    return asBinaryResult(buf).setContentType(bin.getContentType());
  }

  private static BinaryResult asBinaryResult(final TemporaryBuffer.Heap buf) {
    return new BinaryResult() {
      @Override
      public void writeTo(OutputStream os) throws IOException {
        buf.writeTo(os, null);
      }
    }.setContentLength(buf.length());
  }

  private static Heap heap(int max) {
    return new TemporaryBuffer.Heap(max);
  }

  @SuppressWarnings("serial")
  private static class AmbiguousViewException extends Exception {
    AmbiguousViewException(String message) {
      super(message);
    }
  }

  private static class ViewData {
    String pluginName;
    RestView<RestResource> view;

    ViewData(String pluginName, RestView<RestResource> view) {
      this.pluginName = pluginName;
      this.view = view;
    }
  }
}
