// Copyright (C) 2021 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.server.project;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.gerrit.acceptance.GitUtil.fetch;
import static com.google.gerrit.acceptance.GitUtil.pushHead;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.config.GerritConfig;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.extensions.annotations.Exports;
import com.google.gerrit.extensions.client.ListChangesOption;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.SubmitRequirementResultInfo;
import com.google.gerrit.index.query.Matchable;
import com.google.gerrit.index.query.OperatorPredicate;
import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.index.query.QueryParseException;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.project.ProjectConfig;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.ChangeQueryBuilder;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.util.List;
import java.util.Locale;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.transport.PushResult;
import org.eclipse.jgit.transport.RemoteRefUpdate;
import org.eclipse.jgit.transport.RemoteRefUpdate.Status;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.util.RawParseUtils;
import org.junit.Test;

/**
 * Tests validating submit requirements on upload of {@code project.config} to {@code
 * refs/meta/config}.
 */
public class SubmitRequirementsValidationIT extends AbstractDaemonTest {
  @Test
  public void validSubmitRequirementIsAccepted_optionalParametersNotSet() throws Exception {
    fetchRefsMetaConfig();

    String submitRequirementName = "Code-Review";
    updateProjectConfig(
        projectConfig ->
            projectConfig.setString(
                ProjectConfig.SUBMIT_REQUIREMENT,
                /* subsection= */ submitRequirementName,
                /* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
                /* value= */ "label:\"Code-Review=+2\""));

    PushResult r = pushRefsMetaConfig();
    assertOkStatus(r);
  }

  @Test
  public void validSubmitRequirementIsAccepted_allParametersSet() throws Exception {
    fetchRefsMetaConfig();

    String submitRequirementName = "Code-Review";
    updateProjectConfig(
        projectConfig -> {
          projectConfig.setString(
              ProjectConfig.SUBMIT_REQUIREMENT,
              /* subsection= */ submitRequirementName,
              /* name= */ ProjectConfig.KEY_SR_DESCRIPTION,
              /* value= */ "foo bar description");
          projectConfig.setString(
              ProjectConfig.SUBMIT_REQUIREMENT,
              /* subsection= */ submitRequirementName,
              /* name= */ ProjectConfig.KEY_SR_APPLICABILITY_EXPRESSION,
              /* value= */ "branch:refs/heads/master");
          projectConfig.setString(
              ProjectConfig.SUBMIT_REQUIREMENT,
              /* subsection= */ submitRequirementName,
              /* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
              /* value= */ "label:\"Code-Review=+2\"");
          projectConfig.setString(
              ProjectConfig.SUBMIT_REQUIREMENT,
              /* subsection= */ submitRequirementName,
              /* name= */ ProjectConfig.KEY_SR_OVERRIDE_EXPRESSION,
              /* value= */ "label:\"override=+1\"");
          projectConfig.setBoolean(
              ProjectConfig.SUBMIT_REQUIREMENT,
              /* subsection= */ submitRequirementName,
              /* name= */ ProjectConfig.KEY_SR_OVERRIDE_IN_CHILD_PROJECTS,
              /* value= */ false);
        });

    PushResult r = pushRefsMetaConfig();
    assertOkStatus(r);
  }

  @Test
  public void parametersDirectlyInSubmitRequirementsSectionAreRejected() throws Exception {
    fetchRefsMetaConfig();

    updateProjectConfig(
        projectConfig -> {
          projectConfig.setString(
              ProjectConfig.SUBMIT_REQUIREMENT,
              /* subsection= */ null,
              /* name= */ ProjectConfig.KEY_SR_DESCRIPTION,
              /* value= */ "foo bar description");
          projectConfig.setString(
              ProjectConfig.SUBMIT_REQUIREMENT,
              /* subsection= */ null,
              /* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
              /* value= */ "label:\"Code-Review=+2\"");
        });

    PushResult r = pushRefsMetaConfig();
    assertErrorStatus(
        r,
        "Invalid project configuration",
        String.format(
            "project.config: Submit requirements must be defined in submit-requirement.<name>"
                + " subsections. Setting parameters directly in the submit-requirement section is"
                + " not allowed: [%s, %s]",
            ProjectConfig.KEY_SR_DESCRIPTION, ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION));
  }

  @Test
  public void unsupportedParameterDirectlyInSubmitRequirementsSectionIsRejected() throws Exception {
    fetchRefsMetaConfig();

    updateProjectConfig(
        projectConfig ->
            projectConfig.setString(
                ProjectConfig.SUBMIT_REQUIREMENT,
                /* subsection= */ null,
                /* name= */ "unknown",
                /* value= */ "value"));

    PushResult r = pushRefsMetaConfig();
    assertErrorStatus(
        r,
        "Invalid project configuration",
        "project.config: Submit requirements must be defined in submit-requirement.<name>"
            + " subsections. Setting parameters directly in the submit-requirement section is"
            + " not allowed: [unknown]");
  }

  @Test
  public void unsupportedParameterForSubmitRequirementIsRejected() throws Exception {
    fetchRefsMetaConfig();

    String submitRequirementName = "Code-Review";
    updateProjectConfig(
        projectConfig ->
            projectConfig.setString(
                ProjectConfig.SUBMIT_REQUIREMENT,
                /* subsection= */ submitRequirementName,
                /* name= */ "unknown",
                /* value= */ "value"));

    PushResult r = pushRefsMetaConfig();
    assertErrorStatus(
        r,
        "Invalid project configuration",
        String.format(
            "project.config: Unsupported parameters for submit requirement '%s': [unknown]",
            submitRequirementName));
  }

  @Test
  public void conflictingSubmitRequirementsAreRejected() throws Exception {
    fetchRefsMetaConfig();

    String submitRequirementName = "Code-Review";
    updateProjectConfig(
        projectConfig -> {
          projectConfig.setString(
              ProjectConfig.SUBMIT_REQUIREMENT,
              /* subsection= */ submitRequirementName,
              /* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
              /* value= */ "label:\"Code-Review=+2\"");
          projectConfig.setString(
              ProjectConfig.SUBMIT_REQUIREMENT,
              /* subsection= */ submitRequirementName.toLowerCase(Locale.US),
              /* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
              /* value= */ "label:\"Code-Review=+2\"");
        });

    PushResult r = pushRefsMetaConfig();
    assertErrorStatus(
        r,
        "Invalid project configuration",
        String.format(
            "project.config: Submit requirement '%s' conflicts with '%s'.",
            submitRequirementName.toLowerCase(Locale.US), submitRequirementName));
  }

  @Test
  public void conflictingSubmitRequirementIsRejected() throws Exception {
    fetchRefsMetaConfig();
    String submitRequirementName = "Code-Review";
    updateProjectConfig(
        projectConfig ->
            projectConfig.setString(
                ProjectConfig.SUBMIT_REQUIREMENT,
                /* subsection= */ submitRequirementName,
                /* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
                /* value= */ "label:\"Code-Review=+2\""));
    PushResult r = pushRefsMetaConfig();
    assertOkStatus(r);

    updateProjectConfig(
        projectConfig ->
            projectConfig.setString(
                ProjectConfig.SUBMIT_REQUIREMENT,
                /* subsection= */ submitRequirementName.toLowerCase(Locale.US),
                /* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
                /* value= */ "label:\"Code-Review=+2\""));
    r = pushRefsMetaConfig();
    assertErrorStatus(
        r,
        "Invalid project configuration",
        String.format(
            "project.config: Submit requirement '%s' conflicts with '%s'.",
            submitRequirementName.toLowerCase(Locale.US), submitRequirementName));
  }

  @Test
  public void submitRequirementWithoutSubmittabilityExpressionIsRejected() throws Exception {
    fetchRefsMetaConfig();

    String submitRequirementName = "Code-Review";
    updateProjectConfig(
        projectConfig ->
            projectConfig.setString(
                ProjectConfig.SUBMIT_REQUIREMENT,
                /* subsection= */ submitRequirementName,
                /* name= */ ProjectConfig.KEY_SR_DESCRIPTION,
                /* value= */ "foo bar description"));

    PushResult r = pushRefsMetaConfig();
    assertErrorStatus(
        r,
        "Invalid project configuration",
        String.format(
            "project.config: Setting a submittability expression for submit requirement '%s' is"
                + " required: Missing %s.%s.%s",
            submitRequirementName,
            ProjectConfig.SUBMIT_REQUIREMENT,
            submitRequirementName,
            ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION));
  }

  @Test
  public void submitRequirementWithInvalidSubmittabilityExpressionIsRejected() throws Exception {
    fetchRefsMetaConfig();

    String submitRequirementName = "Code-Review";
    String invalidExpression = "invalid_field:invalid_value";
    updateProjectConfig(
        projectConfig ->
            projectConfig.setString(
                ProjectConfig.SUBMIT_REQUIREMENT,
                /* subsection= */ submitRequirementName,
                /* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
                /* value= */ invalidExpression));

    PushResult r = pushRefsMetaConfig();
    assertErrorStatus(
        r,
        "Invalid project configuration",
        String.format(
            "project.config: Expression '%s' of submit requirement '%s' (parameter %s.%s.%s) is"
                + " invalid: Unsupported operator %s",
            invalidExpression,
            submitRequirementName,
            ProjectConfig.SUBMIT_REQUIREMENT,
            submitRequirementName,
            ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
            invalidExpression));
  }

  @Test
  public void submitRequirementWithInvalidApplicabilityExpressionIsRejected() throws Exception {
    fetchRefsMetaConfig();

    String submitRequirementName = "Code-Review";
    String invalidExpression = "invalid_field:invalid_value";
    updateProjectConfig(
        projectConfig -> {
          projectConfig.setString(
              ProjectConfig.SUBMIT_REQUIREMENT,
              /* subsection= */ submitRequirementName,
              /* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
              /* value= */ "label:\"Code-Review=+2\"");
          projectConfig.setString(
              ProjectConfig.SUBMIT_REQUIREMENT,
              /* subsection= */ submitRequirementName,
              /* name= */ ProjectConfig.KEY_SR_APPLICABILITY_EXPRESSION,
              /* value= */ invalidExpression);
        });

    PushResult r = pushRefsMetaConfig();
    assertErrorStatus(
        r,
        "Invalid project configuration",
        String.format(
            "project.config: Expression '%s' of submit requirement '%s' (parameter %s.%s.%s) is"
                + " invalid: Unsupported operator %s",
            invalidExpression,
            submitRequirementName,
            ProjectConfig.SUBMIT_REQUIREMENT,
            submitRequirementName,
            ProjectConfig.KEY_SR_APPLICABILITY_EXPRESSION,
            invalidExpression));
  }

  @Test
  public void submitRequirementWithInvalidOverrideExpressionIsRejected() throws Exception {
    fetchRefsMetaConfig();

    String submitRequirementName = "Code-Review";
    String invalidExpression = "invalid_field:invalid_value";
    updateProjectConfig(
        projectConfig -> {
          projectConfig.setString(
              ProjectConfig.SUBMIT_REQUIREMENT,
              /* subsection= */ submitRequirementName,
              /* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
              /* value= */ "label:\"Code-Review=+2\"");
          projectConfig.setString(
              ProjectConfig.SUBMIT_REQUIREMENT,
              /* subsection= */ submitRequirementName,
              /* name= */ ProjectConfig.KEY_SR_OVERRIDE_EXPRESSION,
              /* value= */ invalidExpression);
        });

    PushResult r = pushRefsMetaConfig();
    assertErrorStatus(
        r,
        "Invalid project configuration",
        String.format(
            "project.config: Expression '%s' of submit requirement '%s' (parameter %s.%s.%s) is"
                + " invalid: Unsupported operator %s",
            invalidExpression,
            submitRequirementName,
            ProjectConfig.SUBMIT_REQUIREMENT,
            submitRequirementName,
            ProjectConfig.KEY_SR_OVERRIDE_EXPRESSION,
            invalidExpression));
  }

  @Test
  public void submitRequirementWithInvalidAllowOverrideInChildProjectsIsRejected()
      throws Exception {
    fetchRefsMetaConfig();

    String submitRequirementName = "Code-Review";
    String invalidValue = "invalid";
    updateProjectConfig(
        projectConfig ->
            projectConfig.setString(
                ProjectConfig.SUBMIT_REQUIREMENT,
                /* subsection= */ submitRequirementName,
                /* name= */ ProjectConfig.KEY_SR_OVERRIDE_IN_CHILD_PROJECTS,
                /* value= */ invalidValue));

    PushResult r = pushRefsMetaConfig();
    assertErrorStatus(
        r,
        "Invalid project configuration",
        String.format(
            "project.config: Invalid value %s.%s.%s for submit requirement '%s': %s",
            ProjectConfig.SUBMIT_REQUIREMENT,
            submitRequirementName,
            ProjectConfig.KEY_SR_OVERRIDE_IN_CHILD_PROJECTS,
            submitRequirementName,
            invalidValue));
  }

  @Test
  public void validSubmitRequirementCanBePushedForReview_optionalParametersNotSet()
      throws Exception {
    fetchRefsMetaConfig();

    String submitRequirementName = "Code-Review";
    RevCommit head = getHead(testRepo.getRepository(), RefNames.REFS_CONFIG);
    Config projectConfig = readProjectConfig(head);
    projectConfig.setString(
        ProjectConfig.SUBMIT_REQUIREMENT,
        /* subsection= */ submitRequirementName,
        /* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
        /* value= */ "label:\"Code-Review=+2\"");

    PushOneCommit.Result r =
        createChange(
            testRepo,
            RefNames.REFS_CONFIG,
            "Add submit requirement",
            ProjectConfig.PROJECT_CONFIG,
            projectConfig.toText(),
            /* topic= */ null);
    r.assertOkStatus();
  }

  @Test
  public void validSubmitRequirementCanBePushedForReview_allParametersSet() throws Exception {
    fetchRefsMetaConfig();

    String submitRequirementName = "Code-Review";
    RevCommit head = getHead(testRepo.getRepository(), RefNames.REFS_CONFIG);
    Config projectConfig = readProjectConfig(head);
    projectConfig.setString(
        ProjectConfig.SUBMIT_REQUIREMENT,
        /* subsection= */ submitRequirementName,
        /* name= */ ProjectConfig.KEY_SR_DESCRIPTION,
        /* value= */ "foo bar description");
    projectConfig.setString(
        ProjectConfig.SUBMIT_REQUIREMENT,
        /* subsection= */ submitRequirementName,
        /* name= */ ProjectConfig.KEY_SR_APPLICABILITY_EXPRESSION,
        /* value= */ "branch:refs/heads/master");
    projectConfig.setString(
        ProjectConfig.SUBMIT_REQUIREMENT,
        /* subsection= */ submitRequirementName,
        /* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
        /* value= */ "label:\"Code-Review=+2\"");
    projectConfig.setString(
        ProjectConfig.SUBMIT_REQUIREMENT,
        /* subsection= */ submitRequirementName,
        /* name= */ ProjectConfig.KEY_SR_OVERRIDE_EXPRESSION,
        /* value= */ "label:\"override=+1\"");
    projectConfig.setBoolean(
        ProjectConfig.SUBMIT_REQUIREMENT,
        /* subsection= */ submitRequirementName,
        /* name= */ ProjectConfig.KEY_SR_OVERRIDE_IN_CHILD_PROJECTS,
        /* value= */ false);

    PushOneCommit.Result r =
        createChange(
            testRepo,
            RefNames.REFS_CONFIG,
            "Add submit requirement",
            ProjectConfig.PROJECT_CONFIG,
            projectConfig.toText(),
            /* topic= */ null);
    r.assertOkStatus();
  }

  protected static class IsOperatorModule extends AbstractModule {
    @Override
    public void configure() {
      bind(ChangeQueryBuilder.ChangeIsOperandFactory.class)
          .annotatedWith(Exports.named("changeNumberEven"))
          .to(SampleIsOperand.class);
    }
  }

  private static class SampleIsOperand implements ChangeQueryBuilder.ChangeIsOperandFactory {
    final Provider<CurrentUser> currentUserProvider;

    @Inject
    SampleIsOperand(Provider<CurrentUser> currentUserProvider) {
      this.currentUserProvider = currentUserProvider;
    }

    @Override
    public Predicate<ChangeData> create(ChangeQueryBuilder builder) throws QueryParseException {
      return new IsSamplePredicate(currentUserProvider.get());
    }
  }

  private static class IsSamplePredicate extends OperatorPredicate<ChangeData>
      implements Matchable<ChangeData> {

    CurrentUser currentUser;

    public IsSamplePredicate(CurrentUser currentUser) {
      super("is", "changeNumberEven");
      this.currentUser = currentUser;
      assertServerUser();
    }

    private void assertServerUser() {
      try {
        currentUser.asIdentifiedUser();
        throw new IllegalStateException("is an identified user");
      } catch (UnsupportedOperationException e) {
        // as expected.
      }
    }

    @Override
    public boolean match(ChangeData changeData) {
      assertServerUser();
      return true;
    }

    @Override
    public int getCost() {
      return 0;
    }
  }

  @Test
  public void submitRequirementValidationRunsAsServer() throws Exception {
    try (TestRepository<Repository> testRepo =
        new TestRepository<>(repoManager.openRepository(project))) {
      testRepo.delete(RefNames.REFS_CONFIG);
    }

    PushOneCommit.Result r = createChange();
    String changeId = r.getChangeId();

    try (AutoCloseable ignored = installPlugin("myplugin", IsOperatorModule.class)) {
      PushOneCommit push =
          pushFactory
              .create(
                  admin.newIdent(),
                  testRepo,
                  "Test Change",
                  ProjectConfig.PROJECT_CONFIG,
                  "[submit-requirement \"SAMPLE\"]\n"
                      + "  submittableIf = is:changeNumberEven_myplugin\n")
              .setParents(ImmutableList.of());
      PushOneCommit.Result cfgPush = push.to(RefNames.REFS_CONFIG);
      cfgPush.assertOkStatus();

      ChangeInfo info = gApi.changes().id(changeId).get(ListChangesOption.SUBMIT_REQUIREMENTS);
      List<SubmitRequirementResultInfo> results =
          info.submitRequirements.stream()
              .filter(x -> x.name.equals("SAMPLE"))
              .collect(Collectors.toList());
      assertThat(results).hasSize(1);
      assertThat(results.get(0).status).isNotEqualTo(SubmitRequirementResultInfo.Status.ERROR);
    }

    // Unloaded the plugin, the SR will fail now.

    ChangeInfo info = gApi.changes().id(changeId).get(ListChangesOption.SUBMIT_REQUIREMENTS);
    List<SubmitRequirementResultInfo> results =
        info.submitRequirements.stream()
            .filter(x -> x.name.equals("SAMPLE"))
            .collect(Collectors.toList());
    assertThat(results).hasSize(1);
    assertThat(results.get(0).status).isEqualTo(SubmitRequirementResultInfo.Status.ERROR);
  }

  @GerritConfig(name = "change.propagateSubmitRequirementErrors", value = "true")
  @Test
  public void submitRequirementPropagateErrorFlag() throws Exception {
    try (TestRepository<Repository> testRepo =
        new TestRepository<>(repoManager.openRepository(project))) {
      testRepo.delete(RefNames.REFS_CONFIG);
    }

    PushOneCommit.Result r = createChange();
    String changeId = r.getChangeId();

    try (AutoCloseable ignored = installPlugin("myplugin", IsOperatorModule.class)) {
      PushOneCommit push =
          pushFactory
              .create(
                  admin.newIdent(),
                  testRepo,
                  "Test Change",
                  ProjectConfig.PROJECT_CONFIG,
                  "[submit-requirement \"SAMPLE\"]\n"
                      + "  submittableIf = is:changeNumberEven_myplugin\n")
              .setParents(ImmutableList.of());
      PushOneCommit.Result cfgPush = push.to(RefNames.REFS_CONFIG);
      cfgPush.assertOkStatus();
    }
    StorageException thrown =
        assertThrows(
            StorageException.class,
            () -> gApi.changes().id(changeId).get(ListChangesOption.SUBMIT_REQUIREMENTS));
    assertThat(thrown).hasMessageThat().contains("changeNumberEven_myplugin");
  }

  @Test
  public void invalidSubmitRequirementIsRejectedWhenPushingForReview() throws Exception {
    fetchRefsMetaConfig();

    String submitRequirementName = "Code-Review";
    String invalidExpression = "invalid_field:invalid_value";

    RevCommit head = getHead(testRepo.getRepository(), RefNames.REFS_CONFIG);
    Config projectConfig = readProjectConfig(head);
    projectConfig.setString(
        ProjectConfig.SUBMIT_REQUIREMENT,
        /* subsection= */ submitRequirementName,
        /* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
        /* value= */ invalidExpression);
    PushOneCommit.Result r =
        createChange(
            testRepo,
            RefNames.REFS_CONFIG,
            "Add submit requirement",
            ProjectConfig.PROJECT_CONFIG,
            projectConfig.toText(),
            /* topic= */ null);
    r.assertErrorStatus(
        String.format(
            "invalid submit requirement expressions in project.config (revision = %s)",
            r.getCommit().name()));
    assertThat(r.getMessage()).contains("Invalid project configuration");
    assertThat(r.getMessage())
        .contains(
            String.format(
                "project.config: Expression '%s' of submit requirement '%s' (parameter %s.%s.%s) is"
                    + " invalid: Unsupported operator %s",
                invalidExpression,
                submitRequirementName,
                ProjectConfig.SUBMIT_REQUIREMENT,
                submitRequirementName,
                ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
                invalidExpression));
  }

  private void fetchRefsMetaConfig() throws Exception {
    fetch(testRepo, RefNames.REFS_CONFIG + ":" + RefNames.REFS_CONFIG);
    testRepo.reset(RefNames.REFS_CONFIG);
  }

  private PushResult pushRefsMetaConfig() throws Exception {
    return pushHead(testRepo, RefNames.REFS_CONFIG);
  }

  private void updateProjectConfig(Consumer<Config> configUpdater) throws Exception {
    RevCommit head = getHead(testRepo.getRepository(), RefNames.REFS_CONFIG);
    Config projectConfig = readProjectConfig(head);
    configUpdater.accept(projectConfig);
    RevCommit commit =
        testRepo.update(
            RefNames.REFS_CONFIG,
            testRepo
                .commit()
                .parent(head)
                .message("Update project config")
                .author(admin.newIdent())
                .committer(admin.newIdent())
                .add(ProjectConfig.PROJECT_CONFIG, projectConfig.toText()));

    testRepo.reset(commit);
  }

  private Config readProjectConfig(RevCommit commit) throws Exception {
    try (TreeWalk tw =
        TreeWalk.forPath(
            testRepo.getRevWalk().getObjectReader(),
            ProjectConfig.PROJECT_CONFIG,
            commit.getTree())) {
      if (tw == null) {
        throw new IllegalStateException(
            String.format("%s does not exist", ProjectConfig.PROJECT_CONFIG));
      }
    }
    RevObject blob = testRepo.get(commit.getTree(), ProjectConfig.PROJECT_CONFIG);
    byte[] data = testRepo.getRepository().open(blob).getCachedBytes(Integer.MAX_VALUE);
    String content = RawParseUtils.decode(data);

    Config projectConfig = new Config();
    projectConfig.fromText(content);
    return projectConfig;
  }

  public void assertOkStatus(PushResult result) {
    RemoteRefUpdate refUpdate = result.getRemoteUpdate(RefNames.REFS_CONFIG);
    assertThat(refUpdate).isNotNull();
    assertWithMessage(getMessage(result, refUpdate))
        .that(refUpdate.getStatus())
        .isEqualTo(Status.OK);
  }

  public void assertErrorStatus(PushResult result, String... expectedMessages) {
    RemoteRefUpdate refUpdate = result.getRemoteUpdate(RefNames.REFS_CONFIG);
    assertThat(refUpdate).isNotNull();
    assertWithMessage(getMessage(result, refUpdate))
        .that(refUpdate.getStatus())
        .isEqualTo(Status.REJECTED_OTHER_REASON);
    for (String expectedMessage : expectedMessages) {
      assertThat(result.getMessages()).contains(expectedMessage);
    }
  }

  private String getMessage(PushResult result, RemoteRefUpdate refUpdate) {
    StringBuilder b = new StringBuilder();
    if (refUpdate.getMessage() != null) {
      b.append(refUpdate.getMessage());
      b.append("\n");
    }
    b.append(result.getMessages());
    return b.toString();
  }
}
