// Copyright (C) 2013 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.google.gerrit.testing;

import static com.google.common.base.Preconditions.checkState;
import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.ACCOUNTS_UPDATE;
import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.BAN_COMMIT;
import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.BRANCH_MODIFICATION;
import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.CHANGE_MODIFICATION;
import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.DIRECT_PUSH;
import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.GPG_KEYS_MODIFICATION;
import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.GROUPS_UPDATE;
import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.HEAD_MODIFICATION;
import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.INIT_REPO;
import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.MERGE_CHANGE;
import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.OFFLINE_OPERATION;
import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.PLUGIN;
import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.REPO_SEQ;
import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.TAG_MODIFICATION;
import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.VERSIONED_META_DATA_CHANGE;
import static java.util.stream.Collectors.toList;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.Project.NameKey;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.gpg.PublicKeyStore;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.RepositoryCaseMismatchException;
import com.google.gerrit.server.update.context.RefUpdateContext;
import com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType;
import com.google.inject.Inject;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NavigableSet;
import java.util.Optional;
import java.util.function.Predicate;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase;
import org.eclipse.jgit.internal.storage.dfs.DfsReftableBatchRefUpdate;
import org.eclipse.jgit.internal.storage.dfs.DfsRepository;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.ReceiveCommand;

/** Repository manager that uses in-memory repositories. */
public class InMemoryRepositoryManager implements GitRepositoryManager {
  public static InMemoryRepository newRepository(Project.NameKey name) {
    return new Repo(name);
  }

  public static class Description extends DfsRepositoryDescription {
    private final Project.NameKey name;

    private Description(Project.NameKey name) {
      super(name.get());
      this.name = name;
    }

    public Project.NameKey getProject() {
      return name;
    }
  }

  public static class Repo extends InMemoryRepository {
    private String description;

    private Repo(Project.NameKey name) {
      super(new Description(name));
      setPerformsAtomicTransactions(true);
    }

    /** Validates that a given ref is updated within the expected context. */
    private static class RefUpdateContextValidator {
      /**
       * A configured singleton for ref context validation.
       *
       * <p>Each ref must match no more than 1 special ref from the list below. If ref is not
       * matched to any special ref predicate, then it is checked against the standard rules - check
       * the code of the {@link #validateRefUpdateContext} for details.
       */
      public static final RefUpdateContextValidator INSTANCE =
          new RefUpdateContextValidator()
              .addSpecialRef(RefNames::isSequenceRef, REPO_SEQ)
              .addSpecialRef(RefNames.HEAD::equals, HEAD_MODIFICATION)
              .addSpecialRef(RefNames::isRefsChanges, CHANGE_MODIFICATION, MERGE_CHANGE)
              .addSpecialRef(RefNames::isAutoMergeRef, CHANGE_MODIFICATION)
              .addSpecialRef(RefNames::isRefsEdit, CHANGE_MODIFICATION, MERGE_CHANGE)
              .addSpecialRef(RefNames::isTagRef, TAG_MODIFICATION)
              .addSpecialRef(RefNames::isRejectCommitsRef, BAN_COMMIT)
              .addSpecialRef(
                  name -> RefNames.isRefsUsers(name) && !RefNames.isRefsEdit(name),
                  VERSIONED_META_DATA_CHANGE,
                  ACCOUNTS_UPDATE,
                  MERGE_CHANGE)
              .addSpecialRef(
                  RefNames::isConfigRef,
                  VERSIONED_META_DATA_CHANGE,
                  BRANCH_MODIFICATION,
                  MERGE_CHANGE)
              .addSpecialRef(RefNames::isExternalIdRef, VERSIONED_META_DATA_CHANGE, ACCOUNTS_UPDATE)
              .addSpecialRef(PublicKeyStore.REFS_GPG_KEYS::equals, GPG_KEYS_MODIFICATION)
              .addSpecialRef(RefNames::isRefsDraftsComments, CHANGE_MODIFICATION)
              .addSpecialRef(RefNames::isRefsStarredChanges, CHANGE_MODIFICATION)
              // A user can create a change for updating a group and then merge it.
              // The GroupsIT#pushToGroupBranchForReviewForNonAllUsersRepoAndSubmit test verifies
              // this scenario.
              .addSpecialRef(RefNames::isGroupRef, GROUPS_UPDATE, MERGE_CHANGE);

      private List<Entry<Predicate<String>, ImmutableList<RefUpdateType>>> specialRefs =
          new ArrayList<>();

      private RefUpdateContextValidator() {}

      public void validateRefUpdateContext(ReceiveCommand cmd) {
        if (TestActionRefUpdateContext.isOpen()
            || RefUpdateContext.hasOpen(OFFLINE_OPERATION)
            || RefUpdateContext.hasOpen(INIT_REPO)
            || RefUpdateContext.hasOpen(DIRECT_PUSH)) {
          // The action can touch any refs in these contexts.
          return;
        }

        String refName = cmd.getRefName();

        Optional<ImmutableList<RefUpdateType>> allowedRefUpdateTypes =
            RefUpdateContextValidator.INSTANCE.getAllowedRefUpdateTypes(refName);

        if (allowedRefUpdateTypes.isPresent()) {
          checkState(
              allowedRefUpdateTypes.get().stream().anyMatch(RefUpdateContext::hasOpen)
                  || isTestRepoCall(),
              "Special ref '%s' is updated outside of the expected operation. Wrap code in the correct RefUpdateContext or fix allowed update types",
              refName);
          return;
        }
        // It is not one of the special ref - update is possible only within specific contexts.
        checkState(
            RefUpdateContext.hasOpen(MERGE_CHANGE)
                || RefUpdateContext.hasOpen(RefUpdateType.BRANCH_MODIFICATION)
                || RefUpdateContext.hasOpen(RefUpdateType.UPDATE_SUPERPROJECT)
                // Plugin can update any ref
                || RefUpdateContext.hasOpen(PLUGIN)
                || isTestRepoCall(),
            "Ordinary ref '%s' is updated outside of the expected operation. Wrap code in the correct RefUpdateContext or add the ref as a special ref.",
            refName);
      }

      private RefUpdateContextValidator addSpecialRef(
          Predicate<String> refNamePredicate, RefUpdateType... validRefUpdateTypes) {
        specialRefs.add(
            new SimpleImmutableEntry<>(
                refNamePredicate, ImmutableList.copyOf(validRefUpdateTypes)));
        return this;
      }

      private Optional<ImmutableList<RefUpdateType>> getAllowedRefUpdateTypes(String refName) {
        List<ImmutableList<RefUpdateType>> allowedTypes =
            specialRefs.stream()
                .filter(entry -> entry.getKey().test(refName))
                .map(Entry::getValue)
                .collect(toList());
        checkState(
            allowedTypes.size() <= 1,
            "refName matches more than 1 predicate. Please fix the specialRefs list, so each reference has no more than one match.");
        if (allowedTypes.size() == 0) {
          return Optional.empty();
        }
        return Optional.of(allowedTypes.get(0));
      }

      /**
       * Returns true if a ref is updated using one of the method in {@link
       * org.eclipse.jgit.junit.TestRepository}.
       *
       * <p>The {@link org.eclipse.jgit.junit.TestRepository} used only in tests and allows to
       * change refs directly. Wrapping each usage in a test context requires a lot of modification,
       * so instead we allow any ref updates, which are made using through this class.
       */
      private boolean isTestRepoCall() {
        return Arrays.stream(Thread.currentThread().getStackTrace())
            .anyMatch(elem -> elem.getClassName().equals("org.eclipse.jgit.junit.TestRepository"));
      }
    }

    @Override
    protected MemRefDatabase createRefDatabase() {
      return new MemRefDatabase() {
        @Override
        public BatchRefUpdate newBatchUpdate() {
          DfsObjDatabase odb = getRepository().getObjectDatabase();
          return new DfsReftableBatchRefUpdate(this, odb) {
            @Override
            public void execute(RevWalk rw, ProgressMonitor pm, List<String> options) {
              getCommands().stream()
                  .forEach(RefUpdateContextValidator.INSTANCE::validateRefUpdateContext);
              super.execute(rw, pm, options);
            }
          };
        }
      };
    }

    @Override
    public Description getDescription() {
      return (Description) super.getDescription();
    }

    @Override
    public String getGitwebDescription() {
      return description;
    }

    @Override
    public void setGitwebDescription(String d) {
      description = d;
    }
  }

  private final Map<String, Repo> repos;

  @Inject
  public InMemoryRepositoryManager() {
    this.repos = new HashMap<>();
  }

  @Override
  public synchronized Status getRepositoryStatus(NameKey name) {
    try {
      get(name);
      return Status.ACTIVE;
    } catch (RepositoryNotFoundException e) {
      return Status.NON_EXISTENT;
    }
  }

  @Override
  public synchronized Repo openRepository(Project.NameKey name) throws RepositoryNotFoundException {
    return get(name);
  }

  @Override
  public synchronized Repo createRepository(Project.NameKey name)
      throws RepositoryCaseMismatchException, RepositoryNotFoundException {
    Repo repo;
    try {
      repo = get(name);
      if (!repo.getDescription().getRepositoryName().equals(name.get())) {
        throw new RepositoryCaseMismatchException(name);
      }
    } catch (RepositoryNotFoundException e) {
      repo = new Repo(name);
      repos.put(normalize(name), repo);
    }
    return repo;
  }

  @Override
  public synchronized NavigableSet<Project.NameKey> list() {
    NavigableSet<Project.NameKey> names = Sets.newTreeSet();
    for (DfsRepository repo : repos.values()) {
      names.add(Project.nameKey(repo.getDescription().getRepositoryName()));
    }
    return Collections.unmodifiableNavigableSet(names);
  }

  public synchronized void deleteRepository(Project.NameKey name) {
    repos.remove(normalize(name));
  }

  private synchronized Repo get(Project.NameKey name) throws RepositoryNotFoundException {
    Repo repo = repos.get(normalize(name));
    if (repo != null) {
      repo.incrementOpen();
      return repo;
    }
    throw new RepositoryNotFoundException(name.get());
  }

  private static String normalize(Project.NameKey name) {
    return name.get().toLowerCase();
  }
}
