// 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.acceptance.testsuite;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
import static org.hamcrest.CoreMatchers.instanceOf;

import com.google.common.collect.ImmutableMap;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.plugins.checks.Check;
import com.google.gerrit.plugins.checks.CheckKey;
import com.google.gerrit.plugins.checks.CheckerRef;
import com.google.gerrit.plugins.checks.CheckerUuid;
import com.google.gerrit.plugins.checks.acceptance.AbstractCheckersTest;
import com.google.gerrit.plugins.checks.api.CheckInfo;
import com.google.gerrit.plugins.checks.api.CheckInput;
import com.google.gerrit.plugins.checks.api.CheckState;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RevId;
import com.google.gerrit.server.util.time.TimeUtil;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.Optional;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.notes.NoteMap;
import org.eclipse.jgit.revwalk.RevWalk;
import org.junit.Before;
import org.junit.Test;

public class CheckOperationsImplTest extends AbstractCheckersTest {
  // Use specific subclass instead of depending on the interface field from the base class.
  @SuppressWarnings("hiding")
  private CheckOperationsImpl checkOperations;

  @Before
  public void setUp() {
    checkOperations = plugin.getSysInjector().getInstance(CheckOperationsImpl.class);
  }

  @Test
  public void checkCanBeCreatedWithSpecifyingKeyOnly() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).upsert();

    CheckInfo foundCheck = getCheckFromServer(checkKey);
    assertThat(foundCheck.repository).isEqualTo(project.get());
    assertThat(foundCheck.changeNumber).isEqualTo(checkKey.patchSet().changeId().get());
    assertThat(foundCheck.patchSetId).isEqualTo(checkKey.patchSet().get());
    assertThat(foundCheck.checkerUuid).isEqualTo(checkerUuid.get());
    assertThat(foundCheck.state).isNotNull();
    assertThat(foundCheck.message).isNull();
    assertThat(foundCheck.url).isNull();
    assertThat(foundCheck.started).isNull();
    assertThat(foundCheck.finished).isNull();
    assertThat(foundCheck.created).isNotNull();
    assertThat(foundCheck.updated).isNotNull();
    assertThat(foundCheck.checkerName).isNull();
    assertThat(foundCheck.checkerStatus).isNull();
    assertThat(foundCheck.blocking).isNull();
  }

  @Test
  public void checkCannotBeCreatedForNonExistingRepo() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().create();
    CheckKey checkKey =
        CheckKey.create(
            new Project.NameKey("non-existing"), createChange().getPatchSetId(), checkerUuid);

    exception.expect(IllegalStateException.class);
    exception.expectCause(instanceOf(RepositoryNotFoundException.class));
    checkOperations.newCheck(checkKey).upsert();
  }

  @Test
  public void checkCannotBeCreatedForNonExistingPatchSet() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().create();
    CheckKey checkKey = CheckKey.create(project, PatchSet.id(new Change.Id(1), 1), checkerUuid);

    exception.expect(IllegalStateException.class);
    exception.expectCause(instanceOf(IOException.class));
    exception.expectMessage("patchset 1,1 not found");
    checkOperations.newCheck(checkKey).upsert();
  }

  @Test
  public void checkCannotBeCreatedForNonExistingChecker() throws Exception {
    CheckKey checkKey =
        CheckKey.create(project, createChange().getPatchSetId(), CheckerUuid.parse("foo:bar"));

    exception.expect(IllegalStateException.class);
    exception.expectCause(instanceOf(IOException.class));
    exception.expectMessage("checker foo:bar not found");
    checkOperations.newCheck(checkKey).upsert();
  }

  @Test
  public void checkCreatedByTestApiCanBeRetrievedViaOfficialApi() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).upsert();

    CheckInfo foundCheck = getCheckFromServer(checkKey);
    assertThat(foundCheck.repository).isEqualTo(project.get());
    assertThat(foundCheck.changeNumber).isEqualTo(checkKey.patchSet().changeId().get());
    assertThat(foundCheck.patchSetId).isEqualTo(checkKey.patchSet().get());
    assertThat(foundCheck.checkerUuid).isEqualTo(checkerUuid.get());
  }

  @Test
  public void specifiedMessageIsRespectedForCheckCreation() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).message("some message").upsert();

    CheckInfo check = getCheckFromServer(checkKey);
    assertThat(check.message).isEqualTo("some message");
  }

  @Test
  public void requestingNoMessageIsPossibleForCheckCreation() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).clearMessage().upsert();

    CheckInfo check = getCheckFromServer(checkKey);
    assertThat(check.message).isNull();
  }

  @Test
  public void specifiedUrlIsRespectedForCheckCreation() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).url("http://example.com/my-check").upsert();

    CheckInfo check = getCheckFromServer(checkKey);
    assertThat(check.url).isEqualTo("http://example.com/my-check");
  }

  @Test
  public void requestingNoUrlIsPossibleForCheckCreation() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).clearUrl().upsert();

    CheckInfo check = getCheckFromServer(checkKey);
    assertThat(check.url).isNull();
  }

  @Test
  public void specifiedStateIsRespectedForCheckCreation() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).state(CheckState.FAILED).upsert();

    CheckInfo check = getCheckFromServer(checkKey);
    assertThat(check.state).isEqualTo(CheckState.FAILED);
  }

  @Test
  public void specifiedStartedIsRespectedForCheckCreation() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    Timestamp started = new Timestamp(1234567L);
    checkOperations.newCheck(checkKey).started(started).upsert();

    CheckInfo check = getCheckFromServer(checkKey);
    assertTimestamp(check.started, started);
  }

  @Test
  public void specifiedFinishedIsRespectedForCheckCreation() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    Timestamp finished = new Timestamp(1234567L);
    checkOperations.newCheck(checkKey).finished(finished).upsert();

    CheckInfo check = getCheckFromServer(checkKey);
    assertTimestamp(check.finished, finished);
  }

  @Test
  public void existingCheckCanBeCheckedForExistence() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey =
        createCheckInServer(
            project, createChange().getPatchSetId(), createArbitraryCheckInput(checkerUuid));

    boolean exists = checkOperations.check(checkKey).exists();

    assertThat(exists).isTrue();
  }

  @Test
  public void notExistingCheckCanBeCheckedForExistence() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);

    boolean exists = checkOperations.check(checkKey).exists();

    assertThat(exists).isFalse();
  }

  @Test
  public void retrievingNotExistingCheckOfNonRelevantCheckerFails() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(allProjects).create();
    CheckKey notExistingCheckKey =
        CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);

    exception.expect(IllegalStateException.class);
    checkOperations.check(notExistingCheckKey).get();
  }

  @Test
  public void retrievingNotExistingCheckOfRelevantCheckerFails() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey notExistingCheckKey =
        CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);

    exception.expect(IllegalStateException.class);
    checkOperations.check(notExistingCheckKey).get();
  }

  @Test
  public void checkNotCreatedByTestApiCanBeRetrieved() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckInput input = createArbitraryCheckInput(checkerUuid);
    input.url = "http://unique-check-not-created-via-test-API";
    CheckKey checkKey = createCheckInServer(project, createChange().getPatchSetId(), input);

    Check foundCheck = checkOperations.check(checkKey).get();

    assertThat(foundCheck.key()).isEqualTo(checkKey);
    assertThat(foundCheck.url().get()).isEqualTo(input.url);
  }

  @Test
  public void keyOfExistingCheckCanBeRetrieved() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).upsert();

    CheckKey foundCheckKey = checkOperations.check(checkKey).get().key();

    assertThat(foundCheckKey).isEqualTo(checkKey);
  }

  @Test
  public void stateOfExistingCheckCanBeRetrieved() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).state(CheckState.FAILED).upsert();

    CheckState checkState = checkOperations.check(checkKey).get().state();

    assertThat(checkState).isEqualTo(CheckState.FAILED);
  }

  @Test
  public void messageOfExistingCheckCanBeRetrieved() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).message("some message").upsert();

    Optional<String> message = checkOperations.check(checkKey).get().message();

    assertThat(message).hasValue("some message");
  }

  @Test
  public void emptyMessageOfExistingCheckCanBeRetrieved() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).clearMessage().upsert();

    Optional<String> message = checkOperations.check(checkKey).get().message();

    assertThat(message).isEmpty();
  }

  @Test
  public void urlOfExistingCheckCanBeRetrieved() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).url("http://example.com/my-check").upsert();

    Optional<String> url = checkOperations.check(checkKey).get().url();

    assertThat(url).hasValue("http://example.com/my-check");
  }

  @Test
  public void emptyUrlOfExistingCheckCanBeRetrieved() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).clearUrl().upsert();

    Optional<String> url = checkOperations.check(checkKey).get().url();

    assertThat(url).isEmpty();
  }

  @Test
  public void startedOfExistingCheckCanBeRetrieved() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    Timestamp started = new Timestamp(1234567L);
    checkOperations.newCheck(checkKey).started(started).upsert();

    Optional<Timestamp> foundStarted = checkOperations.check(checkKey).get().started();

    assertTimestamp(foundStarted, started);
  }

  @Test
  public void finishedOfExistingCheckCanBeRetrieved() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    Timestamp finished = new Timestamp(1234567L);
    checkOperations.newCheck(checkKey).finished(finished).upsert();

    Optional<Timestamp> foundFinished = checkOperations.check(checkKey).get().finished();

    assertTimestamp(foundFinished, finished);
  }

  @Test
  public void createdOfExistingCheckCanBeRetrieved() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    PatchSet.Id patchSetId = createChange().getPatchSetId();
    CheckKey checkKey = CheckKey.create(project, patchSetId, checkerUuid);
    CheckInfo check =
        checksApiFactory.revision(patchSetId).create(createArbitraryCheckInput(checkerUuid)).get();

    Timestamp created = checkOperations.check(checkKey).get().created();

    assertThat(created).isEqualTo(check.created);
  }

  @Test
  public void updatedOfExistingCheckCanBeRetrieved() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    PatchSet.Id patchSetId = createChange().getPatchSetId();
    CheckKey checkKey = CheckKey.create(project, patchSetId, checkerUuid);
    CheckInfo check =
        checksApiFactory.revision(patchSetId).create(createArbitraryCheckInput(checkerUuid)).get();

    Timestamp updated = checkOperations.check(checkKey).get().updated();

    assertThat(updated).isEqualTo(check.updated);
  }

  @Test
  public void updateWithoutAnyParametersIsANoop() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).upsert();

    Check originalCheck = checkOperations.check(checkKey).get();

    checkOperations.check(checkKey).forUpdate().upsert();

    Check updatedCheck = checkOperations.check(checkKey).get();
    assertThat(updatedCheck).isEqualTo(originalCheck);
  }

  @Test
  public void updateWritesToInternalCheckSystem() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).url("http://original-url").upsert();

    checkOperations.check(checkKey).forUpdate().url("http://updated-url").upsert();

    String currentUrl = getCheckFromServer(checkKey).url;
    assertThat(currentUrl).isEqualTo("http://updated-url");
  }

  @Test
  public void stateCanBeUpdated() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).state(CheckState.FAILED).upsert();

    checkOperations.check(checkKey).forUpdate().state(CheckState.SUCCESSFUL).upsert();

    CheckState currentState = checkOperations.check(checkKey).get().state();
    assertThat(currentState).isEqualTo(CheckState.SUCCESSFUL);
  }

  @Test
  public void messageCanBeUpdated() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).message("original message").upsert();

    checkOperations.check(checkKey).forUpdate().message("updated message").upsert();

    Optional<String> currentMessage = checkOperations.check(checkKey).get().message();
    assertThat(currentMessage).hasValue("updated message");
  }

  @Test
  public void messageCanBeCleared() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).message("original message").upsert();

    checkOperations.check(checkKey).forUpdate().clearMessage().upsert();

    Optional<String> currentMessage = checkOperations.check(checkKey).get().message();
    assertThat(currentMessage).isEmpty();
  }

  @Test
  public void urlCanBeUpdated() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).url("http://original-url").upsert();

    checkOperations.check(checkKey).forUpdate().url("http://updated-url").upsert();

    Optional<String> currentUrl = checkOperations.check(checkKey).get().url();
    assertThat(currentUrl).hasValue("http://updated-url");
  }

  @Test
  public void urlCanBeCleared() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).url("http://original-url").upsert();

    checkOperations.check(checkKey).forUpdate().clearUrl().upsert();

    Optional<String> currentUrl = checkOperations.check(checkKey).get().url();
    assertThat(currentUrl).isEmpty();
  }

  @Test
  public void startedCanBeUpdated() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).started(new Timestamp(1234567L)).upsert();

    Timestamp updatedStarted = new Timestamp(7654321L);
    checkOperations.check(checkKey).forUpdate().started(updatedStarted).upsert();

    Optional<Timestamp> currentStarted = checkOperations.check(checkKey).get().started();
    assertTimestamp(currentStarted, updatedStarted);
  }

  @Test
  public void finishedCanBeUpdated() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);
    checkOperations.newCheck(checkKey).finished(new Timestamp(1234567L)).upsert();

    Timestamp updatedFinished = new Timestamp(7654321L);
    checkOperations.check(checkKey).forUpdate().finished(updatedFinished).upsert();

    Optional<Timestamp> currentFinished = checkOperations.check(checkKey).get().finished();
    assertTimestamp(currentFinished, updatedFinished);
  }

  @Test
  public void getNotesAsText() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    PatchSet.Id patchSetId = createChange().getPatchSetId();
    CheckKey checkKey =
        createCheckInServer(project, patchSetId, createArbitraryCheckInput(checkerUuid));

    ImmutableMap<RevId, String> notesAsText = checkOperations.check(checkKey).notesAsText();
    RevId expectedRevId = getRevId(patchSetId);
    assertThat(notesAsText).containsExactly(expectedRevId, readNoteText(checkKey));
  }

  private String readNoteText(CheckKey checkKey) throws Exception {
    try (Repository repo = repoManager.openRepository(checkKey.repository());
        RevWalk rw = new RevWalk(repo);
        ObjectReader reader = repo.newObjectReader()) {
      Ref checkRef =
          repo.getRefDatabase().exactRef(CheckerRef.checksRef(checkKey.patchSet().changeId()));
      checkNotNull(checkRef);

      NoteMap notes = NoteMap.read(reader, rw.parseCommit(checkRef.getObjectId()));
      ObjectId noteId = notes.get(ObjectId.fromString(getRevId(checkKey.patchSet()).get()));
      return new String(reader.open(noteId, OBJ_BLOB).getCachedBytes(Integer.MAX_VALUE), UTF_8);
    }
  }

  @Test
  public void asInfo() throws Exception {
    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
    CheckKey checkKey = CheckKey.create(project, createChange().getPatchSetId(), checkerUuid);

    checkOperations
        .newCheck(checkKey)
        .state(CheckState.RUNNING)
        .message("some message")
        .url("http://example.com/my-check")
        .started(new Timestamp(1234567L))
        .finished(new Timestamp(7654321L))
        .upsert();
    Check check = checkOperations.check(checkKey).get();
    CheckInfo checkInfo = checkOperations.check(checkKey).asInfo();
    assertThat(checkInfo.repository).isEqualTo(check.key().repository().get());
    assertThat(checkInfo.changeNumber).isEqualTo(check.key().patchSet().changeId().get());
    assertThat(checkInfo.patchSetId).isEqualTo(check.key().patchSet().get());
    assertThat(checkInfo.checkerUuid).isEqualTo(check.key().checkerUuid().get());
    assertThat(checkInfo.state).isEqualTo(check.state());
    assertThat(checkInfo.message).isEqualTo(check.message().get());
    assertThat(checkInfo.url).isEqualTo(check.url().get());
    assertThat(checkInfo.started).isEqualTo(check.started().get());
    assertThat(checkInfo.finished).isEqualTo(check.finished().get());
    assertThat(checkInfo.created).isEqualTo(check.created());
    assertThat(checkInfo.updated).isEqualTo(check.updated());
  }

  private CheckInfo getCheckFromServer(CheckKey checkKey) throws RestApiException {
    return checksApiFactory.revision(checkKey.patchSet()).id(checkKey.checkerUuid()).get();
  }

  private CheckInput createArbitraryCheckInput(CheckerUuid checkerUuid) {
    CheckInput checkInput = new CheckInput();
    checkInput.checkerUuid = checkerUuid.get();
    checkInput.state = CheckState.SCHEDULED;
    checkInput.message = "some message";
    checkInput.url = "http://example.com/my-check";
    checkInput.started = TimeUtil.nowTs();
    return checkInput;
  }

  private CheckKey createCheckInServer(
      Project.NameKey repositoryName, PatchSet.Id patchSetId, CheckInput checkInput)
      throws RestApiException {
    checksApiFactory.revision(patchSetId).create(checkInput);
    return CheckKey.create(repositoryName, patchSetId, CheckerUuid.parse(checkInput.checkerUuid));
  }

  private RevId getRevId(PatchSet.Id patchSetId) throws Exception {
    return new RevId(
        gApi.changes()
            .id(patchSetId.changeId().get())
            .revision(patchSetId.get())
            .commit(false)
            .commit);
  }

  private static void assertTimestamp(Optional<Timestamp> actual, Timestamp expected) {
    assertThat(actual).isPresent();
    assertTimestamp(actual.get(), expected);
  }

  private static void assertTimestamp(Timestamp actual, Timestamp expected) {
    long timestampDiffMs = Math.abs(actual.getTime() - expected.getTime());
    assertThat(timestampDiffMs).isAtMost(SECONDS.toMillis(1));
  }
}
