// 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 com.google.common.collect.ImmutableList;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import javax.annotation.Nullable;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.internal.storage.dfs.DfsRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.resolver.RepositoryResolver;

/** Static utility methods for creating {@link GitilesServlet}s for testing. */
public class TestGitilesServlet {
  /** Create GitilesServlet, @see #create(TestRepository,GitwebRedirectFilter, BranchRedirect) */
  public static GitilesServlet create(final TestRepository<DfsRepository> repo)
      throws ServletException {
    return create(repo, new GitwebRedirectFilter(), new BranchRedirect());
  }

  /** Create GitilesServlet, @see #create(TestRepository,GitwebRedirectFilter, BranchRedirect) */
  public static GitilesServlet create(
      final TestRepository<DfsRepository> repo, GitwebRedirectFilter gitwebRedirect)
      throws ServletException {
    return create(repo, gitwebRedirect, new BranchRedirect());
  }

  /**
   * Create a servlet backed by a single test repository.
   *
   * <p>The servlet uses the same filter lists as a real servlet, but only knows about a single
   * repo, having the name returned by {@link
   * org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription#getRepositoryName()}. Pass a
   * {@link FakeHttpServletRequest} and {@link FakeHttpServletResponse} to the servlet's {@code
   * service} method to test.
   *
   * @param repo the test repo backing the servlet.
   * @param gitwebRedirect optional redirect filter for gitweb URLs.
   * @param branchRedirect branch redirect filter
   * @return a servlet.
   */
  public static GitilesServlet create(
      final TestRepository<DfsRepository> repo,
      GitwebRedirectFilter gitwebRedirect,
      BranchRedirect branchRedirect)
      throws ServletException {
    final String repoName = repo.getRepository().getDescription().getRepositoryName();
    GitilesServlet servlet =
        new GitilesServlet(
            new Config(),
            new DefaultRenderer(
                GitilesServlet.STATIC_PREFIX, ImmutableList.<URL>of(), repoName + " test site"),
            TestGitilesUrls.URLS,
            new TestGitilesAccess(repo.getRepository()),
            new RepositoryResolver<HttpServletRequest>() {
              @Override
              public Repository open(HttpServletRequest req, String name)
                  throws RepositoryNotFoundException {
                if (!repoName.equals(name)) {
                  throw new RepositoryNotFoundException(name);
                }
                return repo.getRepository();
              }
            },
            null,
            null,
            null,
            gitwebRedirect,
            branchRedirect);

    servlet.init(
        new ServletConfig() {
          @Override
          public @Nullable String getInitParameter(String name) {
            return null;
          }

          @Override
          public Enumeration<String> getInitParameterNames() {
            return Collections.enumeration(ImmutableList.<String>of());
          }

          @Override
          public @Nullable ServletContext getServletContext() {
            return null;
          }

          @Override
          public String getServletName() {
            return TestGitilesServlet.class.getName();
          }
        });
    return servlet;
  }

  private TestGitilesServlet() {}
}
