// Copyright (C) 2020 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.gerritforge.gerrit.globalrefdb.validation;

import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.LocalDiskRepositoryManager;
import com.google.gerrit.server.git.RepositoryCaseMismatchException;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import java.io.IOException;
import java.util.SortedSet;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Repository;

/**
 * Implements a {@link GitRepositoryManager} interface with the intent of managing repository access
 * and repository creation through instances of {@link SharedRefDbRepository}, which can therefore
 * validate operations on the repository itself against the global refdb
 */
@Singleton
public class SharedRefDbGitRepositoryManager implements GitRepositoryManager {
  /**
   * This value must be used for the named injection binding provided by libModules that want to
   * define refs that should not be validated against the global refdb. For example:
   *
   * <pre>
   *         bind(new TypeLiteral&lt;ImmutableSet&lt;String&gt;&gt;() {})
   *         .annotatedWith(Names.named(SharedRefDbGitRepositoryManager.IGNORED_REFS))
   *         .toInstance(
   *             ImmutableSet.of(
   *                 "refs/foo/bar",
   *                 "refs/foo/baz"));
   * </pre>
   */
  public static final String IGNORED_REFS = "ignored_refs";

  @Inject(optional = true)
  @Named("LocalDiskRepositoryManager")
  private GitRepositoryManager gitRepositoryManager;

  private final LocalDiskRepositoryManager localDiskRepositoryManager;
  private final SharedRefDbRepository.Factory sharedRefDbRepoFactory;

  @Inject(optional = true)
  @Named(IGNORED_REFS)
  private ImmutableSet<String> ignoredRefs = ImmutableSet.of();

  /**
   * Constructs a {@code SharedRefDbGitRepositoryManager} that can create and open Git repositories
   * by wrapping them in a {@code SharedRefDbRepository} object, so that operations on them can be
   * validated against a global refdb
   *
   * @param sharedRefDbRepoFactory a factory providing a {@link SharedRefDbRepository} instance
   * @param localDiskRepositoryManager an instance to manage repositories stored on the local file
   *     system
   */
  @Inject
  public SharedRefDbGitRepositoryManager(
      SharedRefDbRepository.Factory sharedRefDbRepoFactory,
      LocalDiskRepositoryManager localDiskRepositoryManager) {
    this.sharedRefDbRepoFactory = sharedRefDbRepoFactory;
    this.localDiskRepositoryManager = localDiskRepositoryManager;
  }

  /**
   * Get (or open) a {@link Repository} by name.
   *
   * @param name the repository name, relative to the base directory.
   * @return the repository instance
   * @throws RepositoryNotFoundException the name does not denote an existing repository.
   * @throws IOException the name cannot be read as a repository.
   */
  @Override
  public Repository openRepository(Project.NameKey name)
      throws RepositoryNotFoundException, IOException {
    return wrap(name, repositoryManager().openRepository(name));
  }

  /**
   * Create (and open) a {@link Repository} by name.
   *
   * @param name the repository name, relative to the base directory.
   * @return the repository instance
   * @throws RepositoryCaseMismatchException the name collides with an existing repository name, but
   *     only in case of a character within the name.
   * @throws RepositoryNotFoundException the name is invalid.
   * @throws IOException the repository cannot be created.
   */
  @Override
  public Repository createRepository(Project.NameKey name)
      throws RepositoryCaseMismatchException, RepositoryNotFoundException, IOException {
    return wrap(name, repositoryManager().createRepository(name));
  }

  @Override
  public SortedSet<Project.NameKey> list() {
    return repositoryManager().list();
  }

  private Repository wrap(Project.NameKey projectName, Repository projectRepo) {
    return sharedRefDbRepoFactory.create(projectName.get(), projectRepo, ignoredRefs);
  }

  private GitRepositoryManager repositoryManager() {
    return MoreObjects.firstNonNull(gitRepositoryManager, localDiskRepositoryManager);
  }
}
