// 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 org.eclipse.jgit.http.server.ServletUtils.ATTRIBUTE_REPOSITORY;

import com.google.common.base.Strings;
import com.google.gitiles.GitilesRequestFailureException.FailureReason;
import java.io.IOException;
import java.util.Map;
import javax.annotation.Nullable;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jgit.http.server.ServletUtils;
import org.eclipse.jgit.http.server.glue.WrappedRequest;

/** Filter to parse URLs and convert them to {@link GitilesView}s. */
public class ViewFilter extends AbstractHttpFilter {
  // TODO(dborowitz): Make this public in JGit (or implement getRegexGroup
  // upstream).
  private static final String REGEX_GROUPS_ATTRIBUTE =
      "org.eclipse.jgit.http.server.glue.MetaServlet.serveRegex";

  private static final String VIEW_ATTRIBUTE = ViewFilter.class.getName() + "/View";

  private static final String CMD_ARCHIVE = "+archive";
  private static final String CMD_AUTO = "+";
  private static final String CMD_BLAME = "+blame";
  private static final String CMD_DESCRIBE = "+describe";
  private static final String CMD_DIFF = "+diff";
  private static final String CMD_LOG = "+log";
  private static final String CMD_REFS = "+refs";
  private static final String CMD_SHOW = "+show";
  private static final String CMD_DOC = "+doc";

  public static GitilesView getView(HttpServletRequest req) {
    return (GitilesView) req.getAttribute(VIEW_ATTRIBUTE);
  }

  static String getRegexGroup(HttpServletRequest req, int groupId) {
    WrappedRequest[] groups = (WrappedRequest[]) req.getAttribute(REGEX_GROUPS_ATTRIBUTE);
    return checkNotNull(groups)[groupId].getPathInfo();
  }

  static void setView(HttpServletRequest req, GitilesView view) {
    req.setAttribute(VIEW_ATTRIBUTE, view);
  }

  static void removeView(HttpServletRequest req) {
    req.removeAttribute(VIEW_ATTRIBUTE);
  }

  static String trimLeadingSlash(String str) {
    return checkLeadingSlash(str).substring(1);
  }

  private static String checkLeadingSlash(String str) {
    checkArgument(str.startsWith("/"), "expected string starting with a slash: %s", str);
    return str;
  }

  private static boolean isEmptyOrSlash(String path) {
    return path.isEmpty() || path.equals("/");
  }

  private static boolean hasRepository(HttpServletRequest req) {
    return req.getAttribute(ATTRIBUTE_REPOSITORY) != null;
  }

  private final GitilesUrls urls;
  private final GitilesAccess.Factory accessFactory;
  private final VisibilityCache visibilityCache;
  private final BranchRedirect branchRedirect;

  public ViewFilter(
      GitilesAccess.Factory accessFactory,
      GitilesUrls urls,
      VisibilityCache visibilityCache,
      BranchRedirect branchRedirect) {
    this.urls = checkNotNull(urls, "urls");
    this.accessFactory = checkNotNull(accessFactory, "accessFactory");
    this.visibilityCache = checkNotNull(visibilityCache, "visibilityCache");
    this.branchRedirect = checkNotNull(branchRedirect, "branchRedirect");
  }

  @Override
  public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
      throws IOException, ServletException {
    GitilesView.Builder view = parse(req);
    if (view == null) {
      throw new GitilesRequestFailureException(FailureReason.CANNOT_PARSE_GITILES_VIEW);
    }

    Map<String, String[]> params = req.getParameterMap();
    view.setHostName(urls.getHostName(req))
        .setServletPath(req.getContextPath() + req.getServletPath())
        .putAllParams(params);
    if (normalize(view, res)) {
      return;
    }

    setView(req, view.build());
    try {
      chain.doFilter(req, res);
    } finally {
      removeView(req);
    }
  }

  private boolean normalize(GitilesView.Builder view, HttpServletResponse res) throws IOException {
    if (!Revision.isNull(view.getOldRevision())) {
      return false;
    }
    Revision r = view.getRevision();
    Revision nr = Revision.normalizeParentExpressions(r);
    if (!r.equals(nr)) {
      res.sendRedirect(view.setRevision(nr).toUrl());
      return true;
    }
    return false;
  }

  private @Nullable GitilesView.Builder parse(HttpServletRequest req) throws IOException {
    String repoName = trimLeadingSlash(getRegexGroup(req, 1));
    if (repoName.isEmpty()) {
      return GitilesView.hostIndex();
    }
    String command = getRegexGroup(req, 2);
    String path = getRegexGroup(req, 3);

    if (command.isEmpty()) {
      return parseNoCommand(req, repoName);
    }
    if (!hasRepository(req)) {
      return null; // no repository? return null to 404.
    }
    if (command.equals(CMD_ARCHIVE)) {
      return parseArchiveCommand(req, repoName, path);
    } else if (command.equals(CMD_AUTO)) {
      return parseAutoCommand(req, repoName, path);
    } else if (command.equals(CMD_BLAME)) {
      return parseBlameCommand(req, repoName, path);
    } else if (command.equals(CMD_DESCRIBE)) {
      return parseDescribeCommand(repoName, path);
    } else if (command.equals(CMD_DIFF)) {
      return parseDiffCommand(req, repoName, path);
    } else if (command.equals(CMD_LOG)) {
      return parseLogCommand(req, repoName, path);
    } else if (command.equals(CMD_REFS)) {
      return parseRefsCommand(repoName, path);
    } else if (command.equals(CMD_SHOW)) {
      return parseShowCommand(req, repoName, path);
    } else if (command.equals(CMD_DOC)) {
      return parseDocCommand(req, repoName, path);
    } else {
      return null;
    }
  }

  private GitilesView.Builder parseNoCommand(HttpServletRequest req, String repoName) {
    if (!hasRepository(req)) {
      return GitilesView.hostIndex().setRepositoryPrefix(repoName);
    }
    return GitilesView.repositoryIndex().setRepositoryName(repoName);
  }

  private @Nullable GitilesView.Builder parseArchiveCommand(
      HttpServletRequest req, String repoName, String path) throws IOException {
    String ext = null;
    for (String e : ArchiveFormat.allExtensions()) {
      if (path.endsWith(e)) {
        path = path.substring(0, path.length() - e.length());
        ext = e;
        break;
      }
    }
    if (ext == null || path.endsWith("/")) {
      return null;
    }
    RevisionParser.Result result = parseRevision(req, path);
    if (result == null || result.getOldRevision() != null) {
      return null;
    }
    return GitilesView.archive()
        .setRepositoryName(repoName)
        .setRevision(result.getRevision())
        .setPathPart(Strings.emptyToNull(result.getPath()))
        .setExtension(ext);
  }

  private @Nullable GitilesView.Builder parseAutoCommand(
      HttpServletRequest req, String repoName, String path) throws IOException {
    // Note: if you change the mapping for +, make sure to change
    // GitilesView.toUrl() correspondingly.
    if (path.isEmpty()) {
      return null;
    }
    RevisionParser.Result result = parseRevision(req, path);
    if (result == null) {
      return null;
    }
    if (result.getOldRevision() != null) {
      return parseDiffCommand(repoName, result);
    }
    GitilesView.Builder b = parseShowCommand(repoName, result);
    if (b != null && b.getPathPart() != null && b.getPathPart().endsWith(".md")) {
      return GitilesView.doc()
          .setRepositoryName(repoName)
          .setRevision(result.getRevision())
          .setPathPart(result.getPath());
    }
    return b;
  }

  private @Nullable GitilesView.Builder parseBlameCommand(
      HttpServletRequest req, String repoName, String path) throws IOException {
    if (path.isEmpty()) {
      return null;
    }
    RevisionParser.Result result = parseRevision(req, path);
    if (result == null || result.getOldRevision() != null || result.getPath().isEmpty()) {
      return null;
    }
    return GitilesView.blame()
        .setRepositoryName(repoName)
        .setRevision(result.getRevision())
        .setPathPart(result.getPath());
  }

  private @Nullable GitilesView.Builder parseDescribeCommand(String repoName, String path) {
    if (isEmptyOrSlash(path)) {
      return null;
    }
    return GitilesView.describe().setRepositoryName(repoName).setPathPart(path);
  }

  private GitilesView.Builder parseDiffCommand(HttpServletRequest req, String repoName, String path)
      throws IOException {
    return parseDiffCommand(repoName, parseRevision(req, path));
  }

  private @Nullable GitilesView.Builder parseDiffCommand(
      String repoName, RevisionParser.Result result) {
    if (result == null) {
      return null;
    }
    return GitilesView.diff()
        .setRepositoryName(repoName)
        .setRevision(result.getRevision())
        .setOldRevision(result.getOldRevision())
        .setPathPart(result.getPath());
  }

  private @Nullable GitilesView.Builder parseLogCommand(
      HttpServletRequest req, String repoName, String path) throws IOException {
    if (isEmptyOrSlash(path)) {
      return GitilesView.log().setRepositoryName(repoName);
    }
    RevisionParser.Result result = parseRevision(req, path);
    if (result == null) {
      return null;
    }
    return GitilesView.log()
        .setRepositoryName(repoName)
        .setRevision(result.getRevision())
        .setOldRevision(result.getOldRevision())
        .setPathPart(result.getPath());
  }

  private GitilesView.Builder parseRefsCommand(String repoName, String path) {
    return GitilesView.refs().setRepositoryName(repoName).setPathPart(path);
  }

  private GitilesView.Builder parseShowCommand(HttpServletRequest req, String repoName, String path)
      throws IOException {
    return parseShowCommand(repoName, parseRevision(req, path));
  }

  private @Nullable GitilesView.Builder parseShowCommand(
      String repoName, RevisionParser.Result result) {
    if (result == null || result.getOldRevision() != null) {
      return null;
    }
    if (result.getPath().isEmpty()) {
      return GitilesView.revision().setRepositoryName(repoName).setRevision(result.getRevision());
    }
    return GitilesView.path()
        .setRepositoryName(repoName)
        .setRevision(result.getRevision())
        .setPathPart(result.getPath());
  }

  private GitilesView.Builder parseDocCommand(HttpServletRequest req, String repoName, String path)
      throws IOException {
    return parseDocCommand(repoName, parseRevision(req, path));
  }

  private @Nullable GitilesView.Builder parseDocCommand(
      String repoName, RevisionParser.Result result) {
    if (result == null || result.getOldRevision() != null) {
      return null;
    }
    GitilesView.Builder b =
        GitilesView.doc().setRepositoryName(repoName).setRevision(result.getRevision());
    if (!result.getPath().isEmpty()) {
      b.setPathPart(result.getPath());
    }
    return b;
  }

  private RevisionParser.Result parseRevision(HttpServletRequest req, String path)
      throws IOException {
    RevisionParser revParser =
        new RevisionParser(
            ServletUtils.getRepository(req),
            accessFactory.forRequest(req),
            visibilityCache,
            getBranchRedirect(req));
    return revParser.parse(checkLeadingSlash(path));
  }

  private BranchRedirect getBranchRedirect(HttpServletRequest req) {
    return BranchRedirect.isForAutomation(req) ? BranchRedirect.EMPTY : branchRedirect;
  }
}
