// 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.gerrit.acceptance.ExtensionRegistry.PLUGIN_NAME;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static com.google.gerrit.server.project.testing.TestLabels.value;

import com.google.common.collect.MoreCollectors;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.ExtensionRegistry;
import com.google.gerrit.acceptance.ExtensionRegistry.Registration;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.testsuite.change.ChangeOperations;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.LabelFunction;
import com.google.gerrit.entities.SubmitRequirement;
import com.google.gerrit.entities.SubmitRequirementExpression;
import com.google.gerrit.entities.SubmitRequirementExpressionResult;
import com.google.gerrit.entities.SubmitRequirementExpressionResult.Status;
import com.google.gerrit.entities.SubmitRequirementResult;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.ChangeInput;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.index.query.QueryParseException;
import com.google.gerrit.server.project.SubmitRequirementEvaluationException;
import com.google.gerrit.server.project.SubmitRequirementsEvaluator;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.ChangeQueryBuilder;
import com.google.gerrit.server.query.change.ChangeQueryBuilder.ChangeIsOperandFactory;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.query.change.SubmitRequirementPredicate;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.util.Map;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;

@NoHttpd
public class SubmitRequirementsEvaluatorIT extends AbstractDaemonTest {
  @Inject SubmitRequirementsEvaluator evaluator;
  @Inject private ProjectOperations projectOperations;
  @Inject private Provider<InternalChangeQuery> changeQueryProvider;
  @Inject private ExtensionRegistry extensionRegistry;
  @Inject private RequestScopeOperations requestScopeOperations;
  @Inject private ChangeOperations changeOperations;

  private ChangeData changeData;
  private String changeId;

  private static final String FILE_NAME = "file,txt";
  private static final String CONTENT = "line 1\nline 2\n line 3\n";

  @Before
  public void setUp() throws Exception {
    PushOneCommit.Result pushResult =
        createChange(testRepo, "refs/heads/master", "Fix a bug", "file.txt", "content", "topic");
    changeData = pushResult.getChange();
    changeId = pushResult.getChangeId();
  }

  @Test
  public void invalidExpression() throws Exception {
    SubmitRequirementExpression expression =
        SubmitRequirementExpression.create("invalid_field:invalid_value");
    SubmitRequirementExpressionResult result = evaluator.evaluateExpression(expression, changeData);

    assertThat(result.status()).isEqualTo(Status.ERROR);
    assertThat(result.errorMessage().get())
        .isEqualTo("Unsupported operator invalid_field:invalid_value");
  }

  @Test
  public void expressionWithPassingPredicate() throws Exception {
    SubmitRequirementExpression expression =
        SubmitRequirementExpression.create("branch:refs/heads/master");
    SubmitRequirementExpressionResult result = evaluator.evaluateExpression(expression, changeData);

    assertThat(result.status()).isEqualTo(Status.PASS);
    assertThat(result.errorMessage()).isEqualTo(Optional.empty());
  }

  @Test
  public void expressionWithFailingPredicate() throws Exception {
    SubmitRequirementExpression expression =
        SubmitRequirementExpression.create("branch:refs/heads/foo");
    SubmitRequirementExpressionResult result = evaluator.evaluateExpression(expression, changeData);

    assertThat(result.status()).isEqualTo(Status.FAIL);
    assertThat(result.errorMessage()).isEqualTo(Optional.empty());
  }

  @Test
  public void throwingSubmitRequirementPredicate() throws Exception {
    try (Registration registration =
        extensionRegistry
            .newRegistration()
            .add(
                new ThrowingSubmitRequirementPredicate(),
                ThrowingSubmitRequirementPredicate.OPERAND)) {
      SubmitRequirementExpression expression =
          SubmitRequirementExpression.create(
              String.format("is:%s_%s", ThrowingSubmitRequirementPredicate.OPERAND, PLUGIN_NAME));
      SubmitRequirementExpressionResult result =
          evaluator.evaluateExpression(expression, changeData);
      assertThat(result.status()).isEqualTo(Status.ERROR);
      assertThat(result.errorMessage().get())
          .isEqualTo(ThrowingSubmitRequirementPredicate.ERROR_MESSAGE);
    }
  }

  @Test
  public void compositeExpression() throws Exception {
    SubmitRequirementExpression expression =
        SubmitRequirementExpression.create(
            String.format(
                "(project:%s AND branch:refs/heads/foo) OR message:\"Fix a bug\"", project.get()));

    SubmitRequirementExpressionResult result = evaluator.evaluateExpression(expression, changeData);

    assertThat(result.status()).isEqualTo(Status.PASS);

    assertThat(result.passingAtoms())
        .containsExactly(String.format("project:%s", project.get()), "message:\"Fix a bug\"");

    assertThat(result.failingAtoms()).containsExactly(String.format("branch:refs/heads/foo"));
  }

  @Test
  public void globalSubmitRequirementEvaluated() throws Exception {
    SubmitRequirement globalSubmitRequirement =
        createSubmitRequirement(
            /*name=*/ "global-config-requirement",
            /* applicabilityExpr= */ "project:" + project.get(),
            /*submittabilityExpr= */ "is:true",
            /* overrideExpr= */ "", /*allowOverrideInChildProjects*/
            false);
    try (Registration registration =
        extensionRegistry.newRegistration().add(globalSubmitRequirement)) {
      SubmitRequirement projectSubmitRequirement =
          createSubmitRequirement(
              /*name=*/ "project-config-requirement",
              /* applicabilityExpr= */ "project:" + project.get(),
              /*submittabilityExpr= */ "is:true",
              /* overrideExpr= */ "", /*allowOverrideInChildProjects*/
              false);
      configSubmitRequirement(project, projectSubmitRequirement);
      Map<SubmitRequirement, SubmitRequirementResult> results =
          evaluator.evaluateAllRequirements(changeData, /* includeLegacy= */ false);
      assertThat(results).hasSize(2);
      assertThat(results.get(globalSubmitRequirement).status())
          .isEqualTo(SubmitRequirementResult.Status.SATISFIED);
      assertThat(results.get(projectSubmitRequirement).status())
          .isEqualTo(SubmitRequirementResult.Status.SATISFIED);
    }
  }

  @Test
  public void
      globalSubmitRequirement_duplicateInProjectConfig_overrideAllowed_projectResultReturned()
          throws Exception {
    SubmitRequirement globalSubmitRequirement =
        createSubmitRequirement(
            /*name=*/ "config-requirement",
            /* applicabilityExpr= */ "project:" + project.get(),
            /*submittabilityExpr= */ "is:true",
            /* overrideExpr= */ "", /*allowOverrideInChildProjects*/
            true);
    try (Registration registration =
        extensionRegistry.newRegistration().add(globalSubmitRequirement)) {
      SubmitRequirement projectSubmitRequirement =
          createSubmitRequirement(
              /*name=*/ "config-requirement",
              /* applicabilityExpr= */ "project:" + project.get(),
              /*submittabilityExpr= */ "is:true",
              /* overrideExpr= */ "", /*allowOverrideInChildProjects*/
              false);
      configSubmitRequirement(project, projectSubmitRequirement);
      Map<SubmitRequirement, SubmitRequirementResult> results =
          evaluator.evaluateAllRequirements(changeData, /* includeLegacy= */ false);
      assertThat(results).hasSize(1);
      assertThat(results.get(projectSubmitRequirement).status())
          .isEqualTo(SubmitRequirementResult.Status.SATISFIED);
    }
  }

  @Test
  public void
      globalSubmitRequirement_duplicateInProjectConfig_overrideNotAllowedAllowed_globalResultReturned()
          throws Exception {
    SubmitRequirement globalSubmitRequirement =
        createSubmitRequirement(
            /*name=*/ "config-requirement",
            /* applicabilityExpr= */ "project:" + project.get(),
            /*submittabilityExpr= */ "is:true",
            /* overrideExpr= */ "", /*allowOverrideInChildProjects*/
            false);
    try (Registration registration =
        extensionRegistry.newRegistration().add(globalSubmitRequirement)) {
      SubmitRequirement projectSubmitRequirement =
          createSubmitRequirement(
              /*name=*/ "config-requirement",
              /* applicabilityExpr= */ "project:" + project.get(),
              /*submittabilityExpr= */ "is:true",
              /* overrideExpr= */ "", /*allowOverrideInChildProjects*/
              false);
      configSubmitRequirement(project, projectSubmitRequirement);
      Map<SubmitRequirement, SubmitRequirementResult> results =
          evaluator.evaluateAllRequirements(changeData, /* includeLegacy= */ false);
      assertThat(results).hasSize(1);
      assertThat(results.get(globalSubmitRequirement).status())
          .isEqualTo(SubmitRequirementResult.Status.SATISFIED);
    }
  }

  @Test
  public void submitRequirementIsNotApplicable_whenApplicabilityExpressionIsFalse()
      throws Exception {
    SubmitRequirement sr =
        createSubmitRequirement(
            /* applicabilityExpr= */ "project:non-existent-project",
            /* submittabilityExpr= */ "message:\"Fix bug\"",
            /* overrideExpr= */ "");

    SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);
    assertThat(result.status()).isEqualTo(SubmitRequirementResult.Status.NOT_APPLICABLE);
  }

  @Test
  public void submitRequirement_alwaysNotApplicable() {
    SubmitRequirement sr =
        createSubmitRequirement(
            /* applicabilityExpr= */ "is:false",
            /* submittabilityExpr= */ "is:false", // redundant
            /* overrideExpr= */ "");

    SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);
    assertThat(result.status()).isEqualTo(SubmitRequirementResult.Status.NOT_APPLICABLE);
  }

  @Test
  public void submitRequirement_alwaysApplicable() {
    SubmitRequirement sr =
        createSubmitRequirement(
            /* applicabilityExpr= */ "is:true",
            /* submittabilityExpr= */ "is:true",
            /* overrideExpr= */ "");

    SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);
    assertThat(result.status()).isEqualTo(SubmitRequirementResult.Status.SATISFIED);
  }

  @Test
  public void submittabilityAndOverrideNotEvaluated_whenApplicabilityIsFalse() throws Exception {
    SubmitRequirement sr =
        createSubmitRequirement(
            /* applicabilityExpr= */ "project:non-existent-project",
            /* submittabilityExpr= */ "message:\"Fix bug\"",
            /* overrideExpr= */ "");

    SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);
    assertThat(result.status()).isEqualTo(SubmitRequirementResult.Status.NOT_APPLICABLE);
    assertThat(result.applicabilityExpressionResult().get().status()).isEqualTo(Status.FAIL);
    assertThat(result.submittabilityExpressionResult().isPresent()).isFalse();
    assertThat(result.overrideExpressionResult().isPresent()).isFalse();
  }

  @Test
  public void submittabilityAndOverrideEvaluated_whenApplicabilityIsEmpty() throws Exception {
    SubmitRequirement sr =
        createSubmitRequirement(
            /* applicabilityExpr= */ null,
            /* submittabilityExpr= */ "message:\"Fix bug\"",
            /* overrideExpr= */ "label:\"build-cop-override=-1\"");

    SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);
    assertThat(result.status()).isEqualTo(SubmitRequirementResult.Status.SATISFIED);
    assertThat(result.applicabilityExpressionResult().isPresent()).isFalse();
    assertThat(result.submittabilityExpressionResult().get().status()).isEqualTo(Status.PASS);
    assertThat(result.overrideExpressionResult().get().status()).isEqualTo(Status.FAIL);
  }

  @Test
  public void submittabilityAndOverrideEvaluated_whenApplicabilityIsTrue() throws Exception {
    SubmitRequirement sr =
        createSubmitRequirement(
            /* applicabilityExpr= */ "project:" + project.get(),
            /* submittabilityExpr= */ "message:\"Fix bug\"",
            /* overrideExpr= */ "label:\"build-cop-override=-1\"");

    SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);

    assertThat(result.status()).isEqualTo(SubmitRequirementResult.Status.SATISFIED);
    assertThat(result.applicabilityExpressionResult().get().status()).isEqualTo(Status.PASS);
    assertThat(result.submittabilityExpressionResult().get().status()).isEqualTo(Status.PASS);
    assertThat(result.overrideExpressionResult().get().status()).isEqualTo(Status.FAIL);
  }

  @Test
  public void submittabilityIsEvaluated_whenOverrideApplies() throws Exception {
    SubmitRequirement sr =
        createSubmitRequirement(
            /* applicabilityExpr= */ null,
            /* submittabilityExpr= */ "message:\"Fix bug\"",
            /* overrideExpr= */ "project:" + project.get());

    SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);
    assertThat(result.status()).isEqualTo(SubmitRequirementResult.Status.OVERRIDDEN);

    assertThat(result.applicabilityExpressionResult().isPresent()).isFalse();
    assertThat(result.submittabilityExpressionResult().get().status()).isEqualTo(Status.PASS);
    assertThat(result.overrideExpressionResult().get().status()).isEqualTo(Status.PASS);
  }

  @Test
  public void submitRequirementIsSatisfied_whenSubmittabilityExpressionIsTrue() throws Exception {
    SubmitRequirement sr =
        createSubmitRequirement(
            /* applicabilityExpr= */ "project:" + project.get(),
            /* submittabilityExpr= */ "message:\"Fix a bug\"",
            /* overrideExpr= */ "");

    SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);
    assertThat(result.status()).isEqualTo(SubmitRequirementResult.Status.SATISFIED);
  }

  @Test
  public void submitRequirementIsUnsatisfied_whenSubmittabilityExpressionIsFalse()
      throws Exception {
    SubmitRequirement sr =
        createSubmitRequirement(
            /* applicabilityExpr= */ "project:" + project.get(),
            /* submittabilityExpr= */ "label:\"Code-Review=+2\"",
            /* overrideExpr= */ "");

    SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);
    assertThat(result.status()).isEqualTo(SubmitRequirementResult.Status.UNSATISFIED);
    assertThat(result.submittabilityExpressionResult().get().failingAtoms())
        .containsExactly("label:\"Code-Review=+2\"");
  }

  @Test
  public void submitRequirementIsOverridden_whenOverrideExpressionIsTrue() throws Exception {
    addLabel("build-cop-override");
    voteLabel(changeId, "build-cop-override", 1);

    // Reload change data after applying the vote
    changeData =
        changeQueryProvider.get().byLegacyChangeId(changeData.getId()).stream()
            .collect(MoreCollectors.onlyElement());

    SubmitRequirement sr =
        createSubmitRequirement(
            /* applicabilityExpr= */ "project:" + project.get(),
            /* submittabilityExpr= */ "label:\"Code-Review=+2\"",
            /* overrideExpr= */ "label:\"build-cop-override=+1\"");

    SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);
    assertThat(result.status()).isEqualTo(SubmitRequirementResult.Status.OVERRIDDEN);
  }

  @Test
  public void submitRequirementIsError_whenApplicabilityExpressionHasInvalidSyntax()
      throws Exception {
    addLabel("build-cop-override");

    SubmitRequirement sr =
        createSubmitRequirement(
            /* applicabilityExpr= */ "invalid_field:invalid_value",
            /* submittabilityExpr= */ "label:\"Code-Review=+2\"",
            /* overrideExpr= */ "label:\"build-cop-override=+1\"");

    SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);
    assertThat(result.status()).isEqualTo(SubmitRequirementResult.Status.ERROR);
    assertThat(result.applicabilityExpressionResult().get().errorMessage().get())
        .isEqualTo("Unsupported operator invalid_field:invalid_value");
  }

  @Test
  public void submitRequirementIsError_whenSubmittabilityExpressionHasInvalidSyntax()
      throws Exception {
    addLabel("build-cop-override");

    SubmitRequirement sr =
        createSubmitRequirement(
            /* applicabilityExpr= */ "project:" + project.get(),
            /* submittabilityExpr= */ "invalid_field:invalid_value",
            /* overrideExpr= */ "label:\"build-cop-override=+1\"");

    SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);
    assertThat(result.status()).isEqualTo(SubmitRequirementResult.Status.ERROR);
    assertThat(result.submittabilityExpressionResult().get().errorMessage().get())
        .isEqualTo("Unsupported operator invalid_field:invalid_value");
  }

  @Test
  public void submitRequirementIsError_whenOverrideExpressionHasInvalidSyntax() throws Exception {
    SubmitRequirement sr =
        createSubmitRequirement(
            /* applicabilityExpr= */ "project:" + project.get(),
            /* submittabilityExpr= */ "label:\"Code-Review=+2\"",
            /* overrideExpr= */ "invalid_field:invalid_value");

    SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);
    assertThat(result.status()).isEqualTo(SubmitRequirementResult.Status.ERROR);
    assertThat(result.overrideExpressionResult().get().errorMessage().get())
        .isEqualTo("Unsupported operator invalid_field:invalid_value");
  }

  @Test
  public void byPureRevert() throws Exception {
    testRepo.reset("HEAD~1");
    PushOneCommit.Result pushResult =
        createChange(testRepo, "refs/heads/master", "Fix a bug", "file.txt", "content", "topic");
    changeData = pushResult.getChange();
    changeId = pushResult.getChangeId();

    SubmitRequirement sr =
        createSubmitRequirement(
            /* applicabilityExpr= */ "project:" + project.get(),
            /* submittabilityExpr= */ "is:pure-revert",
            /* overrideExpr= */ "");

    SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);
    assertThat(result.status()).isEqualTo(SubmitRequirementResult.Status.UNSATISFIED);
    approve(changeId);
    gApi.changes().id(changeId).current().submit();

    ChangeInfo changeInfo = gApi.changes().id(changeId).revert().get();
    String revertId = Integer.toString(changeInfo._number);
    ChangeData revertChangeData =
        changeQueryProvider.get().byLegacyChangeId(Change.Id.tryParse(revertId).get()).get(0);
    result = evaluator.evaluateRequirement(sr, revertChangeData);
    assertThat(result.status()).isEqualTo(SubmitRequirementResult.Status.SATISFIED);
  }

  @Test
  public void byAuthorEmail() throws Exception {
    TestAccount user2 =
        accountCreator.create("Foo", "user@example.com", "User", /* displayName = */ null);
    requestScopeOperations.setApiUser(user2.id());
    ChangeInfo info =
        gApi.changes().create(new ChangeInput(project.get(), "master", "Test Change")).get();
    ChangeData cd =
        changeQueryProvider
            .get()
            .byLegacyChangeId(Change.Id.tryParse(Integer.toString(info._number)).get())
            .get(0);

    // Match by email works
    checkSubmitRequirementResult(
        cd,
        /* submittabilityExpr= */ "authoremail:\"^.*@example\\.com\"",
        SubmitRequirementResult.Status.SATISFIED);
    checkSubmitRequirementResult(
        cd,
        /* submittabilityExpr= */ "authoremail:\"^user@.*\\.com\"",
        SubmitRequirementResult.Status.SATISFIED);

    // Match by name does not work
    checkSubmitRequirementResult(
        cd,
        /* submittabilityExpr= */ "authoremail:\"^Foo$\"",
        SubmitRequirementResult.Status.UNSATISFIED);
    checkSubmitRequirementResult(
        cd,
        /* submittabilityExpr= */ "authoremail:\"^User$\"",
        SubmitRequirementResult.Status.UNSATISFIED);
  }

  private void checkSubmitRequirementResult(
      ChangeData cd, String submittabilityExpr, SubmitRequirementResult.Status expectedStatus) {
    SubmitRequirement sr =
        createSubmitRequirement(
            /* applicabilityExpr= */ "project:" + project.get(),
            submittabilityExpr,
            /* overrideExpr= */ "");

    SubmitRequirementResult result = evaluator.evaluateRequirement(sr, cd);
    assertThat(result.status()).isEqualTo(expectedStatus);
  }

  @Test
  public void byFileEdits_deletedContent_matching() throws Exception {
    Change.Id parent = changeOperations.newChange().file(FILE_NAME).content(CONTENT).create();
    Change.Id childId =
        changeOperations
            .newChange()
            .file(FILE_NAME)
            .content(CONTENT.replace("line 2\n", ""))
            .childOf()
            .change(parent)
            .create();

    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create("file:\"'^.*\\.txt',withDiffContaining='line 2'\"");

    ChangeData childChangeData = changeQueryProvider.get().byLegacyChangeId(childId).get(0);
    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, childChangeData);
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.PASS);
  }

  @Test
  public void byFileEdits_deletedContent_nonMatching() throws Exception {
    Change.Id parent = changeOperations.newChange().file(FILE_NAME).content(CONTENT).create();
    Change.Id childId =
        changeOperations
            .newChange()
            .file(FILE_NAME)
            .content(CONTENT.replace("line 1\n", ""))
            .childOf()
            .change(parent)
            .create();

    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create("file:\"'^.*\\.txt',withDiffContaining='line 2'\"");

    ChangeData childChangeData = changeQueryProvider.get().byLegacyChangeId(childId).get(0);
    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, childChangeData);
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.FAIL);
  }

  @Test
  public void byFileEdits_addedContent_matching() throws Exception {
    Change.Id parent = changeOperations.newChange().file(FILE_NAME).content(CONTENT).create();
    Change.Id childId =
        changeOperations
            .newChange()
            .file(FILE_NAME)
            .content(CONTENT + "line 4\n")
            .childOf()
            .change(parent)
            .create();

    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create("file:\"'^.*\\.txt',withDiffContaining='line 4'\"");

    ChangeData childChangeData = changeQueryProvider.get().byLegacyChangeId(childId).get(0);
    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, childChangeData);
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.PASS);
  }

  @Test
  public void byFileEdits_addedContent_nonMatching() throws Exception {
    Change.Id parent = changeOperations.newChange().file(FILE_NAME).content(CONTENT).create();
    Change.Id childId =
        changeOperations
            .newChange()
            .file(FILE_NAME)
            .content(CONTENT + "line 4\n")
            .childOf()
            .change(parent)
            .create();

    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create("file:\"'^.*\\.txt',withDiffContaining='line 5'\"");

    ChangeData childChangeData = changeQueryProvider.get().byLegacyChangeId(childId).get(0);
    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, childChangeData);
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.FAIL);
  }

  @Test
  public void byFileEdits_addedFile_matching() throws Exception {
    Change.Id parent = changeOperations.newChange().file(FILE_NAME).content(CONTENT).create();
    Change.Id childId =
        changeOperations
            .newChange()
            .file("new_file.txt")
            .content("content of the new file")
            .childOf()
            .change(parent)
            .create();

    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create(
            "file:\"'^new.*\\\\.txt',withDiffContaining='of the new'\"");

    ChangeData childChangeData = changeQueryProvider.get().byLegacyChangeId(childId).get(0);
    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, childChangeData);
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.PASS);
  }

  @Test
  public void byFileEdits_addedFile_nonMatching() throws Exception {
    Change.Id parent = changeOperations.newChange().file(FILE_NAME).content(CONTENT).create();
    Change.Id childId =
        changeOperations
            .newChange()
            .file("new_file.txt")
            .content("content of the new file")
            .childOf()
            .change(parent)
            .create();

    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create(
            "file:\"'^new.*\\.txt',withDiffContaining='not_exist'\"");

    ChangeData childChangeData = changeQueryProvider.get().byLegacyChangeId(childId).get(0);
    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, childChangeData);
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.FAIL);
  }

  @Test
  public void byFileEdits_modifiedContent_matching() throws Exception {
    Change.Id parent = changeOperations.newChange().file(FILE_NAME).content(CONTENT).create();
    Change.Id childId =
        changeOperations
            .newChange()
            .file(FILE_NAME)
            .content(CONTENT.replace("line 3\n", "line three\n"))
            .childOf()
            .change(parent)
            .create();

    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create("file:\"'^.*\\.txt',withDiffContaining='three'\"");

    ChangeData childChangeData = changeQueryProvider.get().byLegacyChangeId(childId).get(0);
    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, childChangeData);
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.PASS);
  }

  @Test
  public void byFileEdits_modifiedContent_nonMatching() throws Exception {
    Change.Id parent = changeOperations.newChange().file(FILE_NAME).content(CONTENT).create();
    Change.Id childId =
        changeOperations
            .newChange()
            .file(FILE_NAME)
            .content(CONTENT.replace("line 3\n", "line three\n"))
            .childOf()
            .change(parent)
            .create();

    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create("file:\"'^.*\\.txt',withDiffContaining='ten'\"");

    ChangeData childChangeData = changeQueryProvider.get().byLegacyChangeId(childId).get(0);
    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, childChangeData);
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.FAIL);
  }

  @Test
  public void byFileEdits_modifiedContentPattern_matching() throws Exception {
    Change.Id parent = changeOperations.newChange().file(FILE_NAME).content(CONTENT).create();
    Change.Id childId =
        changeOperations
            .newChange()
            .file(FILE_NAME)
            .content(CONTENT.replace("line 3\n", "line three\n"))
            .childOf()
            .change(parent)
            .create();

    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create(
            "file:\"'^.*\\.txt',withDiffContaining='^.*th[rR]ee$'\"");

    ChangeData childChangeData = changeQueryProvider.get().byLegacyChangeId(childId).get(0);
    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, childChangeData);
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.PASS);
  }

  @Test
  public void byFileEdits_exactMatchingWithFilePath_matching() throws Exception {
    Change.Id parent = changeOperations.newChange().file(FILE_NAME).content(CONTENT).create();
    Change.Id childId =
        changeOperations
            .newChange()
            .file(FILE_NAME)
            .content(CONTENT.replace("line 3\n", "line three\n"))
            .childOf()
            .change(parent)
            .create();

    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create(
            String.format("file:\"'%s',withDiffContaining='three'\"", FILE_NAME));

    ChangeData childChangeData = changeQueryProvider.get().byLegacyChangeId(childId).get(0);
    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, childChangeData);
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.PASS);
  }

  @Test
  public void byFileEdits_exactMatchingWithFilePath_nonMatching() throws Exception {
    Change.Id parent = changeOperations.newChange().file(FILE_NAME).content(CONTENT).create();
    Change.Id childId =
        changeOperations
            .newChange()
            .file(FILE_NAME)
            .content(CONTENT.replace("line 3\n", "line three\n"))
            .childOf()
            .change(parent)
            .create();

    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create(
            "file:\"'non_existent.txt',withDiffContaining='three'\"");

    ChangeData childChangeData = changeQueryProvider.get().byLegacyChangeId(childId).get(0);
    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, childChangeData);
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.FAIL);
  }

  @Test
  public void byFileEdits_notMatchingWithFilePath() throws Exception {
    Change.Id parent = changeOperations.newChange().file(FILE_NAME).content(CONTENT).create();
    Change.Id childId =
        changeOperations
            .newChange()
            .file(FILE_NAME)
            .content(CONTENT.replace("line 3\n", "line three\n"))
            .childOf()
            .change(parent)
            .create();

    // commit edit only matches with files ending with ".java". Since our modified file name ends
    // with ".txt", the applicability expression will not match.
    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create("file:\"'^.*\\.java',withDiffContaining='three'\"");

    ChangeData childChangeData = changeQueryProvider.get().byLegacyChangeId(childId).get(0);
    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, childChangeData);
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.FAIL);
  }

  @Test
  public void byFileEdits_escapeSingleQuotes() throws Exception {
    Change.Id parent = changeOperations.newChange().file(FILE_NAME).content(CONTENT).create();
    Change.Id childId =
        changeOperations
            .newChange()
            .file(FILE_NAME)
            .content(CONTENT.replace("line 3\n", "line 'three' is modified\n"))
            .childOf()
            .change(parent)
            .create();

    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create(
            "file:\"'^.*\\.txt',withDiffContaining='line \\'three\\' is'\"");

    ChangeData childChangeData = changeQueryProvider.get().byLegacyChangeId(childId).get(0);
    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, childChangeData);
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.PASS);
  }

  @Test
  public void byFileEdits_doubleEscapeSingleQuote() throws Exception {
    Change.Id parent = changeOperations.newChange().file(FILE_NAME).content(CONTENT).create();
    Change.Id childId =
        changeOperations
            .newChange()
            .file(FILE_NAME)
            // This will be written to the file as: line \'three\' is modified.
            .content(CONTENT.replace("line 3\n", "line \\'three\\' is modified\n"))
            .childOf()
            .change(parent)
            .create();

    // Users can still provide back-slashes in regexes by escaping them.
    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create(
            "file:\"'^.*\\.txt',withDiffContaining='line \\\\'three\\\\' is'\"");

    ChangeData childChangeData = changeQueryProvider.get().byLegacyChangeId(childId).get(0);
    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, childChangeData);
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.PASS);
  }

  @Test
  public void byFileEdits_escapeDoubleQuotes() throws Exception {
    Change.Id parent = changeOperations.newChange().file(FILE_NAME).content(CONTENT).create();
    Change.Id childId =
        changeOperations
            .newChange()
            .file(FILE_NAME)
            .content(CONTENT.replace("line 3\n", "line \"three\" is modified\n"))
            .childOf()
            .change(parent)
            .create();

    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create(
            "file:\"'^.*\\.txt',withDiffContaining='line \\\"three\\\" is'\"");

    ChangeData childChangeData = changeQueryProvider.get().byLegacyChangeId(childId).get(0);
    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, childChangeData);
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.PASS);
  }

  @Test
  public void byFileEdits_invalidSyntax() throws Exception {
    Change.Id parent = changeOperations.newChange().file(FILE_NAME).content(CONTENT).create();
    Change.Id childId =
        changeOperations
            .newChange()
            .file(FILE_NAME)
            .content(CONTENT.replace("line 3\n", "line three\n"))
            .childOf()
            .change(parent)
            .create();

    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create(
            "file:\"'^.*\\.txt',withDiffContaining=forgot single quotes\"");

    ChangeData childChangeData = changeQueryProvider.get().byLegacyChangeId(childId).get(0);
    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, childChangeData);
    // If the format is invalid, the operator falls back to the default operator of
    // ChangeQueryBuilder which does not match the change, i.e. returns false.
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.FAIL);
  }

  @Test
  public void byFileEdits_invalidFilePattern() throws Exception {
    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create("file:\"'^**',withDiffContaining='content'\"");

    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, changeData);
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.ERROR);
    assertThat(srResult.errorMessage().get()).isEqualTo("Invalid file pattern.");
  }

  @Test
  public void byFileEdits_invalidContentPattern() throws Exception {
    SubmitRequirementExpression exp =
        SubmitRequirementExpression.create("file:\"'fileName\\.txt',withDiffContaining='^**'\"");

    SubmitRequirementExpressionResult srResult = evaluator.evaluateExpression(exp, changeData);
    assertThat(srResult.status()).isEqualTo(SubmitRequirementExpressionResult.Status.ERROR);
    assertThat(srResult.errorMessage().get()).isEqualTo("Invalid content pattern.");
  }

  private void voteLabel(String changeId, String labelName, int score) throws RestApiException {
    gApi.changes().id(changeId).current().review(new ReviewInput().label(labelName, score));
  }

  private void addLabel(String labelName) throws Exception {
    configLabel(
        project,
        labelName,
        LabelFunction.NO_OP,
        value(1, "ok"),
        value(0, "No score"),
        value(-1, "Needs work"));

    projectOperations
        .project(project)
        .forUpdate()
        .add(allowLabel(labelName).ref("refs/heads/master").group(REGISTERED_USERS).range(-1, +1))
        .update();
  }

  private SubmitRequirement createSubmitRequirement(
      @Nullable String applicabilityExpr,
      String submittabilityExpr,
      @Nullable String overrideExpr) {
    return createSubmitRequirement(
        /*name= */ "sr-name",
        applicabilityExpr,
        submittabilityExpr,
        overrideExpr,
        /*allowOverrideInChildProjects=*/ false);
  }

  private SubmitRequirement createSubmitRequirement(
      String name,
      @Nullable String applicabilityExpr,
      String submittabilityExpr,
      @Nullable String overrideExpr,
      boolean allowOverrideInChildProjects) {
    return SubmitRequirement.builder()
        .setName(name)
        .setDescription(Optional.of("sr-description"))
        .setApplicabilityExpression(SubmitRequirementExpression.of(applicabilityExpr))
        .setSubmittabilityExpression(SubmitRequirementExpression.create(submittabilityExpr))
        .setOverrideExpression(SubmitRequirementExpression.of(overrideExpr))
        .setAllowOverrideInChildProjects(allowOverrideInChildProjects)
        .build();
  }

  /** Submit requirement predicate that always throws an error on match. */
  static class ThrowingSubmitRequirementPredicate extends SubmitRequirementPredicate
      implements ChangeIsOperandFactory {

    public static final String OPERAND = "throwing-predicate";

    public static final String ERROR_MESSAGE = "Error is storage";

    public ThrowingSubmitRequirementPredicate() {
      super("is", OPERAND);
    }

    @Override
    public boolean match(ChangeData object) {
      throw new SubmitRequirementEvaluationException(ERROR_MESSAGE);
    }

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

    @Override
    public Predicate<ChangeData> create(ChangeQueryBuilder builder) throws QueryParseException {
      return this;
    }
  }
}
