// Copyright (C) 2019 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.plugins.checks.db;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;

import com.google.common.truth.StringSubject;
import com.google.gerrit.plugins.checks.CheckerRef;
import com.google.gerrit.plugins.checks.CheckerUuid;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.util.time.TimeUtil;
import java.io.IOException;
import java.util.TimeZone;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.junit.Before;
import org.junit.Test;

public class CheckersByRepositoryNotesTest {
  private final TimeZone timeZone = TimeZone.getTimeZone("America/Los_Angeles");

  private AllProjectsName projectName;
  private Repository repository;

  @Before
  public void setUp() throws Exception {
    projectName = new AllProjectsName("Test Repository");
    repository = new InMemoryRepository(new DfsRepositoryDescription("Test Repository"));
  }

  @Test
  public void getEmptyCheckersList() throws Exception {
    CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();
    assertThat(checkersByRepositoryNotes.get(Project.nameKey("some-project"))).isEmpty();
  }

  @Test
  public void insertCheckers() throws Exception {
    CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();

    Project.NameKey project1 = Project.nameKey("some-project");
    Project.NameKey project2 = Project.nameKey("other-project");

    CheckerUuid checkerUuid1 = CheckerUuid.parse("foo:bar");
    checkersByRepositoryNotes.insert(checkerUuid1, project1);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project1)).containsExactly(checkerUuid1);
    assertThat(checkersByRepositoryNotes.get(project2)).isEmpty();

    CheckerUuid checkerUuid2 = CheckerUuid.parse("foo:baz");
    checkersByRepositoryNotes.insert(checkerUuid2, project1);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project1))
        .containsExactly(checkerUuid1, checkerUuid2)
        .inOrder();
    assertThat(checkersByRepositoryNotes.get(project2)).isEmpty();

    CheckerUuid checkerUuid3 = CheckerUuid.parse("bar:baz");
    checkersByRepositoryNotes.insert(checkerUuid3, project2);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project1))
        .containsExactly(checkerUuid1, checkerUuid2)
        .inOrder();
    assertThat(checkersByRepositoryNotes.get(project2)).containsExactly(checkerUuid3);
  }

  @Test
  public void insertCheckerTwice() throws Exception {
    CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();

    CheckerUuid checkerUuid = CheckerUuid.parse("foo:bar");
    Project.NameKey project = Project.nameKey("some-project");

    checkersByRepositoryNotes.insert(checkerUuid, project);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project)).containsExactly(checkerUuid);

    ObjectId commitId = getRefsMetaCheckersState();
    checkersByRepositoryNotes.insert(checkerUuid, project);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project)).containsExactly(checkerUuid);
    assertThat(getRefsMetaCheckersState()).isEqualTo(commitId);
  }

  @Test
  public void removeCheckers() throws Exception {
    CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();

    Project.NameKey project = Project.nameKey("some-project");

    CheckerUuid checkerUuid1 = CheckerUuid.parse("bar:baz");
    CheckerUuid checkerUuid2 = CheckerUuid.parse("foo:bar");
    CheckerUuid checkerUuid3 = CheckerUuid.parse("foo:baz");

    checkersByRepositoryNotes.insert(checkerUuid1, project);
    checkersByRepositoryNotes.insert(checkerUuid2, project);
    checkersByRepositoryNotes.insert(checkerUuid3, project);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project))
        .containsExactly(checkerUuid1, checkerUuid2, checkerUuid3)
        .inOrder();

    checkersByRepositoryNotes.remove(checkerUuid2, project);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project))
        .containsExactly(checkerUuid1, checkerUuid3)
        .inOrder();

    checkersByRepositoryNotes.remove(checkerUuid1, project);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project)).containsExactly(checkerUuid3).inOrder();

    checkersByRepositoryNotes.remove(checkerUuid3, project);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project)).isEmpty();
  }

  @Test
  public void removeNonExistingChecker() throws Exception {
    CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();

    Project.NameKey project1 = Project.nameKey("some-project");
    Project.NameKey project2 = Project.nameKey("other-project");

    CheckerUuid checkerUuid1 = CheckerUuid.parse("foo:bar");
    CheckerUuid checkerUuid2 = CheckerUuid.parse("foo:baz");

    checkersByRepositoryNotes.insert(checkerUuid1, project1);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project1)).containsExactly(checkerUuid1);
    assertThat(checkersByRepositoryNotes.get(project2)).isEmpty();

    ObjectId commitId = getRefsMetaCheckersState();
    checkersByRepositoryNotes.remove(checkerUuid2, project1);
    checkersByRepositoryNotes.remove(checkerUuid1, project2);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project1)).containsExactly(checkerUuid1);
    assertThat(checkersByRepositoryNotes.get(project2)).isEmpty();
    assertThat(getRefsMetaCheckersState()).isEqualTo(commitId);
  }

  @Test
  public void updateCheckers() throws Exception {
    CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();

    Project.NameKey project1 = Project.nameKey("some-project");
    Project.NameKey project2 = Project.nameKey("other-project");

    CheckerUuid checkerUuid1 = CheckerUuid.parse("foo:bar");
    CheckerUuid checkerUuid2 = CheckerUuid.parse("foo:baz");

    checkersByRepositoryNotes.insert(checkerUuid1, project1);
    checkersByRepositoryNotes.insert(checkerUuid2, project1);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project1))
        .containsExactly(checkerUuid1, checkerUuid2)
        .inOrder();
    assertThat(checkersByRepositoryNotes.get(project2)).isEmpty();

    checkersByRepositoryNotes.update(checkerUuid1, project1, project2);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project1)).containsExactly(checkerUuid2);
    assertThat(checkersByRepositoryNotes.get(project2)).containsExactly(checkerUuid1);

    checkersByRepositoryNotes.update(checkerUuid2, project1, project2);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project1)).isEmpty();
    assertThat(checkersByRepositoryNotes.get(project2))
        .containsExactly(checkerUuid1, checkerUuid2)
        .inOrder();
  }

  @Test
  public void sortOrder() throws Exception {
    CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();

    Project.NameKey project = Project.nameKey("some-project");

    CheckerUuid checkerUuid1 = CheckerUuid.parse("foo:bar");
    CheckerUuid checkerUuid2 = CheckerUuid.parse("foo:baz");
    checkersByRepositoryNotes.insert(checkerUuid1, project);
    checkersByRepositoryNotes.insert(checkerUuid2, project);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project))
        .containsExactly(checkerUuid1, checkerUuid2)
        .inOrder();

    CheckerUuid checkerUuid3 = CheckerUuid.parse("abc:xyz");
    CheckerUuid checkerUuid4 = CheckerUuid.parse("xyz:abc");

    checkersByRepositoryNotes.insert(checkerUuid3, project);
    checkersByRepositoryNotes.insert(checkerUuid4, project);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project))
        .containsExactly(checkerUuid3, checkerUuid1, checkerUuid2, checkerUuid4)
        .inOrder();
  }

  @Test
  public void commitMessage() throws Exception {
    CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();

    CheckerUuid checkerUuid = CheckerUuid.parse("foo:bar");
    Project.NameKey project = Project.nameKey("some-project");

    checkersByRepositoryNotes.insert(checkerUuid, project);
    commit(checkersByRepositoryNotes);
    assertThatCommitMessage()
        .isEqualTo(
            "Update checkers by repository\n\nChecker: "
                + checkerUuid.toString()
                + "\nRepository: "
                + project.get());
  }

  @Test
  public void noOpUpdate() throws Exception {
    CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();

    Project.NameKey project = Project.nameKey("some-project");

    CheckerUuid checkerUuid1 = CheckerUuid.parse("foo:bar");
    checkersByRepositoryNotes.insert(checkerUuid1, project);
    commit(checkersByRepositoryNotes);

    ObjectId commitId = getRefsMetaCheckersState();

    // Set the repository of the checker to the same value that it currently has.
    checkersByRepositoryNotes.update(checkerUuid1, project, project);
    commit(checkersByRepositoryNotes);
    assertThat(getRefsMetaCheckersState()).isEqualTo(commitId);

    // Insert a new checker and remove it before commit.
    CheckerUuid checkerUuid2 = CheckerUuid.parse("foo:baz");
    checkersByRepositoryNotes.insert(checkerUuid2, project);
    checkersByRepositoryNotes.remove(checkerUuid2, project);
    commit(checkersByRepositoryNotes);
    assertThat(getRefsMetaCheckersState()).isEqualTo(commitId);
  }

  @Test
  public void getCheckersFromOldRevision() throws Exception {
    CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();

    Project.NameKey project = Project.nameKey("some-project");

    CheckerUuid checkerUuid1 = CheckerUuid.parse("foo:bar");
    checkersByRepositoryNotes.insert(checkerUuid1, project);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project)).containsExactly(checkerUuid1);

    ObjectId oldRevision = getRefsMetaCheckersState();

    CheckerUuid checkerUuid2 = CheckerUuid.parse("foo:baz");
    checkersByRepositoryNotes.insert(checkerUuid2, project);
    commit(checkersByRepositoryNotes);
    assertThat(checkersByRepositoryNotes.get(project))
        .containsExactly(checkerUuid1, checkerUuid2)
        .inOrder();

    assertThat(CheckersByRepositoryNotes.load(projectName, repository, oldRevision).get(project))
        .containsExactly(checkerUuid1);
  }

  @Test
  public void getCheckersFromZeroIdRevision() throws Exception {
    assertThat(
            CheckersByRepositoryNotes.load(projectName, repository, ObjectId.zeroId())
                .get(Project.nameKey("some-project")))
        .isEmpty();
  }

  @Test
  public void getCheckersFromNullRevision() throws Exception {
    assertThat(
            CheckersByRepositoryNotes.load(projectName, repository, null)
                .get(Project.nameKey("some-project")))
        .isEmpty();
  }

  private CheckersByRepositoryNotes loadCheckersByRepositoryNotes() throws IOException {
    return CheckersByRepositoryNotes.load(projectName, repository);
  }

  private void commit(CheckersByRepositoryNotes checkersByRepositoryNotes) throws IOException {
    try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) {
      checkersByRepositoryNotes.commit(metaDataUpdate);
    }
  }

  private MetaDataUpdate createMetaDataUpdate() {
    PersonIdent serverIdent =
        new PersonIdent(
            "Gerrit Server", "noreply@gerritcodereview.com", TimeUtil.nowTs(), timeZone);

    MetaDataUpdate metaDataUpdate =
        new MetaDataUpdate(
            GitReferenceUpdated.DISABLED, Project.nameKey("Test Repository"), repository);
    metaDataUpdate.getCommitBuilder().setCommitter(serverIdent);
    metaDataUpdate.getCommitBuilder().setAuthor(serverIdent);
    return metaDataUpdate;
  }

  private ObjectId getRefsMetaCheckersState() throws IOException {
    return repository.exactRef(CheckerRef.REFS_META_CHECKERS).getObjectId();
  }

  private StringSubject assertThatCommitMessage() throws IOException {
    try (RevWalk rw = new RevWalk(repository)) {
      RevCommit commit = rw.parseCommit(getRefsMetaCheckersState());
      return assertWithMessage("commit message").that(commit.getFullMessage());
    }
  }
}
