// Copyright (C) 2017 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.acceptance;

import static com.google.common.base.Preconditions.checkState;
import static com.google.gerrit.entities.RefNames.REFS_USERS;
import static com.google.gerrit.testing.TestActionRefUpdateContext.testRefAction;
import static java.util.stream.Collectors.toSet;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.MultimapBuilder;
import com.google.common.collect.Sets;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.index.RefState;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.account.GroupIncludeCache;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.index.account.AccountIndexer;
import com.google.gerrit.server.index.group.GroupIndexer;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.RefPatternMatcher;
import com.google.inject.Inject;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Stream;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;

/**
 * Saves the states of given projects and resets the project states on close.
 *
 * <p>Saving the project states is done by saving the states of all refs in the project. On close
 * those refs are reset to the saved states. Refs that were newly created are deleted.
 *
 * <p>By providing ref patterns per project it can be controlled which refs should be reset on
 * close.
 *
 * <p>If resetting touches {@code refs/meta/config} branches the corresponding projects are evicted
 * from the project cache.
 *
 * <p>If resetting touches user branches or the {@code refs/meta/external-ids} branch the
 * corresponding accounts are evicted from the account cache and also if needed from the cache in
 * {@link AccountCreator}.
 *
 * <p>At the moment this class has the following limitations:
 *
 * <ul>
 *   <li>Resetting group branches doesn't evict the corresponding groups from the group cache.
 *   <li>Changes are not reindexed if change meta refs are reset.
 *   <li>Changes are not reindexed if starred-changes refs in All-Users are reset.
 *   <li>If accounts are deleted changes may still refer to these accounts (e.g. as reviewers).
 * </ul>
 *
 * Primarily this class is intended to reset the states of the All-Projects and All-Users projects
 * after each test. These projects rarely contain changes and it's currently not a problem if these
 * changes get stale. For creating changes each test gets a brand new project. Since this project is
 * not used outside of the test method that creates it, it doesn't need to be reset.
 */
public class ProjectResetter implements AutoCloseable {
  public static class Builder {
    public interface Factory {
      Builder builder();
    }

    private final GitRepositoryManager repoManager;
    private final AllUsersName allUsersName;
    @Nullable private final AccountCreator accountCreator;
    @Nullable private final AccountCache accountCache;
    @Nullable private final AccountIndexer accountIndexer;
    @Nullable private final GroupCache groupCache;
    @Nullable private final GroupIncludeCache groupIncludeCache;
    @Nullable private final GroupIndexer groupIndexer;
    @Nullable private final ProjectCache projectCache;

    @Inject
    public Builder(
        GitRepositoryManager repoManager,
        AllUsersName allUsersName,
        @Nullable AccountCreator accountCreator,
        @Nullable AccountCache accountCache,
        @Nullable AccountIndexer accountIndexer,
        @Nullable GroupCache groupCache,
        @Nullable GroupIncludeCache groupIncludeCache,
        @Nullable GroupIndexer groupIndexer,
        @Nullable ProjectCache projectCache) {
      this.repoManager = repoManager;
      this.allUsersName = allUsersName;
      this.accountCreator = accountCreator;
      this.accountCache = accountCache;
      this.accountIndexer = accountIndexer;
      this.groupCache = groupCache;
      this.groupIncludeCache = groupIncludeCache;
      this.groupIndexer = groupIndexer;
      this.projectCache = projectCache;
    }

    public ProjectResetter build(ProjectResetter.Config input) throws IOException {
      return new ProjectResetter(
          repoManager,
          allUsersName,
          accountCreator,
          accountCache,
          accountIndexer,
          groupCache,
          groupIncludeCache,
          groupIndexer,
          projectCache,
          input.refsByProject);
    }
  }

  public static class Config {
    private final ImmutableMultimap<Project.NameKey, String> refsByProject;

    private Config(ImmutableMultimap<Project.NameKey, String> refsByProject) {
      this.refsByProject = refsByProject;
    }

    public Builder toBuilder() {
      Builder builder = new Builder();
      builder.refsByProject.putAll(refsByProject);
      return builder;
    }

    public static class Builder {
      private final ListMultimap<Project.NameKey, String> refsByProject;

      public Builder() {
        this.refsByProject = MultimapBuilder.hashKeys().arrayListValues().build();
      }

      public Builder reset(Project.NameKey project, String... refPatterns) {
        List<String> refPatternList = Arrays.asList(refPatterns);
        if (refPatternList.isEmpty()) {
          refPatternList = ImmutableList.of(RefNames.REFS + "*");
        }
        refsByProject.putAll(project, refPatternList);
        return this;
      }

      public Config build() {
        return new Config(ImmutableMultimap.copyOf(refsByProject));
      }
    }
  }

  @Inject private GitRepositoryManager repoManager;
  @Inject private AllUsersName allUsersName;
  @Inject @Nullable private AccountCreator accountCreator;
  @Inject @Nullable private AccountCache accountCache;
  @Inject @Nullable private GroupCache groupCache;
  @Inject @Nullable private GroupIncludeCache groupIncludeCache;
  @Inject @Nullable private GroupIndexer groupIndexer;
  @Inject @Nullable private AccountIndexer accountIndexer;
  @Inject @Nullable private ProjectCache projectCache;

  private final Multimap<Project.NameKey, String> refsPatternByProject;

  // State to which to reset to.
  private final ListMultimap<Project.NameKey, RefState> savedRefStatesByProject;

  // Results of the resetting
  private ListMultimap<Project.NameKey, String> keptRefsByProject;
  private ListMultimap<Project.NameKey, String> restoredRefsByProject;
  private ListMultimap<Project.NameKey, String> deletedRefsByProject;

  private ProjectResetter(
      GitRepositoryManager repoManager,
      AllUsersName allUsersName,
      @Nullable AccountCreator accountCreator,
      @Nullable AccountCache accountCache,
      @Nullable AccountIndexer accountIndexer,
      @Nullable GroupCache groupCache,
      @Nullable GroupIncludeCache groupIncludeCache,
      @Nullable GroupIndexer groupIndexer,
      @Nullable ProjectCache projectCache,
      Multimap<Project.NameKey, String> refPatternByProject)
      throws IOException {
    this.repoManager = repoManager;
    this.allUsersName = allUsersName;
    this.accountCreator = accountCreator;
    this.accountCache = accountCache;
    this.accountIndexer = accountIndexer;
    this.groupCache = groupCache;
    this.groupIndexer = groupIndexer;
    this.groupIncludeCache = groupIncludeCache;
    this.projectCache = projectCache;
    this.refsPatternByProject = refPatternByProject;
    this.savedRefStatesByProject = readRefStates();
  }

  @Override
  public void close() throws Exception {
    keptRefsByProject = MultimapBuilder.hashKeys().arrayListValues().build();
    restoredRefsByProject = MultimapBuilder.hashKeys().arrayListValues().build();
    deletedRefsByProject = MultimapBuilder.hashKeys().arrayListValues().build();
    testRefAction(
        () -> {
          restoreRefs();
          deleteNewlyCreatedRefs();
          evictCachesAndReindex();
        });
  }

  /** Read the states of all matching refs. */
  private ListMultimap<Project.NameKey, RefState> readRefStates() throws IOException {
    ListMultimap<Project.NameKey, RefState> refStatesByProject =
        MultimapBuilder.hashKeys().arrayListValues().build();
    for (Map.Entry<Project.NameKey, Collection<String>> e :
        refsPatternByProject.asMap().entrySet()) {
      try (Repository repo = repoManager.openRepository(e.getKey())) {
        List<Ref> refs = repo.getRefDatabase().getRefs();
        for (String refPattern : e.getValue()) {
          RefPatternMatcher matcher = RefPatternMatcher.getMatcher(refPattern);
          for (Ref ref : refs) {
            if (matcher.match(ref.getName(), null)) {
              refStatesByProject.put(e.getKey(), RefState.create(ref.getName(), ref.getObjectId()));
            }
          }
        }
      }
    }
    return refStatesByProject;
  }

  private void restoreRefs() throws IOException {
    for (Map.Entry<Project.NameKey, Collection<RefState>> e :
        savedRefStatesByProject.asMap().entrySet()) {
      try (Repository repo = repoManager.openRepository(e.getKey())) {
        for (RefState refState : e.getValue()) {
          if (refState.match(repo)) {
            keptRefsByProject.put(e.getKey(), refState.ref());
            continue;
          }
          Ref ref = repo.exactRef(refState.ref());
          RefUpdate updateRef = repo.updateRef(refState.ref());
          updateRef.setExpectedOldObjectId(ref != null ? ref.getObjectId() : ObjectId.zeroId());
          updateRef.setNewObjectId(refState.id());
          updateRef.setForceUpdate(true);
          RefUpdate.Result result = updateRef.update();
          checkState(
              result == RefUpdate.Result.FORCED || result == RefUpdate.Result.NEW,
              "resetting branch %s in %s failed",
              refState.ref(),
              e.getKey());
          restoredRefsByProject.put(e.getKey(), refState.ref());
        }
      }
    }
  }

  private void deleteNewlyCreatedRefs() throws IOException {
    for (Map.Entry<Project.NameKey, Collection<String>> e :
        refsPatternByProject.asMap().entrySet()) {
      try (Repository repo = repoManager.openRepository(e.getKey())) {
        Set<Ref> nonRestoredRefs =
            repo.getRefDatabase().getRefs().stream()
                .filter(
                    r ->
                        !keptRefsByProject.containsEntry(e.getKey(), r.getName())
                            && !restoredRefsByProject.containsEntry(e.getKey(), r.getName()))
                .collect(toSet());
        for (String refPattern : e.getValue()) {
          RefPatternMatcher matcher = RefPatternMatcher.getMatcher(refPattern);
          for (Ref ref : nonRestoredRefs) {
            if (matcher.match(ref.getName(), null)
                && !deletedRefsByProject.containsEntry(e.getKey(), ref.getName())) {
              RefUpdate updateRef = repo.updateRef(ref.getName());
              updateRef.setExpectedOldObjectId(ref.getObjectId());
              updateRef.setNewObjectId(ObjectId.zeroId());
              updateRef.setForceUpdate(true);
              RefUpdate.Result result = updateRef.delete();
              checkState(
                  result == RefUpdate.Result.FORCED,
                  "deleting branch %s in %s failed",
                  ref.getName(),
                  e.getKey());
              deletedRefsByProject.put(e.getKey(), ref.getName());
            }
          }
        }
      }
    }
  }

  private void evictCachesAndReindex() throws IOException {
    evictAndReindexProjects();
    evictAndReindexAccounts();
    evictAndReindexGroups();

    // TODO(ekempin): Reindex changes if starred-changes refs in All-Users were modified.
  }

  /** Evict projects for which the config was changed. */
  private void evictAndReindexProjects() {
    if (projectCache == null) {
      return;
    }

    for (Project.NameKey project :
        Sets.union(
            projectsWithConfigChanges(restoredRefsByProject),
            projectsWithConfigChanges(deletedRefsByProject))) {
      projectCache.evictAndReindex(project);
    }
  }

  private Set<Project.NameKey> projectsWithConfigChanges(
      Multimap<Project.NameKey, String> projects) {
    return projects.entries().stream()
        .filter(e -> e.getValue().equals(RefNames.REFS_CONFIG))
        .map(Map.Entry::getKey)
        .collect(toSet());
  }

  /** Evict accounts that were modified. */
  private void evictAndReindexAccounts() throws IOException {
    Set<Account.Id> deletedAccounts = accountIds(deletedRefsByProject.get(allUsersName).stream());
    if (accountCreator != null) {
      accountCreator.evict(deletedAccounts);
    }
    if (accountCache != null || accountIndexer != null) {
      Set<Account.Id> modifiedAccounts =
          new HashSet<>(accountIds(restoredRefsByProject.get(allUsersName).stream()));

      if (restoredRefsByProject.get(allUsersName).contains(RefNames.REFS_EXTERNAL_IDS)
          || deletedRefsByProject.get(allUsersName).contains(RefNames.REFS_EXTERNAL_IDS)) {
        // The external IDs have been modified but we don't know which accounts were affected.
        // Make sure all accounts are evicted and reindexed.
        try (Repository repo = repoManager.openRepository(allUsersName)) {
          for (Account.Id id : accountIds(repo)) {
            reindexAccount(id);
          }
        }

        // Remove deleted accounts from the cache and index.
        for (Account.Id id : deletedAccounts) {
          reindexAccount(id);
        }
      } else {
        // Evict and reindex all modified and deleted accounts.
        for (Account.Id id : Sets.union(modifiedAccounts, deletedAccounts)) {
          reindexAccount(id);
        }
      }
    }
  }

  /** Evict groups that were modified. */
  private void evictAndReindexGroups() {
    if (groupCache != null || groupIndexer != null) {
      Set<AccountGroup.UUID> modifiedGroups =
          new HashSet<>(groupUUIDs(restoredRefsByProject.get(allUsersName)));
      Set<AccountGroup.UUID> deletedGroups =
          new HashSet<>(groupUUIDs(deletedRefsByProject.get(allUsersName)));

      // Evict and reindex all modified and deleted groups.
      for (AccountGroup.UUID uuid : Sets.union(modifiedGroups, deletedGroups)) {
        evictAndReindexGroup(uuid);
      }
    }
  }

  private void reindexAccount(Account.Id accountId) {
    if (groupIncludeCache != null) {
      groupIncludeCache.evictGroupsWithMember(accountId);
    }
    if (accountIndexer != null) {
      accountIndexer.index(accountId);
    }
  }

  private void evictAndReindexGroup(AccountGroup.UUID uuid) {
    if (groupCache != null) {
      groupCache.evict(uuid);
    }

    if (groupIncludeCache != null) {
      groupIncludeCache.evictParentGroupsOf(uuid);
    }

    if (groupIndexer != null) {
      groupIndexer.index(uuid);
    }
  }

  private static Set<Account.Id> accountIds(Repository repo) throws IOException {
    return accountIds(repo.getRefDatabase().getRefsByPrefix(REFS_USERS).stream().map(Ref::getName));
  }

  private static Set<Account.Id> accountIds(Stream<String> refs) {
    return refs.filter(r -> r.startsWith(REFS_USERS))
        .map(Account.Id::fromRef)
        .filter(Objects::nonNull)
        .collect(toSet());
  }

  private Set<AccountGroup.UUID> groupUUIDs(Collection<String> refs) {
    return refs.stream()
        .filter(RefNames::isRefsGroups)
        .map(AccountGroup.UUID::fromRef)
        .filter(Objects::nonNull)
        .collect(toSet());
  }
}
