// Copyright 2021 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.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.gitiles.GitilesServlet.STATIC_PREFIX;
import static com.google.gitiles.Renderer.fileUrlMapper;
import static java.util.stream.Collectors.toList;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Maps;
import com.google.gitiles.blame.BlameServlet;
import com.google.gitiles.blame.cache.BlameCache;
import com.google.gitiles.blame.cache.BlameCacheImpl;
import com.google.gitiles.doc.DocServlet;
import java.io.File;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.http.server.glue.MetaFilter;
import org.eclipse.jgit.http.server.glue.ServletBinder;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.transport.resolver.FileResolver;
import org.eclipse.jgit.transport.resolver.RepositoryResolver;

/**
 * MetaFilter to serve Gitiles.
 *
 * <p>Do not use directly; use {@link GitilesServlet}.
 */
class GitilesFilter extends MetaFilter {

  // The following regexes have the following capture groups:
  // 1. The whole string, which causes RegexPipeline to set REGEX_GROUPS but
  //    not otherwise modify the original request.
  // 2. The repository name part, before /<CMD>.
  // 3. The command, <CMD>, with no slashes and beginning with +. Commands have
  //    names analogous to (but not exactly the same as) git command names, such
  //    as "+log" and "+show". The bare command "+" maps to one of the other
  //    commands based on the revision/path, and may change over time.
  // 4. The revision/path part, after /<CMD> (called just "path" below). This is
  //    split into a revision and a path by RevisionParser.

  private static final String CMD = "\\+[a-z0-9-]*";

  @VisibleForTesting
  static final Pattern ROOT_REGEX =
      Pattern.compile(
          ""
              + "^(      " // 1. Everything
              + "  /*    " // Excess slashes
              + "  (/)   " // 2. Repo name (just slash)
              + "  ()    " // 3. Command
              + "  ()    " // 4. Path
              + ")$      ",
          Pattern.COMMENTS);

  @VisibleForTesting
  static final Pattern REPO_REGEX =
      Pattern.compile(
          ""
              + "^(                     " // 1. Everything
              + "  /*                   " // Excess slashes
              + "  (                    " // 2. Repo name
              + "   /                   " // Leading slash
              + "   (?:.(?!             " // Anything, as long as it's not followed by...
              + "        /"
              + CMD
              + "/  " // the special "/<CMD>/" separator,
              + "        |/"
              + CMD
              + "$ " // or "/<CMD>" at the end of the string
              + "        ))*?           "
              + "  )                    "
              + "  /*                   " // Trailing slashes
              + "  ()                   " // 3. Command
              + "  ()                   " // 4. Path
              + ")$                     ",
          Pattern.COMMENTS);

  @VisibleForTesting
  static final Pattern REPO_PATH_REGEX =
      Pattern.compile(
          ""
              + "^(              " // 1. Everything
              + "  /*            " // Excess slashes
              + "  (             " // 2. Repo name
              + "   /            " // Leading slash
              + "   .*?          " // Anything, non-greedy
              + "  )             "
              + "  /("
              + CMD
              + ")" // 3. Command
              + "  (             " // 4. Path
              + "   (?:/.*)?     " // Slash path, or nothing.
              + "  )             "
              + ")$              ",
          Pattern.COMMENTS);

  private static class DispatchFilter extends AbstractHttpFilter {
    private final ListMultimap<GitilesView.Type, Filter> filters;
    private final Map<GitilesView.Type, HttpServlet> servlets;

    private DispatchFilter(
        ListMultimap<GitilesView.Type, Filter> filters,
        Map<GitilesView.Type, HttpServlet> servlets) {
      this.filters = LinkedListMultimap.create(filters);
      this.servlets = ImmutableMap.copyOf(servlets);
      for (GitilesView.Type type : GitilesView.Type.values()) {
        checkState(servlets.containsKey(type), "Missing handler for view %s", type);
      }
    }

    @Override
    public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
        throws IOException, ServletException {
      GitilesView view = checkNotNull(ViewFilter.getView(req));
      final Iterator<Filter> itr = filters.get(view.getType()).iterator();
      final HttpServlet servlet = servlets.get(view.getType());
      new FilterChain() {
        @Override
        public void doFilter(ServletRequest req, ServletResponse res)
            throws IOException, ServletException {
          if (itr.hasNext()) {
            itr.next().doFilter(req, res, this);
          } else {
            servlet.service(req, res);
          }
        }
      }.doFilter(req, res);
    }
  }

  private final ListMultimap<GitilesView.Type, Filter> filters = LinkedListMultimap.create();
  private final Map<GitilesView.Type, HttpServlet> servlets = Maps.newHashMap();

  private Config config;
  private Renderer renderer;
  private GitilesUrls urls;
  private Linkifier linkifier;
  private GitilesAccess.Factory accessFactory;
  private RepositoryResolver<HttpServletRequest> resolver;
  private VisibilityCache visibilityCache;
  private TimeCache timeCache;
  private BlameCache blameCache;
  private GitwebRedirectFilter gitwebRedirect;
  private Filter errorHandler;
  private BranchRedirectFilter branchRedirect;
  private boolean initialized;

  GitilesFilter() {}

  GitilesFilter(
      Config config,
      @Nullable Renderer renderer,
      @Nullable GitilesUrls urls,
      @Nullable GitilesAccess.Factory accessFactory,
      @Nullable RepositoryResolver<HttpServletRequest> resolver,
      @Nullable VisibilityCache visibilityCache,
      @Nullable TimeCache timeCache,
      @Nullable BlameCache blameCache,
      @Nullable GitwebRedirectFilter gitwebRedirect,
      @Nullable BranchRedirectFilter branchRedirect,
      @Nullable Filter errorHandler) {
    this.config = checkNotNull(config, "config");
    this.renderer = renderer;
    this.urls = urls;
    this.accessFactory = accessFactory;
    this.visibilityCache = visibilityCache;
    this.timeCache = timeCache;
    this.blameCache = blameCache;
    this.gitwebRedirect = gitwebRedirect;
    if (resolver != null) {
      this.resolver = resolver;
    }
    this.errorHandler = errorHandler;
    this.branchRedirect = branchRedirect;
  }

  @Override
  public synchronized void init(FilterConfig config) throws ServletException {
    super.init(config);
    setDefaultFields(config);

    for (GitilesView.Type type : GitilesView.Type.values()) {
      if (!servlets.containsKey(type)) {
        servlets.put(type, getDefaultHandler(type));
      }
    }

    Filter repositoryFilter = new RepositoryFilter(resolver);
    Filter viewFilter = new ViewFilter(accessFactory, urls, visibilityCache);
    Filter dispatchFilter = new DispatchFilter(filters, servlets);

    ServletBinder root = serveRegex(ROOT_REGEX).through(viewFilter);
    if (gitwebRedirect != null) {
      root.through(gitwebRedirect);
    }
    if (branchRedirect != null) {
      root.through(branchRedirect);
    }
    root.through(dispatchFilter);

    serveRegex(REPO_REGEX)
        .through(repositoryFilter)
        .through(viewFilter)
        .through(branchRedirect)
        .through(dispatchFilter);

    serveRegex(REPO_PATH_REGEX)
        .through(repositoryFilter)
        .through(viewFilter)
        .through(branchRedirect)
        .through(dispatchFilter);

    initialized = true;
  }

  @Override
  protected ServletBinder register(ServletBinder b) {
    b.through(errorHandler);
    return b;
  }

  public synchronized BaseServlet getDefaultHandler(GitilesView.Type view) {
    checkNotInitialized();
    switch (view) {
      case HOST_INDEX:
        return new HostIndexServlet(accessFactory, renderer, urls);
      case REPOSITORY_INDEX:
        return new RepositoryIndexServlet(accessFactory, renderer, timeCache);
      case REFS:
        return new RefServlet(accessFactory, renderer, timeCache);
      case REVISION:
        return new RevisionServlet(accessFactory, renderer, linkifier());
      case SHOW:
      case PATH:
        return new PathServlet(accessFactory, renderer, urls);
      case DIFF:
        return new DiffServlet(accessFactory, renderer, linkifier());
      case LOG:
        return new LogServlet(accessFactory, renderer, linkifier());
      case DESCRIBE:
        return new DescribeServlet(accessFactory);
      case ARCHIVE:
        return new ArchiveServlet(accessFactory);
      case BLAME:
        return new BlameServlet(accessFactory, renderer, blameCache);
      case DOC:
      case ROOTED_DOC:
        return new DocServlet(accessFactory, renderer);
      default:
        throw new IllegalArgumentException("Invalid view type: " + view);
    }
  }

  public synchronized void setRenderer(Renderer renderer) {
    checkNotInitialized();
    this.renderer = checkNotNull(renderer, "renderer");
  }

  synchronized void addFilter(GitilesView.Type view, Filter filter) {
    checkNotInitialized();
    filters.put(checkNotNull(view, "view"), checkNotNull(filter, "filter for %s", view));
  }

  synchronized void setHandler(GitilesView.Type view, HttpServlet handler) {
    checkNotInitialized();
    servlets.put(checkNotNull(view, "view"), checkNotNull(handler, "handler for %s", view));
  }

  private synchronized void checkNotInitialized() {
    checkState(!initialized, "Gitiles already initialized");
  }

  private synchronized Linkifier linkifier() {
    if (linkifier == null) {
      checkState(urls != null, "GitilesUrls not yet set");
      linkifier = new Linkifier(urls, config);
    }
    return linkifier;
  }

  private void setDefaultFields(FilterConfig filterConfig) throws ServletException {
    setDefaultConfig(filterConfig);
    setDefaultRenderer(filterConfig);
    setDefaultUrls();
    setDefaultAccess();
    setDefaultVisibilityCache();
    setDefaultTimeCache();
    setDefaultBlameCache();
    setDefaultGitwebRedirect();
    setDefaultErrorHandler();
  }

  private void setDefaultConfig(FilterConfig filterConfig) throws ServletException {
    if (config == null) {
      try {
        config = GitilesConfig.loadDefault(filterConfig);
      } catch (IOException | ConfigInvalidException e) {
        throw new ServletException(e);
      }
    }
  }

  private void setDefaultRenderer(FilterConfig filterConfig) {
    if (renderer == null) {
      renderer =
          new DefaultRenderer(
              filterConfig.getServletContext().getContextPath() + STATIC_PREFIX,
              Arrays.stream(config.getStringList("gitiles", null, "customTemplates"))
                  .map(fileUrlMapper())
                  .collect(toList()),
              firstNonNull(config.getString("gitiles", null, "siteTitle"), "Gitiles"));
    }
  }

  private void setDefaultUrls() throws ServletException {
    if (urls == null) {
      try {
        urls =
            new DefaultUrls(
                config.getString("gitiles", null, "canonicalHostName"),
                getBaseGitUrl(config),
                config.getString("gitiles", null, "gerritUrl"));
      } catch (UnknownHostException e) {
        throw new ServletException(e);
      }
    }
  }

  private void setDefaultAccess() throws ServletException {
    if (accessFactory == null || resolver == null) {
      String basePath = config.getString("gitiles", null, "basePath");
      if (basePath == null) {
        throw new ServletException("gitiles.basePath not set");
      }
      boolean exportAll = config.getBoolean("gitiles", null, "exportAll", false);

      FileResolver<HttpServletRequest> fileResolver;
      if (resolver == null) {
        fileResolver = new FileResolver<>(new File(basePath), exportAll);
        resolver = fileResolver;
      } else if (resolver instanceof FileResolver) {
        fileResolver = (FileResolver<HttpServletRequest>) resolver;
      } else {
        fileResolver = null;
      }
      if (accessFactory == null) {
        checkState(fileResolver != null, "need a FileResolver when GitilesAccess.Factory not set");
        try {
          accessFactory =
              new DefaultAccess.Factory(
                  new File(basePath), getBaseGitUrl(config), config, fileResolver);
        } catch (IOException e) {
          throw new ServletException(e);
        }
      }
    }
  }

  private void setDefaultVisibilityCache() {
    if (visibilityCache == null) {
      if (config.getSubsections("cache").contains("visibility")) {
        visibilityCache = new VisibilityCache(ConfigUtil.getCacheBuilder(config, "visibility"));
      } else {
        visibilityCache = new VisibilityCache();
      }
    }
  }

  private void setDefaultTimeCache() {
    if (timeCache == null) {
      if (config.getSubsections("cache").contains("tagTime")) {
        timeCache = new TimeCache(ConfigUtil.getCacheBuilder(config, "tagTime"));
      } else {
        timeCache = new TimeCache();
      }
    }
  }

  private void setDefaultBlameCache() {
    if (blameCache == null) {
      if (config.getSubsections("cache").contains("blame")) {
        blameCache = new BlameCacheImpl(ConfigUtil.getCacheBuilder(config, "blame"));
      } else {
        blameCache = new BlameCacheImpl();
      }
    }
  }

  private void setDefaultGitwebRedirect() {
    if (gitwebRedirect == null) {
      if (config.getBoolean("gitiles", null, "redirectGitweb", true)) {
        gitwebRedirect = new GitwebRedirectFilter();
      }
    }
  }

  private void setDefaultErrorHandler() {
    if (errorHandler == null) {
      errorHandler = new DefaultErrorHandlingFilter(renderer);
    }
  }

  private static String getBaseGitUrl(Config config) throws ServletException {
    String baseGitUrl = config.getString("gitiles", null, "baseGitUrl");
    if (baseGitUrl == null) {
      throw new ServletException("gitiles.baseGitUrl not set");
    }
    return baseGitUrl;
  }
}
