// 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.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 {
  /** @see #create(TestRepository,GitwebRedirectFilter, BranchRedirect) */
  public static GitilesServlet create(final TestRepository<DfsRepository> repo)
      throws ServletException {
    return create(repo, new GitwebRedirectFilter(), new BranchRedirect());
  }

  /** @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 String getInitParameter(String name) {
            return null;
          }

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

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

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

  private TestGitilesServlet() {}
}
