// Copyright (C) 2014 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.googlesource.gerrit.plugins.xdocs;

import static java.nio.charset.StandardCharsets.UTF_8;
import static javax.servlet.http.HttpServletResponse.SC_NOT_MODIFIED;

import com.google.common.base.CharMatcher;
import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
import com.google.common.net.HttpHeaders;
import com.google.gerrit.common.data.PatchScript.FileMode;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.httpd.resources.Resource;
import com.google.gerrit.httpd.resources.SmallResource;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.change.FileContentUtil;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.mime.FileTypeRegistry;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.RefPermission;
import com.google.gerrit.server.project.CommitsCollection;
import com.google.gerrit.server.project.GetHead;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.ProjectResource;
import com.google.gerrit.server.project.ProjectState;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.xdocs.formatter.Formatters;
import com.googlesource.gerrit.plugins.xdocs.formatter.Formatters.FormatterProvider;
import eu.medsea.mimeutil.MimeType;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.errors.RevisionSyntaxException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.PathFilter;

@Singleton
public class XDocServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;

  public static final String PATH_PREFIX = "/project/";

  private final String pluginName;
  private final ProjectControl.Factory projectControlFactory;
  private final ProjectCache projectCache;
  private final Provider<GetHead> getHead;
  private final GitRepositoryManager repoManager;
  private final XDocCache docCache;
  private final FileTypeRegistry fileTypeRegistry;
  private final XDocProjectConfig.Factory cfgFactory;
  private final Formatters formatters;
  private final CommitsCollection commits;
  private final PermissionBackend permissionBackend;

  @Inject
  XDocServlet(
      @PluginName String pluginName,
      ProjectControl.Factory projectControlFactory,
      ProjectCache projectCache,
      Provider<GetHead> getHead,
      GitRepositoryManager repoManager,
      XDocCache cache,
      FileTypeRegistry fileTypeRegistry,
      XDocProjectConfig.Factory cfgFactory,
      Formatters formatters,
      CommitsCollection commits,
      PermissionBackend permissionBackend) {
    this.pluginName = pluginName;
    this.projectControlFactory = projectControlFactory;
    this.projectCache = projectCache;
    this.getHead = getHead;
    this.repoManager = repoManager;
    this.docCache = cache;
    this.fileTypeRegistry = fileTypeRegistry;
    this.cfgFactory = cfgFactory;
    this.formatters = formatters;
    this.commits = commits;
    this.permissionBackend = permissionBackend;
  }

  @Override
  public void service(HttpServletRequest req, HttpServletResponse res) throws IOException {
    try {
      validateRequestMethod(req);

      ResourceKey key = ResourceKey.fromPath(getEncodedPath(req));
      ProjectState state = getProject(key);
      XDocProjectConfig cfg = cfgFactory.create(state);

      if (key.file == null) {
        res.sendRedirect(getRedirectUrl(req, key, cfg));
        return;
      }

      MimeType mimeType = fileTypeRegistry.getMimeType(key.file, (byte[]) null);
      mimeType =
          new MimeType(
              FileContentUtil.resolveContentType(
                  state, key.file, FileMode.FILE, mimeType.toString()));
      FormatterProvider formatter = getFormatter(req, key, mimeType);
      validateDiffMode(key);

      ProjectControl projectControl = projectControlFactory.controlFor(key.project);
      String rev =
          getRevision(
              key.diffMode == DiffMode.NO_DIFF
                  ? MoreObjects.firstNonNull(key.revision, cfg.getIndexRef())
                  : key.revision,
              projectControl);
      String revB = getRevision(key.revisionB, projectControl);

      try (Repository repo = repoManager.openRepository(key.project)) {
        ObjectId revId =
            resolveRevision(
                repo,
                key.diffMode == DiffMode.NO_DIFF
                    ? MoreObjects.firstNonNull(rev, Constants.HEAD)
                    : rev);
        if (revId != null && ObjectId.isId(rev)) {
          validateCanReadCommit(repo, projectControl, revId);
        }

        ObjectId revIdB = resolveRevision(repo, revB);
        if (revIdB != null && ObjectId.isId(revB)) {
          validateCanReadCommit(repo, projectControl, revIdB);
        }

        if (isResourceNotModified(req, key, revId, revIdB)) {
          res.sendError(SC_NOT_MODIFIED);
          return;
        }

        Resource rsc;
        if (formatter != null) {
          rsc = docCache.get(formatter, key.project, key.file, revId, revIdB, key.diffMode);
        } else if (isImage(mimeType)) {
          rsc = getImageResource(repo, key.diffMode, revId, revIdB, key.file);
        } else {
          rsc = Resource.NOT_FOUND;
        }

        if (rsc != Resource.NOT_FOUND) {
          res.setHeader(
              HttpHeaders.ETAG, computeETag(key.project, revId, key.file, revIdB, key.diffMode));
        }
        if (key.diffMode == DiffMode.NO_DIFF && rev == null) {
          // file was loaded from HEAD, since HEAD is modifiable the document
          // should only be cached for a short period
          CacheHeaders.setCacheablePrivate(res, 15, TimeUnit.MINUTES, false);
        } else {
          CacheHeaders.setCacheablePrivate(res, 7, TimeUnit.DAYS, false);
        }
        rsc.send(req, res);
        return;
      }
    } catch (RepositoryNotFoundException
        | NoSuchProjectException
        | ResourceNotFoundException
        | AuthException
        | RevisionSyntaxException e) {
      Resource.NOT_FOUND.send(req, res);
    } catch (MethodNotAllowedException e) {
      CacheHeaders.setNotCacheable(res);
      res.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
    } catch (PermissionBackendException e) {
      //
    }
  }

  private String getEncodedPath(HttpServletRequest req) {
    String path = req.getRequestURI();
    String prefix = "/plugins/" + pluginName;
    if (path.startsWith(prefix)) {
      path = path.substring(prefix.length());
    }
    return path;
  }

  private Resource getImageResource(
      Repository repo, DiffMode diffMode, ObjectId revId, ObjectId revIdB, String file) {
    ObjectId id =
        diffMode == DiffMode.NO_DIFF || diffMode == DiffMode.SIDEBYSIDE_A ? revId : revIdB;
    try (RevWalk rw = new RevWalk(repo)) {
      RevCommit commit = rw.parseCommit(id);
      RevTree tree = commit.getTree();
      try (TreeWalk tw = new TreeWalk(repo)) {
        tw.addTree(tree);
        tw.setRecursive(true);
        tw.setFilter(PathFilter.create(file));
        if (!tw.next()) {
          return Resource.NOT_FOUND;
        }
        ObjectId objectId = tw.getObjectId(0);
        ObjectLoader loader = repo.open(objectId);
        byte[] content = loader.getBytes(Integer.MAX_VALUE);

        MimeType mimeType = fileTypeRegistry.getMimeType(file, content);
        if (!isSafeImage(mimeType)) {
          return Resource.NOT_FOUND;
        }
        return new SmallResource(content)
            .setContentType(mimeType.toString())
            .setCharacterEncoding(UTF_8.name())
            .setLastModified(commit.getCommitTime());
      }
    } catch (IOException e) {
      return Resource.NOT_FOUND;
    }
  }

  private static void validateRequestMethod(HttpServletRequest req)
      throws MethodNotAllowedException {
    if (!("GET".equals(req.getMethod()) || "HEAD".equals(req.getMethod()))) {
      throw new MethodNotAllowedException();
    }
  }

  private static void validateDiffMode(ResourceKey key) throws ResourceNotFoundException {
    if (key.diffMode != DiffMode.NO_DIFF && (key.revisionB == null)) {
      throw new ResourceNotFoundException();
    }
  }

  private ProjectState getProject(ResourceKey key) throws ResourceNotFoundException {
    ProjectState state = projectCache.get(key.project);
    if (state == null) {
      throw new ResourceNotFoundException();
    }
    return state;
  }

  private FormatterProvider getFormatter(HttpServletRequest req, ResourceKey key, MimeType mimeType)
      throws ResourceNotFoundException {
    FormatterProvider formatter;
    if (req.getParameter("raw") != null) {
      formatter = formatters.getRawFormatter();
    } else {
      formatter = formatters.get(getProject(key), key.file);
    }
    if (isSafeImage(mimeType)) {
      if (req.getParameter("formatImage") == null) {
        // image formatting is not requested, return the plain image
        formatter = null;
      }
    } else {
      if (formatter == null) {
        throw new ResourceNotFoundException();
      }
    }
    if (formatter == null && !isSafeImage(mimeType)) {
      throw new ResourceNotFoundException();
    }
    return formatter;
  }

  private boolean isSafeImage(MimeType mimeType) {
    return isImage(mimeType) && fileTypeRegistry.isSafeInline(mimeType);
  }

  private static boolean isImage(MimeType mimeType) {
    return "image".equals(mimeType.getMediaType());
  }

  private String getRevision(String revision, ProjectControl projectControl)
      throws ResourceNotFoundException, AuthException, IOException, PermissionBackendException {
    if (revision == null) {
      return null;
    }

    if (ObjectId.isId(revision)) {
      return revision;
    }

    if (Constants.HEAD.equals(revision)) {
      return getHead.get().apply(new ProjectResource(projectControl));
    }
    String rev = revision;
    if (!rev.startsWith(Constants.R_REFS)) {
      rev = Constants.R_HEADS + rev;
    }
    try {
      permissionBackend
          .user(projectControl.getUser())
          .project(projectControl.getProject().getNameKey())
          .ref(rev)
          .check(RefPermission.READ);
    } catch (AuthException e) {
      // Don't leak the project's existence
      throw new ResourceNotFoundException();
    }
    return rev;
  }

  private static ObjectId resolveRevision(Repository repo, String revision)
      throws ResourceNotFoundException, IOException {
    if (revision == null) {
      return null;
    }

    ObjectId revId = repo.resolve(revision);
    if (revId == null) {
      throw new ResourceNotFoundException();
    }
    return revId;
  }

  private void validateCanReadCommit(Repository repo, ProjectControl projectControl, ObjectId revId)
      throws ResourceNotFoundException, IOException {
    try (RevWalk rw = new RevWalk(repo)) {
      RevCommit commit = rw.parseCommit(revId);
      ProjectState state = projectControl.getProjectState();
      if (!commits.canRead(state, repo, commit)) {
        throw new ResourceNotFoundException();
      }
    }
  }

  private static boolean isResourceNotModified(
      HttpServletRequest req, ResourceKey key, ObjectId revId, ObjectId revIdB) {
    String receivedETag = req.getHeader(HttpHeaders.IF_NONE_MATCH);
    if (receivedETag != null) {
      return receivedETag.equals(computeETag(key.project, revId, key.file, revIdB, key.diffMode));
    }
    return false;
  }

  private static String computeETag(
      Project.NameKey project, ObjectId revId, String file, ObjectId revIdB, DiffMode diffMode) {
    @SuppressWarnings("deprecation")
    Hasher hasher = Hashing.md5().newHasher();
    hasher.putUnencodedChars(project.get());
    if (revId != null) {
      hasher.putUnencodedChars(revId.getName());
    }
    hasher.putUnencodedChars(file);
    if (diffMode != DiffMode.NO_DIFF) {
      hasher.putUnencodedChars(revIdB.getName()).putUnencodedChars(diffMode.name());
    }
    return hasher.hash().toString();
  }

  private String getRedirectUrl(HttpServletRequest req, ResourceKey key, XDocProjectConfig cfg) {
    StringBuilder redirectUrl = new StringBuilder();
    redirectUrl.append(
        req.getRequestURL()
            .substring(0, req.getRequestURL().length() - req.getRequestURI().length()));
    redirectUrl.append(req.getContextPath());
    redirectUrl.append(PATH_PREFIX);
    redirectUrl.append(IdString.fromDecoded(key.project.get()).encoded());
    redirectUrl.append("/");
    if (key.revision != null) {
      redirectUrl.append("rev/");
      redirectUrl.append(key.revision);
      redirectUrl.append("/");
    }
    redirectUrl.append(cfg.getIndexFile());
    return redirectUrl.toString();
  }

  private static class ResourceKey {
    final Project.NameKey project;
    final String file;
    final String revision;
    final String revisionB;
    final DiffMode diffMode;

    static ResourceKey fromPath(String path) {
      String project;
      String file = null;
      String revision = null;
      String revisionB = null;
      DiffMode diffMode = DiffMode.NO_DIFF;

      if (!path.startsWith(PATH_PREFIX)) {
        // should not happen since this servlet is only registered to handle
        // paths that start with this prefix
        throw new IllegalStateException("path must start with '" + PATH_PREFIX + "'");
      }
      path = path.substring(PATH_PREFIX.length());

      int i = path.indexOf('/');
      if (i != -1 && i != path.length() - 1) {
        project = IdString.fromUrl(path.substring(0, i)).get();
        String rest = path.substring(i + 1);

        if (rest.startsWith("rev/")) {
          if (rest.length() > 4) {
            rest = rest.substring(4);
            i = rest.indexOf('/');
            if (i != -1 && i != path.length() - 1) {
              revision = IdString.fromUrl(rest.substring(0, i)).get();
              file = rest.substring(i + 1);
            } else {
              revision = IdString.fromUrl(rest).get();
            }
          }
        } else {
          file = rest;
        }

      } else {
        project = IdString.fromUrl(CharMatcher.is('/').trimTrailingFrom(path)).get();
      }

      if (revision != null) {
        if (revision.contains("<->")) {
          diffMode = DiffMode.UNIFIED;
          int p = revision.indexOf("<->");
          revisionB = revision.substring(p + 3);
          revision = Strings.emptyToNull(revision.substring(0, p));
        } else if (revision.contains("<-")) {
          diffMode = DiffMode.SIDEBYSIDE_A;
          int p = revision.indexOf("<-");
          revisionB = revision.substring(p + 2);
          revision = revision.substring(0, p);
        } else if (revision.contains("->")) {
          diffMode = DiffMode.SIDEBYSIDE_B;
          int p = revision.indexOf("->");
          revisionB = revision.substring(p + 2);
          revision = Strings.emptyToNull(revision.substring(0, p));
        }
      }

      return new ResourceKey(project, file, revision, revisionB, diffMode);
    }

    private ResourceKey(String p, String f, String r, String r2, DiffMode dm) {
      project = new Project.NameKey(p);
      file = f;
      revision = r;
      revisionB = r2;
      diffMode = dm;
    }
  }
}
