// 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 static com.google.gerrit.plugins.checks.testing.CheckerConfigSubject.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;

import com.google.common.collect.ImmutableSortedSet;
import com.google.common.truth.StringSubject;
import com.google.gerrit.entities.Project;
import com.google.gerrit.plugins.checks.CheckerCreation;
import com.google.gerrit.plugins.checks.CheckerQuery;
import com.google.gerrit.plugins.checks.CheckerUpdate;
import com.google.gerrit.plugins.checks.CheckerUuid;
import com.google.gerrit.plugins.checks.api.BlockingCondition;
import com.google.gerrit.plugins.checks.api.CheckerStatus;
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.sql.Timestamp;
import java.util.TimeZone;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
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 CheckerConfigTest {
  private Project.NameKey projectName;
  private Repository repository;
  private TestRepository<?> testRepository;

  private final CheckerUuid checkerUuid = CheckerUuid.parse("test:my-checker");
  private final String checkerName = "My Checker";
  private final Project.NameKey checkerRepository = Project.nameKey("my-repo");
  private final TimeZone timeZone = TimeZone.getTimeZone("America/Los_Angeles");

  @Before
  public void setUp() throws Exception {
    projectName = Project.nameKey("Test Repository");
    repository = new InMemoryRepository(new DfsRepositoryDescription("Test Repository"));
    testRepository = new TestRepository<>(repository);
  }

  @Test
  public void correctCommitMessageForCheckerCreation() throws Exception {
    CheckerCreation checkerCreation =
        getPrefilledCheckerCreationBuilder().setCheckerUuid(checkerUuid).build();
    createChecker(checkerCreation);
    assertThatCommitMessage(checkerUuid).isEqualTo("Create checker");
  }

  @Test
  public void specifiedCheckerUuidIsRespectedForNewChecker() throws Exception {
    CheckerCreation checkerCreation =
        getPrefilledCheckerCreationBuilder().setCheckerUuid(checkerUuid).build();
    createChecker(checkerCreation);

    CheckerConfig checkerConfig = loadChecker(checkerUuid);
    assertThat(checkerConfig).hasUuid(checkerUuid);
    assertThat(checkerConfig).configStringList("uuid").containsExactly("test:my-checker");
  }

  @Test
  public void specifiedCheckerNameIsRespectedForNewChecker() throws Exception {
    CheckerCreation checkerCreation =
        getPrefilledCheckerCreationBuilder().setName(checkerName).build();
    createChecker(checkerCreation);

    CheckerConfig checkerConfig = loadChecker(checkerUuid);
    assertThat(checkerConfig).hasName(checkerName);
    assertThat(checkerConfig).configStringList("name").containsExactly("My Checker");
  }

  @Test
  public void nameOfCheckerUpdateOverridesCheckerCreation() throws Exception {
    String anotherName = "Another Name";

    CheckerCreation checkerCreation =
        getPrefilledCheckerCreationBuilder().setName(checkerName).build();
    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setName(anotherName).build();
    createChecker(checkerCreation, checkerUpdate);

    CheckerConfig checkerConfig = loadChecker(checkerCreation.getCheckerUuid());
    assertThat(checkerConfig).hasName(anotherName);
    assertThat(checkerConfig).configStringList("name").containsExactly(anotherName);
  }

  @Test
  public void nameOfNewCheckerMustNotBeEmpty() throws Exception {
    CheckerCreation checkerCreation =
        getPrefilledCheckerCreationBuilder().setName("").buildWithoutValidationForTesting();
    CheckerConfig checkerConfig =
        CheckerConfig.createForNewChecker(projectName, repository, checkerCreation);

    try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) {
      Throwable thrown = assertThrows(Throwable.class, () -> checkerConfig.commit(metaDataUpdate));
      assertThat(thrown).hasCauseThat().isInstanceOf(ConfigInvalidException.class);
      assertThat(thrown)
          .hasMessageThat()
          .contains(String.format("Name of the checker %s must be defined", checkerUuid));
    }
  }

  @Test
  public void descriptionDefaultsToOptionalEmpty() throws Exception {
    CheckerCreation checkerCreation =
        CheckerCreation.builder()
            .setCheckerUuid(checkerUuid)
            .setName(checkerName)
            .setRepository(checkerRepository)
            .build();
    createChecker(checkerCreation);

    CheckerConfig checkerConfig = loadChecker(checkerCreation.getCheckerUuid());
    assertThat(checkerConfig).hasDescriptionThat().isEmpty();
    assertThat(checkerConfig).configStringList("description").isEmpty();
  }

  @Test
  public void specifiedDescriptionIsRespectedForNewChecker() throws Exception {
    String description = "This is a test checker.";

    CheckerCreation checkerCreation = getPrefilledCheckerCreationBuilder().build();
    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setDescription(description).build();
    createChecker(checkerCreation, checkerUpdate);

    CheckerConfig checkerConfig = loadChecker(checkerCreation.getCheckerUuid());
    assertThat(checkerConfig).hasDescriptionThat().value().isEqualTo(description);
    assertThat(checkerConfig).configStringList("description").containsExactly(description);
  }

  @Test
  public void emptyDescriptionForNewCheckerIsIgnored() throws Exception {
    CheckerCreation checkerCreation = getPrefilledCheckerCreationBuilder().build();
    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setDescription("").build();
    createChecker(checkerCreation, checkerUpdate);

    CheckerConfig checkerConfig = loadChecker(checkerCreation.getCheckerUuid());
    assertThat(checkerConfig).hasDescriptionThat().isEmpty();
    assertThat(checkerConfig).configStringList("description").isEmpty();
  }

  @Test
  public void urlDefaultsToOptionalEmpty() throws Exception {
    CheckerCreation checkerCreation =
        CheckerCreation.builder()
            .setCheckerUuid(checkerUuid)
            .setName(checkerName)
            .setRepository(checkerRepository)
            .build();
    createChecker(checkerCreation);

    CheckerConfig checkerConfig = loadChecker(checkerCreation.getCheckerUuid());
    assertThat(checkerConfig).hasUrlThat().isEmpty();
    assertThat(checkerConfig).configStringList("url").isEmpty();
  }

  @Test
  public void specifiedUrlIsRespectedForNewChecker() throws Exception {
    String url = "http://example.com/my-checker";

    CheckerCreation checkerCreation = getPrefilledCheckerCreationBuilder().build();
    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setUrl(url).build();
    createChecker(checkerCreation, checkerUpdate);

    CheckerConfig checkerConfig = loadChecker(checkerCreation.getCheckerUuid());
    assertThat(checkerConfig).hasUrlThat().value().isEqualTo(url);
    assertThat(checkerConfig).configStringList("url").containsExactly(url);
  }

  @Test
  public void emptyUrlForNewCheckerIsIgnored() throws Exception {
    CheckerCreation checkerCreation = getPrefilledCheckerCreationBuilder().build();
    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setUrl("").build();
    createChecker(checkerCreation, checkerUpdate);

    CheckerConfig checkerConfig = loadChecker(checkerCreation.getCheckerUuid());
    assertThat(checkerConfig).hasUrlThat().isEmpty();
    assertThat(checkerConfig).configStringList("url").isEmpty();
  }

  @Test
  public void specifiedRepositoryIsRespectedForNewChecker() throws Exception {
    CheckerCreation checkerCreation =
        getPrefilledCheckerCreationBuilder().setRepository(checkerRepository).build();
    createChecker(checkerCreation);

    CheckerConfig checkerConfig = loadChecker(checkerCreation.getCheckerUuid());
    assertThat(checkerConfig).hasRepository(checkerRepository);
    assertThat(checkerConfig)
        .configStringList("repository")
        .containsExactly(checkerRepository.get());
  }

  @Test
  public void repositoryOfCheckerUpdateOverridesCheckerCreation() throws Exception {
    Project.NameKey anotherRepository = Project.nameKey("another-repo");

    CheckerCreation checkerCreation =
        getPrefilledCheckerCreationBuilder().setRepository(checkerRepository).build();
    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setRepository(anotherRepository).build();
    createChecker(checkerCreation, checkerUpdate);

    CheckerConfig checkerConfig = loadChecker(checkerCreation.getCheckerUuid());
    assertThat(checkerConfig).hasRepository(anotherRepository);
    assertThat(checkerConfig)
        .configStringList("repository")
        .containsExactly(anotherRepository.get());
  }

  @Test
  public void repositoryOfNewCheckerMustNotBeEmpty() throws Exception {
    CheckerCreation checkerCreation =
        getPrefilledCheckerCreationBuilder()
            .setRepository(Project.nameKey(""))
            .buildWithoutValidationForTesting();
    CheckerConfig checkerConfig =
        CheckerConfig.createForNewChecker(projectName, repository, checkerCreation);

    try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) {
      Throwable thrown = assertThrows(Throwable.class, () -> checkerConfig.commit(metaDataUpdate));
      assertThat(thrown).hasCauseThat().isInstanceOf(ConfigInvalidException.class);
      assertThat(thrown)
          .hasMessageThat()
          .contains(String.format("Repository of the checker %s must be defined", checkerUuid));
    }
  }

  @Test
  public void createdDefaultsToNow() throws Exception {
    // Git timestamps are only precise to the second.
    Timestamp testStart = Timestamp.from(TimeUtil.truncateToSecond(TimeUtil.now()));

    createArbitraryChecker(checkerUuid);
    CheckerConfig checkerConfig = loadChecker(checkerUuid);
    assertThat(checkerConfig).hasCreatedThat().isAtLeast(testStart);
  }

  @Test
  public void uuidInConfigMayNotBeUndefined() throws Exception {
    populateCheckerConfig(checkerUuid, "[checker]");

    ConfigInvalidException thrown =
        assertThrows(ConfigInvalidException.class, () -> loadChecker(checkerUuid));
    assertThat(thrown)
        .hasMessageThat()
        .contains("checker.uuid is not set in config file for checker " + checkerUuid);
  }

  @Test
  public void nameInConfigMayNotBeUndefined() throws Exception {
    populateCheckerConfig(
        checkerUuid,
        "[checker]\n  uuid = "
            + checkerUuid
            + "\n  repository = "
            + checkerRepository
            + "\n  status = ENABLED");

    ConfigInvalidException thrown =
        assertThrows(ConfigInvalidException.class, () -> loadChecker(checkerUuid));
    assertThat(thrown)
        .hasMessageThat()
        .contains("checker.name is not set in config file for checker " + checkerUuid);
  }

  @Test
  public void correctCommitMessageForCheckerUpdate() throws Exception {
    createArbitraryChecker(checkerUuid);
    assertThatCommitMessage(checkerUuid).isEqualTo("Create checker");

    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setDescription("A description.").build();
    updateChecker(checkerUuid, checkerUpdate);
    assertThatCommitMessage(checkerUuid).isEqualTo("Update checker");
  }

  @Test
  public void nameCanBeUpdated() throws Exception {
    CheckerCreation checkerCreation =
        CheckerCreation.builder()
            .setCheckerUuid(checkerUuid)
            .setName(checkerName)
            .setRepository(checkerRepository)
            .build();
    createChecker(checkerCreation);

    CheckerConfig checkerConfig = loadChecker(checkerUuid);
    assertThat(checkerConfig).hasName(checkerName);

    String newName = "New Name";
    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setName(newName).build();
    updateChecker(checkerUuid, checkerUpdate);

    checkerConfig = loadChecker(checkerUuid);
    assertThat(checkerConfig).hasName(newName);
    assertThat(checkerConfig).configStringList("name").containsExactly(newName);
  }

  @Test
  public void nameCannotBeRemoved() throws Exception {
    createArbitraryChecker(checkerUuid);

    CheckerUpdate checkerUpdate =
        CheckerUpdate.builder().setName("").buildWithoutValidationForTesting();

    IOException thrown =
        assertThrows(IOException.class, () -> updateChecker(checkerUuid, checkerUpdate));
    assertThat(thrown)
        .hasMessageThat()
        .contains(String.format("Name of the checker %s must be defined", checkerUuid));
  }

  @Test
  public void descriptionCanBeUpdated() throws Exception {
    createArbitraryChecker(checkerUuid);
    String newDescription = "New description";

    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setDescription(newDescription).build();
    updateChecker(checkerUuid, checkerUpdate);

    CheckerConfig checkerConfig = loadChecker(checkerUuid);
    assertThat(checkerConfig).hasDescriptionThat().value().isEqualTo(newDescription);
    assertThat(checkerConfig).configStringList("description").containsExactly(newDescription);
  }

  @Test
  public void descriptionCanBeRemoved() throws Exception {
    createArbitraryChecker(checkerUuid);

    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setDescription("").build();
    CheckerConfig checkerConfig = updateChecker(checkerUuid, checkerUpdate);
    assertThat(checkerConfig).hasDescriptionThat().isEmpty();
    assertThat(checkerConfig).configStringList("description").isEmpty();
  }

  @Test
  public void urlCanBeUpdated() throws Exception {
    createArbitraryChecker(checkerUuid);
    String newUrl = "http://example.com/my-checker";

    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setUrl(newUrl).build();
    updateChecker(checkerUuid, checkerUpdate);

    CheckerConfig checkerConfig = loadChecker(checkerUuid);
    assertThat(checkerConfig).hasUrlThat().value().isEqualTo(newUrl);
    assertThat(checkerConfig).configStringList("url").containsExactly(newUrl);
  }

  @Test
  public void urlCanBeRemoved() throws Exception {
    createArbitraryChecker(checkerUuid);

    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setUrl("").build();
    CheckerConfig checkerConfig = updateChecker(checkerUuid, checkerUpdate);
    assertThat(checkerConfig).hasUrlThat().isEmpty();
    assertThat(checkerConfig).configStringList("url").isEmpty();
  }

  @Test
  public void repositoryCanBeUpdated() throws Exception {
    CheckerCreation checkerCreation =
        CheckerCreation.builder()
            .setCheckerUuid(checkerUuid)
            .setName(checkerName)
            .setRepository(checkerRepository)
            .build();
    createChecker(checkerCreation);

    Project.NameKey newRepository = Project.nameKey("another-repo");
    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setRepository(newRepository).build();
    updateChecker(checkerUuid, checkerUpdate);

    CheckerConfig checkerConfig = loadChecker(checkerUuid);
    assertThat(checkerConfig).hasRepository(newRepository);
    assertThat(checkerConfig).configStringList("repository").containsExactly(newRepository.get());

    assertThatCommitMessage(checkerUuid).isEqualTo("Update checker");
  }

  @Test
  public void repositoryCannotBeRemoved() throws Exception {
    createArbitraryChecker(checkerUuid);

    CheckerUpdate checkerUpdate =
        CheckerUpdate.builder()
            .setRepository(Project.nameKey(""))
            .buildWithoutValidationForTesting();

    IOException thrown =
        assertThrows(IOException.class, () -> updateChecker(checkerUuid, checkerUpdate));
    assertThat(thrown)
        .hasMessageThat()
        .contains(String.format("Repository of the checker %s must be defined", checkerUuid));
  }

  @Test
  public void createDisabledChecker() throws Exception {
    CheckerCreation checkerCreation = getPrefilledCheckerCreationBuilder().build();
    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setStatus(CheckerStatus.DISABLED).build();
    CheckerConfig checker = createChecker(checkerCreation, checkerUpdate);

    assertThat(checker).hasStatus(CheckerStatus.DISABLED);
    assertThat(checker).configStringList("status").containsExactly("disabled");
    assertThatCommitMessage(checkerUuid).isEqualTo("Create checker");
  }

  @Test
  public void updateStatusToSameStatus() throws Exception {
    CheckerConfig checker = createArbitraryChecker(checkerUuid);
    assertThat(checker).hasStatus(CheckerStatus.ENABLED);
    assertThat(checker).configStringList("status").containsExactly("enabled");

    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setStatus(CheckerStatus.ENABLED).build();
    checker = updateChecker(checkerUuid, checkerUpdate);
    assertThat(checker).hasStatus(CheckerStatus.ENABLED);
    assertThat(checker).configStringList("status").containsExactly("enabled");
  }

  @Test
  public void disableAndReenable() throws Exception {
    createArbitraryChecker(checkerUuid);

    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setStatus(CheckerStatus.DISABLED).build();
    CheckerConfig checker = updateChecker(checkerUuid, checkerUpdate);
    assertThat(checker).hasStatus(CheckerStatus.DISABLED);
    assertThat(checker).configStringList("status").containsExactly("disabled");

    checkerUpdate = CheckerUpdate.builder().setStatus(CheckerStatus.ENABLED).build();
    checker = updateChecker(checkerUuid, checkerUpdate);
    assertThat(checker).hasStatus(CheckerStatus.ENABLED);
    assertThat(checker).configStringList("status").containsExactly("enabled");
  }

  @Test
  public void setBlockingConditions() throws Exception {
    CheckerConfig checker = createArbitraryChecker(checkerUuid);
    assertThat(checker).hasBlockingConditionSetThat().isEmpty();
    assertThat(checker).configStringList("blocking").isEmpty();

    CheckerUpdate checkerUpdate =
        CheckerUpdate.builder()
            .setBlockingConditions(ImmutableSortedSet.of(BlockingCondition.STATE_NOT_PASSING))
            .build();
    checker = updateChecker(checkerUuid, checkerUpdate);
    assertThat(checker)
        .hasBlockingConditionSetThat()
        .containsExactly(BlockingCondition.STATE_NOT_PASSING);
    assertThat(checker).configStringList("blocking").containsExactly("state not passing");

    checkerUpdate = CheckerUpdate.builder().setBlockingConditions(ImmutableSortedSet.of()).build();
    checker = updateChecker(checkerUuid, checkerUpdate);
    assertThat(checker).hasBlockingConditionSetThat().isEmpty();
    assertThat(checker).configStringList("blocking").isEmpty();
  }

  @Test
  public void setBlockingConditionsDuringCreate() throws Exception {
    CheckerCreation checkerCreation = getPrefilledCheckerCreationBuilder().build();
    CheckerUpdate checkerUpdate =
        CheckerUpdate.builder()
            .setBlockingConditions(ImmutableSortedSet.of(BlockingCondition.STATE_NOT_PASSING))
            .build();
    CheckerConfig checker = createChecker(checkerCreation, checkerUpdate);

    assertThat(checker)
        .hasBlockingConditionSetThat()
        .containsExactly(BlockingCondition.STATE_NOT_PASSING);
    assertThat(checker).configStringList("blocking").containsExactly("state not passing");
  }

  @Test
  public void setQuery() throws Exception {
    CheckerConfig checker = createArbitraryChecker(checkerUuid);
    String expectedQuery = "status:open";
    assertThat(checker).hasQuery(expectedQuery);
    // Default query must be a valid query.
    assertThat(CheckerQuery.clean(expectedQuery)).isEqualTo(expectedQuery);

    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setQuery("f:foo").build();
    checker = updateChecker(checkerUuid, checkerUpdate);
    assertThat(checker).hasQuery("f:foo");
    assertThat(checker).configStringList("query").containsExactly("f:foo");

    checkerUpdate = CheckerUpdate.builder().setQuery("").build();
    checker = updateChecker(checkerUuid, checkerUpdate);
    assertThat(checker).hasNoQuery();
    assertThat(checker).configStringList("query").isEmpty();
  }

  @Test
  public void setQueryDuringCreate() throws Exception {
    CheckerCreation checkerCreation = getPrefilledCheckerCreationBuilder().build();
    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setQuery("f:foo").build();
    CheckerConfig checker = createChecker(checkerCreation, checkerUpdate);

    assertThat(checker).hasQuery("f:foo");
    assertThat(checker).configStringList("query").containsExactly("f:foo");
  }

  @Test
  public void setQueryDoesNotValidateQuery() throws Exception {
    String query = "foo:bar";
    assertThrows(ConfigInvalidException.class, () -> CheckerQuery.clean(query));

    createArbitraryChecker(checkerUuid);

    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setQuery("f:foo").build();
    CheckerConfig checker = updateChecker(checkerUuid, checkerUpdate);
    assertThat(checker).hasQuery("f:foo");
    assertThat(checker).configStringList("query").containsExactly("f:foo");
  }

  @Test
  public void refStateIsCorrectlySet() throws Exception {
    CheckerCreation checkerCreation =
        getPrefilledCheckerCreationBuilder().setCheckerUuid(checkerUuid).build();
    CheckerConfig newChecker = createChecker(checkerCreation);
    ObjectId expectedRefStateAfterCreation = getCheckerRefState(checkerUuid);
    assertThat(newChecker).hasRefStateThat().isEqualTo(expectedRefStateAfterCreation);

    CheckerConfig checker = loadChecker(checkerUuid);
    assertThat(checker).hasRefStateThat().isEqualTo(expectedRefStateAfterCreation);

    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setDescription("A description.").build();
    CheckerConfig updatedChecker = updateChecker(checkerUuid, checkerUpdate);
    ObjectId expectedRefStateAfterUpdate = getCheckerRefState(checkerUuid);
    assertThat(expectedRefStateAfterUpdate).isNotEqualTo(expectedRefStateAfterCreation);
    assertThat(updatedChecker).hasRefStateThat().isEqualTo(expectedRefStateAfterUpdate);
  }

  @Test
  public void noNewCommitOnNoOpUpdate() throws Exception {
    CheckerCreation checkerCreation =
        getPrefilledCheckerCreationBuilder().setCheckerUuid(checkerUuid).build();
    createChecker(checkerCreation);
    ObjectId refState = getCheckerRefState(checkerUuid);

    // Setting a description updates the ref.
    CheckerUpdate checkerUpdate = CheckerUpdate.builder().setDescription("A description.").build();
    updateChecker(checkerUuid, checkerUpdate);
    ObjectId refState2 = getCheckerRefState(checkerUuid);
    assertThat(refState2).isNotEqualTo(refState);

    // Setting the same description again is a no-op and the ref is not updated.
    updateChecker(checkerUuid, checkerUpdate);
    assertThat(getCheckerRefState(checkerUuid)).isEqualTo(refState2);
  }

  private CheckerConfig createArbitraryChecker(CheckerUuid checkerUuid) throws Exception {
    CheckerCreation checkerCreation =
        getPrefilledCheckerCreationBuilder().setCheckerUuid(checkerUuid).build();
    return createChecker(checkerCreation);
  }

  private CheckerCreation.Builder getPrefilledCheckerCreationBuilder() {
    return CheckerCreation.builder()
        .setCheckerUuid(checkerUuid)
        .setName(checkerName)
        .setRepository(checkerRepository);
  }

  private CheckerConfig createChecker(CheckerCreation checkerCreation) throws Exception {
    CheckerConfig checkerConfig =
        CheckerConfig.createForNewChecker(projectName, repository, checkerCreation);
    commit(checkerConfig);
    return loadChecker(checkerCreation.getCheckerUuid());
  }

  private CheckerConfig createChecker(CheckerCreation checkerCreation, CheckerUpdate checkerUpdate)
      throws Exception {
    CheckerConfig checkerConfig =
        CheckerConfig.createForNewChecker(projectName, repository, checkerCreation);
    checkerConfig.setCheckerUpdate(checkerUpdate);
    commit(checkerConfig);
    return loadChecker(checkerCreation.getCheckerUuid());
  }

  private CheckerConfig updateChecker(CheckerUuid checkerUuid, CheckerUpdate checkerUpdate)
      throws Exception {
    CheckerConfig checkerConfig =
        CheckerConfig.loadForChecker(projectName, repository, checkerUuid);
    checkerConfig.setCheckerUpdate(checkerUpdate);
    commit(checkerConfig);
    return loadChecker(checkerUuid);
  }

  private CheckerConfig loadChecker(CheckerUuid checkerUuid) throws Exception {
    return CheckerConfig.loadForChecker(projectName, repository, checkerUuid);
  }

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

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

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

  private void populateCheckerConfig(CheckerUuid checkerUuid, String fileContent) throws Exception {
    testRepository
        .branch(checkerUuid.toRefName())
        .commit()
        .message("Prepopulate checker.config")
        .add(CheckerConfig.CHECKER_CONFIG_FILE, fileContent)
        .create();
  }

  private ObjectId getCheckerRefState(CheckerUuid checkerUuid) throws IOException {
    return repository.exactRef(checkerUuid.toRefName()).getObjectId();
  }

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