// 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.truth.Truth.assertThat;

import com.google.common.collect.ImmutableSet;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
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.config.AllUsersNameProvider;
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.util.time.TimeUtil;
import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.InMemoryRepositoryManager;
import com.google.gerrit.testing.TestTimeUtil;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.easymock.EasyMock;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevWalk;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class ProjectResetterTest extends GerritBaseTests {
  private InMemoryRepositoryManager repoManager;
  private Project.NameKey project;
  private Repository repo;

  @Before
  public void setUp() throws Exception {
    repoManager = new InMemoryRepositoryManager();
    project = new Project.NameKey("foo");
    repo = repoManager.createRepository(project);
  }

  @Before
  public void setTimeForTesting() {
    TestTimeUtil.resetWithClockStep(1, TimeUnit.SECONDS);
  }

  @After
  public void resetTime() {
    TestTimeUtil.useSystemTime();
  }

  @Test
  public void resetAllRefs() throws Exception {
    Ref matchingRef = createRef("refs/any/test");

    try (ProjectResetter resetProject =
        builder().build(new ProjectResetter.Config().reset(project))) {
      updateRef(matchingRef);
    }

    // The matching refs are reset to the old state.
    assertRef(matchingRef);
  }

  @Test
  public void onlyResetMatchingRefs() throws Exception {
    Ref matchingRef = createRef("refs/match/test");
    Ref anotherMatchingRef = createRef("refs/another-match/test");
    Ref nonMatchingRef = createRef("refs/no-match/test");

    Ref updatedNonMatchingRef;
    try (ProjectResetter resetProject =
        builder()
            .build(
                new ProjectResetter.Config()
                    .reset(project, "refs/match/*", "refs/another-match/*"))) {
      updateRef(matchingRef);
      updateRef(anotherMatchingRef);
      updatedNonMatchingRef = updateRef(nonMatchingRef);
    }

    // The matching refs are reset to the old state.
    assertRef(matchingRef);
    assertRef(anotherMatchingRef);

    // The non-matching ref is not reset, hence it still has the updated state.
    assertRef(updatedNonMatchingRef);
  }

  @Test
  public void onlyDeleteNewlyCreatedMatchingRefs() throws Exception {
    Ref matchingRef;
    Ref anotherMatchingRef;
    Ref nonMatchingRef;
    try (ProjectResetter resetProject =
        builder()
            .build(
                new ProjectResetter.Config()
                    .reset(project, "refs/match/*", "refs/another-match/*"))) {
      matchingRef = createRef("refs/match/test");
      anotherMatchingRef = createRef("refs/another-match/test");
      nonMatchingRef = createRef("refs/no-match/test");
    }

    // The matching refs are deleted since they didn't exist before.
    assertDeletedRef(matchingRef);
    assertDeletedRef(anotherMatchingRef);

    // The non-matching ref is not deleted.
    assertRef(nonMatchingRef);
  }

  @Test
  public void onlyResetMatchingRefsMultipleProjects() throws Exception {
    Project.NameKey project2 = new Project.NameKey("bar");
    Repository repo2 = repoManager.createRepository(project2);

    Ref matchingRefProject1 = createRef("refs/foo/test");
    Ref nonMatchingRefProject1 = createRef("refs/bar/test");

    Ref matchingRefProject2 = createRef(repo2, "refs/bar/test");
    Ref nonMatchingRefProject2 = createRef(repo2, "refs/foo/test");

    Ref updatedNonMatchingRefProject1;
    Ref updatedNonMatchingRefProject2;
    try (ProjectResetter resetProject =
        builder()
            .build(
                new ProjectResetter.Config()
                    .reset(project, "refs/foo/*")
                    .reset(project2, "refs/bar/*"))) {
      updateRef(matchingRefProject1);
      updatedNonMatchingRefProject1 = updateRef(nonMatchingRefProject1);

      updateRef(repo2, matchingRefProject2);
      updatedNonMatchingRefProject2 = updateRef(repo2, nonMatchingRefProject2);
    }

    // The matching refs are reset to the old state.
    assertRef(matchingRefProject1);
    assertRef(repo2, matchingRefProject2);

    // The non-matching refs are not reset, hence they still has the updated states.
    assertRef(updatedNonMatchingRefProject1);
    assertRef(repo2, updatedNonMatchingRefProject2);
  }

  @Test
  public void onlyDeleteNewlyCreatedMatchingRefsMultipleProjects() throws Exception {
    Project.NameKey project2 = new Project.NameKey("bar");
    Repository repo2 = repoManager.createRepository(project2);

    Ref matchingRefProject1;
    Ref nonMatchingRefProject1;
    Ref matchingRefProject2;
    Ref nonMatchingRefProject2;
    try (ProjectResetter resetProject =
        builder()
            .build(
                new ProjectResetter.Config()
                    .reset(project, "refs/foo/*")
                    .reset(project2, "refs/bar/*"))) {
      matchingRefProject1 = createRef("refs/foo/test");
      nonMatchingRefProject1 = createRef("refs/bar/test");

      matchingRefProject2 = createRef(repo2, "refs/bar/test");
      nonMatchingRefProject2 = createRef(repo2, "refs/foo/test");
    }

    // The matching refs are deleted since they didn't exist before.
    assertDeletedRef(matchingRefProject1);
    assertDeletedRef(repo2, matchingRefProject2);

    // The non-matching ref is not deleted.
    assertRef(nonMatchingRefProject1);
    assertRef(repo2, nonMatchingRefProject2);
  }

  @Test
  public void onlyDeleteNewlyCreatedWithOverlappingRefPatterns() throws Exception {
    Ref matchingRef;
    try (ProjectResetter resetProject =
        builder()
            .build(
                new ProjectResetter.Config().reset(project, "refs/match/*", "refs/match/test"))) {
      // This ref matches 2 ref pattern, ProjectResetter should try to delete it only once.
      matchingRef = createRef("refs/match/test");
    }

    // The matching ref is deleted since it didn't exist before.
    assertDeletedRef(matchingRef);
  }

  @Test
  public void projectEvictionIfRefsMetaConfigIsReset() throws Exception {
    Project.NameKey project2 = new Project.NameKey("bar");
    Repository repo2 = repoManager.createRepository(project2);
    Ref metaConfig = createRef(repo2, RefNames.REFS_CONFIG);

    ProjectCache projectCache = EasyMock.createNiceMock(ProjectCache.class);
    projectCache.evict(project2);
    EasyMock.expectLastCall();
    EasyMock.replay(projectCache);

    Ref nonMetaConfig = createRef("refs/heads/master");

    try (ProjectResetter resetProject =
        builder(null, null, null, null, null, null, projectCache)
            .build(new ProjectResetter.Config().reset(project).reset(project2))) {
      updateRef(nonMetaConfig);
      updateRef(repo2, metaConfig);
    }

    EasyMock.verify(projectCache);
  }

  @Test
  public void projectEvictionIfRefsMetaConfigIsDeleted() throws Exception {
    Project.NameKey project2 = new Project.NameKey("bar");
    Repository repo2 = repoManager.createRepository(project2);

    ProjectCache projectCache = EasyMock.createNiceMock(ProjectCache.class);
    projectCache.evict(project2);
    EasyMock.expectLastCall();
    EasyMock.replay(projectCache);

    try (ProjectResetter resetProject =
        builder(null, null, null, null, null, null, projectCache)
            .build(new ProjectResetter.Config().reset(project).reset(project2))) {
      createRef("refs/heads/master");
      createRef(repo2, RefNames.REFS_CONFIG);
    }

    EasyMock.verify(projectCache);
  }

  @Test
  public void accountEvictionIfUserBranchIsReset() throws Exception {
    Account.Id accountId = new Account.Id(1);
    Project.NameKey allUsers = new Project.NameKey(AllUsersNameProvider.DEFAULT);
    Repository allUsersRepo = repoManager.createRepository(allUsers);
    Ref userBranch = createRef(allUsersRepo, RefNames.refsUsers(accountId));

    AccountCache accountCache = EasyMock.createNiceMock(AccountCache.class);
    accountCache.evict(accountId);
    EasyMock.expectLastCall();
    EasyMock.replay(accountCache);

    AccountIndexer accountIndexer = EasyMock.createNiceMock(AccountIndexer.class);
    accountIndexer.index(accountId);
    EasyMock.expectLastCall();
    EasyMock.replay(accountIndexer);

    // Non-user branch because it's not in All-Users.
    Ref nonUserBranch = createRef(RefNames.refsUsers(new Account.Id(2)));

    try (ProjectResetter resetProject =
        builder(null, accountCache, accountIndexer, null, null, null, null)
            .build(new ProjectResetter.Config().reset(project).reset(allUsers))) {
      updateRef(nonUserBranch);
      updateRef(allUsersRepo, userBranch);
    }

    EasyMock.verify(accountCache, accountIndexer);
  }

  @Test
  public void accountEvictionIfUserBranchIsDeleted() throws Exception {
    Account.Id accountId = new Account.Id(1);
    Project.NameKey allUsers = new Project.NameKey(AllUsersNameProvider.DEFAULT);
    Repository allUsersRepo = repoManager.createRepository(allUsers);

    AccountCache accountCache = EasyMock.createNiceMock(AccountCache.class);
    accountCache.evict(accountId);
    EasyMock.expectLastCall();
    EasyMock.replay(accountCache);

    AccountIndexer accountIndexer = EasyMock.createNiceMock(AccountIndexer.class);
    accountIndexer.index(accountId);
    EasyMock.expectLastCall();
    EasyMock.replay(accountIndexer);

    try (ProjectResetter resetProject =
        builder(null, accountCache, accountIndexer, null, null, null, null)
            .build(new ProjectResetter.Config().reset(project).reset(allUsers))) {
      // Non-user branch because it's not in All-Users.
      createRef(RefNames.refsUsers(new Account.Id(2)));

      createRef(allUsersRepo, RefNames.refsUsers(accountId));
    }

    EasyMock.verify(accountCache, accountIndexer);
  }

  @Test
  public void accountEvictionIfExternalIdsBranchIsReset() throws Exception {
    Account.Id accountId = new Account.Id(1);
    Project.NameKey allUsers = new Project.NameKey(AllUsersNameProvider.DEFAULT);
    Repository allUsersRepo = repoManager.createRepository(allUsers);
    Ref externalIds = createRef(allUsersRepo, RefNames.REFS_EXTERNAL_IDS);
    createRef(allUsersRepo, RefNames.refsUsers(accountId));

    Account.Id accountId2 = new Account.Id(2);

    AccountCache accountCache = EasyMock.createNiceMock(AccountCache.class);
    accountCache.evict(accountId);
    EasyMock.expectLastCall();
    accountCache.evict(accountId2);
    EasyMock.expectLastCall();
    EasyMock.replay(accountCache);

    AccountIndexer accountIndexer = EasyMock.createNiceMock(AccountIndexer.class);
    accountIndexer.index(accountId);
    EasyMock.expectLastCall();
    accountIndexer.index(accountId2);
    EasyMock.expectLastCall();
    EasyMock.replay(accountIndexer);

    // Non-user branch because it's not in All-Users.
    Ref nonUserBranch = createRef(RefNames.refsUsers(new Account.Id(3)));

    try (ProjectResetter resetProject =
        builder(null, accountCache, accountIndexer, null, null, null, null)
            .build(new ProjectResetter.Config().reset(project).reset(allUsers))) {
      updateRef(nonUserBranch);
      updateRef(allUsersRepo, externalIds);
      createRef(allUsersRepo, RefNames.refsUsers(accountId2));
    }

    EasyMock.verify(accountCache, accountIndexer);
  }

  @Test
  public void accountEvictionIfExternalIdsBranchIsDeleted() throws Exception {
    Account.Id accountId = new Account.Id(1);
    Project.NameKey allUsers = new Project.NameKey(AllUsersNameProvider.DEFAULT);
    Repository allUsersRepo = repoManager.createRepository(allUsers);
    createRef(allUsersRepo, RefNames.refsUsers(accountId));

    Account.Id accountId2 = new Account.Id(2);

    AccountCache accountCache = EasyMock.createNiceMock(AccountCache.class);
    accountCache.evict(accountId);
    EasyMock.expectLastCall();
    accountCache.evict(accountId2);
    EasyMock.expectLastCall();
    EasyMock.replay(accountCache);

    AccountIndexer accountIndexer = EasyMock.createNiceMock(AccountIndexer.class);
    accountIndexer.index(accountId);
    EasyMock.expectLastCall();
    accountIndexer.index(accountId2);
    EasyMock.expectLastCall();
    EasyMock.replay(accountIndexer);

    // Non-user branch because it's not in All-Users.
    Ref nonUserBranch = createRef(RefNames.refsUsers(new Account.Id(3)));

    try (ProjectResetter resetProject =
        builder(null, accountCache, accountIndexer, null, null, null, null)
            .build(new ProjectResetter.Config().reset(project).reset(allUsers))) {
      updateRef(nonUserBranch);
      createRef(allUsersRepo, RefNames.REFS_EXTERNAL_IDS);
      createRef(allUsersRepo, RefNames.refsUsers(accountId2));
    }

    EasyMock.verify(accountCache, accountIndexer);
  }

  @Test
  public void accountEvictionFromAccountCreatorIfUserBranchIsDeleted() throws Exception {
    Account.Id accountId = new Account.Id(1);
    Project.NameKey allUsers = new Project.NameKey(AllUsersNameProvider.DEFAULT);
    Repository allUsersRepo = repoManager.createRepository(allUsers);

    AccountCreator accountCreator = EasyMock.createNiceMock(AccountCreator.class);
    accountCreator.evict(ImmutableSet.of(accountId));
    EasyMock.expectLastCall();
    EasyMock.replay(accountCreator);

    try (ProjectResetter resetProject =
        builder(accountCreator, null, null, null, null, null, null)
            .build(new ProjectResetter.Config().reset(project).reset(allUsers))) {
      createRef(allUsersRepo, RefNames.refsUsers(accountId));
    }

    EasyMock.verify(accountCreator);
  }

  @Test
  public void groupEviction() throws Exception {
    AccountGroup.UUID uuid1 = new AccountGroup.UUID("abcd1");
    AccountGroup.UUID uuid2 = new AccountGroup.UUID("abcd2");
    AccountGroup.UUID uuid3 = new AccountGroup.UUID("abcd3");
    Project.NameKey allUsers = new Project.NameKey(AllUsersNameProvider.DEFAULT);
    Repository allUsersRepo = repoManager.createRepository(allUsers);

    GroupCache cache = EasyMock.createNiceMock(GroupCache.class);
    GroupIndexer indexer = EasyMock.createNiceMock(GroupIndexer.class);
    GroupIncludeCache includeCache = EasyMock.createNiceMock(GroupIncludeCache.class);
    cache.evict(uuid2);
    indexer.index(uuid2);
    includeCache.evictParentGroupsOf(uuid2);
    cache.evict(uuid3);
    indexer.index(uuid3);
    includeCache.evictParentGroupsOf(uuid3);
    EasyMock.expectLastCall();

    EasyMock.replay(cache, indexer);

    createRef(allUsersRepo, RefNames.refsGroups(uuid1));
    Ref ref2 = createRef(allUsersRepo, RefNames.refsGroups(uuid2));
    try (ProjectResetter resetProject =
        builder(null, null, null, cache, includeCache, indexer, null)
            .build(new ProjectResetter.Config().reset(project).reset(allUsers))) {
      updateRef(allUsersRepo, ref2);
      createRef(allUsersRepo, RefNames.refsGroups(uuid3));
    }

    EasyMock.verify(cache, indexer);
  }

  private Ref createRef(String ref) throws IOException {
    return createRef(repo, ref);
  }

  private Ref createRef(Repository repo, String ref) throws IOException {
    try (ObjectInserter oi = repo.newObjectInserter();
        RevWalk rw = new RevWalk(repo)) {
      ObjectId emptyCommit = createCommit(repo);
      RefUpdate updateRef = repo.updateRef(ref);
      updateRef.setExpectedOldObjectId(ObjectId.zeroId());
      updateRef.setNewObjectId(emptyCommit);
      assertThat(updateRef.update(rw)).isEqualTo(RefUpdate.Result.NEW);
      return repo.exactRef(ref);
    }
  }

  private Ref updateRef(Ref ref) throws IOException {
    return updateRef(repo, ref);
  }

  private Ref updateRef(Repository repo, Ref ref) throws IOException {
    try (ObjectInserter oi = repo.newObjectInserter();
        RevWalk rw = new RevWalk(repo)) {
      ObjectId emptyCommit = createCommit(repo);
      RefUpdate updateRef = repo.updateRef(ref.getName());
      updateRef.setExpectedOldObjectId(ref.getObjectId());
      updateRef.setNewObjectId(emptyCommit);
      updateRef.setForceUpdate(true);
      assertThat(updateRef.update(rw)).isEqualTo(RefUpdate.Result.FORCED);
      Ref updatedRef = repo.exactRef(ref.getName());
      assertThat(updatedRef.getObjectId()).isNotEqualTo(ref.getObjectId());
      return updatedRef;
    }
  }

  private void assertRef(Ref ref) throws IOException {
    assertRef(repo, ref);
  }

  private void assertRef(Repository repo, Ref ref) throws IOException {
    assertThat(repo.exactRef(ref.getName()).getObjectId()).isEqualTo(ref.getObjectId());
  }

  private void assertDeletedRef(Ref ref) throws IOException {
    assertDeletedRef(repo, ref);
  }

  private void assertDeletedRef(Repository repo, Ref ref) throws IOException {
    assertThat(repo.exactRef(ref.getName())).isNull();
  }

  private ObjectId createCommit(Repository repo) throws IOException {
    try (ObjectInserter oi = repo.newObjectInserter()) {
      PersonIdent ident =
          new PersonIdent(new PersonIdent("Foo Bar", "foo.bar@baz.com"), TimeUtil.nowTs());
      CommitBuilder cb = new CommitBuilder();
      cb.setTreeId(oi.insert(Constants.OBJ_TREE, new byte[] {}));
      cb.setCommitter(ident);
      cb.setAuthor(ident);
      cb.setMessage("Test commit");

      ObjectId commit = oi.insert(cb);
      oi.flush();
      return commit;
    }
  }

  private ProjectResetter.Builder builder() {
    return builder(null, null, null, null, null, null, null);
  }

  private ProjectResetter.Builder builder(
      @Nullable AccountCreator accountCreator,
      @Nullable AccountCache accountCache,
      @Nullable AccountIndexer accountIndexer,
      @Nullable GroupCache groupCache,
      @Nullable GroupIncludeCache groupIncludeCache,
      @Nullable GroupIndexer groupIndexer,
      @Nullable ProjectCache projectCache) {
    return new ProjectResetter.Builder(
        repoManager,
        new AllUsersName(AllUsersNameProvider.DEFAULT),
        accountCreator,
        accountCache,
        accountIndexer,
        groupCache,
        groupIncludeCache,
        groupIndexer,
        projectCache);
  }
}
