// Copyright (C) 2020 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.rest.change;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.extensions.restapi.testing.AttentionSetUpdateSubject.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.truth.Correspondence;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.UseClockStep;
import com.google.gerrit.acceptance.config.GerritConfig;
import com.google.gerrit.acceptance.testsuite.account.AccountOperations;
import com.google.gerrit.acceptance.testsuite.change.ChangeOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.AttentionSetUpdate;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Patch;
import com.google.gerrit.extensions.api.changes.AddReviewerInput;
import com.google.gerrit.extensions.api.changes.AttentionSetInput;
import com.google.gerrit.extensions.api.changes.DeleteReviewerInput;
import com.google.gerrit.extensions.api.changes.HashtagsInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo.EmailStrategy;
import com.google.gerrit.extensions.client.ReviewerState;
import com.google.gerrit.extensions.client.Side;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.gerrit.testing.FakeEmailSender;
import com.google.gerrit.testing.TestCommentHelper;
import com.google.gerrit.truth.NullAwareCorrespondence;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.LongSupplier;
import java.util.stream.Collectors;
import org.junit.Before;
import org.junit.Test;

@NoHttpd
@UseClockStep(clockStepUnit = TimeUnit.MINUTES)
public class AttentionSetIT extends AbstractDaemonTest {

  @Inject private ChangeOperations changeOperations;
  @Inject private AccountOperations accountOperations;
  @Inject private RequestScopeOperations requestScopeOperations;

  @Inject private FakeEmailSender email;
  @Inject private TestCommentHelper testCommentHelper;
  @Inject private Provider<InternalChangeQuery> changeQueryProvider;

  /** Simulates a fake clock. Uses second granularity. */
  private static class FakeClock implements LongSupplier {
    Instant now = Instant.now();

    @Override
    public long getAsLong() {
      return TimeUnit.SECONDS.toMillis(now.getEpochSecond());
    }

    Instant now() {
      return Instant.ofEpochSecond(now.getEpochSecond());
    }

    void advance(Duration duration) {
      now = now.plus(duration);
    }
  }

  private FakeClock fakeClock = new FakeClock();

  @Before
  public void setUp() {
    TimeUtil.setCurrentMillisSupplier(fakeClock);
  }

  @Test
  public void emptyAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    assertThat(r.getChange().attentionSet()).isEmpty();
  }

  @Test
  public void addUser() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    int accountId =
        change(r).addToAttentionSet(new AttentionSetInput(user.email(), "first"))._accountId;
    assertThat(accountId).isEqualTo(user.id().get());
    AttentionSetUpdate expectedAttentionSetUpdate =
        AttentionSetUpdate.createFromRead(
            fakeClock.now(), user.id(), AttentionSetUpdate.Operation.ADD, "first");
    assertThat(r.getChange().attentionSet()).containsExactly(expectedAttentionSetUpdate);

    // Second add is ignored.
    accountId =
        change(r).addToAttentionSet(new AttentionSetInput(user.email(), "second"))._accountId;
    assertThat(accountId).isEqualTo(user.id().get());
    assertThat(r.getChange().attentionSet()).containsExactly(expectedAttentionSetUpdate);

    // Only one email since the second add was ignored.
    String emailBody = Iterables.getOnlyElement(email.getMessages()).body();
    assertThat(emailBody)
        .contains(
            user.fullName()
                + " added themselves to the attention set of this change.\n The reason is: first.");
  }

  @Test
  public void addMultipleUsers() throws Exception {
    PushOneCommit.Result r = createChange();
    Instant timestamp1 = fakeClock.now();
    int accountId1 =
        change(r).addToAttentionSet(new AttentionSetInput(user.email(), "user"))._accountId;
    assertThat(accountId1).isEqualTo(user.id().get());
    fakeClock.advance(Duration.ofSeconds(42));
    Instant timestamp2 = fakeClock.now();
    int accountId2 =
        change(r)
            .addToAttentionSet(new AttentionSetInput(admin.id().toString(), "admin"))
            ._accountId;
    assertThat(accountId2).isEqualTo(admin.id().get());

    AttentionSetUpdate expectedAttentionSetUpdate1 =
        AttentionSetUpdate.createFromRead(
            timestamp1, user.id(), AttentionSetUpdate.Operation.ADD, "user");
    AttentionSetUpdate expectedAttentionSetUpdate2 =
        AttentionSetUpdate.createFromRead(
            timestamp2, admin.id(), AttentionSetUpdate.Operation.ADD, "admin");
    assertThat(r.getChange().attentionSet())
        .containsExactly(expectedAttentionSetUpdate1, expectedAttentionSetUpdate2);
  }

  @Test
  public void removeUser() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addToAttentionSet(new AttentionSetInput(user.email(), "added"));
    requestScopeOperations.setApiUser(user.id());

    fakeClock.advance(Duration.ofSeconds(42));
    change(r).attention(user.id().toString()).remove(new AttentionSetInput("removed"));
    AttentionSetUpdate expectedAttentionSetUpdate =
        AttentionSetUpdate.createFromRead(
            fakeClock.now(), user.id(), AttentionSetUpdate.Operation.REMOVE, "removed");
    assertThat(r.getChange().attentionSet()).containsExactly(expectedAttentionSetUpdate);

    // Second removal is ignored.
    fakeClock.advance(Duration.ofSeconds(42));
    change(r).attention(user.id().toString()).remove(new AttentionSetInput("removed again"));
    assertThat(r.getChange().attentionSet()).containsExactly(expectedAttentionSetUpdate);

    // Only one email since the second remove was ignored.
    String emailBody = Iterables.getOnlyElement(email.getMessages()).body();
    assertThat(emailBody)
        .contains(
            user.fullName()
                + " removed themselves from the attention set of this change.\n"
                + " The reason is: removed.");
  }

  @Test
  public void removeUserWithInvalidUserInput() throws Exception {
    PushOneCommit.Result r = createChange();
    BadRequestException exception =
        assertThrows(
            BadRequestException.class,
            () ->
                change(r)
                    .attention(user.id().toString())
                    .remove(new AttentionSetInput("invalid user", "reason")));
    assertThat(exception.getMessage())
        .isEqualTo("The user specified in the input body couldn't be found.");

    exception =
        assertThrows(
            BadRequestException.class,
            () ->
                change(r)
                    .attention(user.id().toString())
                    .remove(new AttentionSetInput(admin.email(), "reason")));
    assertThat(exception.getMessage())
        .isEqualTo(
            "The field \"user\" must be empty, or must match the user specified in the URL.");
  }

  @Test
  public void removeUnrelatedUser() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).attention(user.id().toString()).remove(new AttentionSetInput("foo"));
    assertThat(r.getChange().attentionSet()).isEmpty();
  }

  @Test
  public void abandonRemovesUsers() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addToAttentionSet(new AttentionSetInput(user.email(), "user"));
    change(r).addToAttentionSet(new AttentionSetInput(admin.email(), "admin"));

    change(r).abandon();

    AttentionSetUpdate userUpdate =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(userUpdate).hasAccountIdThat().isEqualTo(user.id());
    assertThat(userUpdate).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(userUpdate).hasReasonThat().isEqualTo("Change was abandoned");

    AttentionSetUpdate adminUpdate =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
    assertThat(adminUpdate).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(adminUpdate).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(adminUpdate).hasReasonThat().isEqualTo("Change was abandoned");
  }

  @Test
  public void workInProgressRemovesUsers() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addToAttentionSet(new AttentionSetInput(user.email(), "reason"));

    change(r).setWorkInProgress();

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Change was marked work in progress");
  }

  @Test
  public void submitRemovesUsersForAllSubmittedChanges() throws Exception {
    PushOneCommit.Result r1 = createChange("refs/heads/master", "file1", "content");

    change(r1)
        .current()
        .review(ReviewInput.approve().addUserToAttentionSet(user.email(), "reason"));
    PushOneCommit.Result r2 = createChange("refs/heads/master", "file2", "content");
    change(r2)
        .current()
        .review(ReviewInput.approve().addUserToAttentionSet(user.email(), "reason"));

    change(r2).current().submit();

    // Attention set updates that relate to the admin (the person who replied) are filtered out.
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r1, user));

    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Change was submitted");

    // Attention set updates that relate to the admin (the person who replied) are filtered out.
    attentionSet = Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r2, user));

    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Change was submitted");
  }

  @Test
  public void robotSubmitsRemovesUsers() throws Exception {
    PushOneCommit.Result r1 = createChange("refs/heads/master", "file1", "content");

    change(r1)
        .current()
        .review(ReviewInput.approve().addUserToAttentionSet(user.email(), "reason"));

    TestAccount robot =
        accountCreator.create(
            "robot2", "robot2@example.com", "Ro Bot", "Ro", "Service Users", "Administrators");
    requestScopeOperations.setApiUser(robot.id());
    change(r1).current().submit();

    // Attention set updates that relate to the admin (the person who replied) are filtered out.
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r1, user));

    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Change was submitted");
  }

  @Test
  public void addedReviewersAreAddedToAttentionSetOnMergedChanges() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).current().review(ReviewInput.approve());
    change(r).current().submit();

    change(r).addReviewer(user.email());
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));

    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer was added");
  }

  @Test
  public void reviewersAddedAndRemovedFromAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();

    change(r).addReviewer(user.id().toString());

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer was added");

    change(r).reviewer(user.email()).remove();

    attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer/Cc was removed");
  }

  @Test
  public void removedCcRemovedFromAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();

    // Add cc
    AddReviewerInput input = new AddReviewerInput();
    input.reviewer = user.email();
    input.state = ReviewerState.CC;
    change(r).addReviewer(input);

    // Add them to the attention set
    AttentionSetInput attentionSetInput = new AttentionSetInput();
    attentionSetInput.user = user.email();
    attentionSetInput.reason = "reason";
    change(r).addToAttentionSet(attentionSetInput);

    // Remove them from cc
    change(r).reviewer(user.email()).remove();

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer/Cc was removed");
  }

  @Test
  public void reviewersAddedAndRemovedByEmailFromAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();

    change(r).addReviewer(user.email());

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer was added");

    change(r).reviewer(user.email()).remove();

    attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer/Cc was removed");
  }

  @Test
  public void reviewersInWorkProgressNotAddedToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setWorkInProgress();
    change(r).addReviewer(user.email());

    assertThat(r.getChange().attentionSet()).isEmpty();
  }

  @Test
  public void addingReviewerWhileMarkingWorkInProgressDoesntAddToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    ReviewInput reviewInput = ReviewInput.create().setWorkInProgress(true);
    AddReviewerInput addReviewerInput = new AddReviewerInput();
    addReviewerInput.state = ReviewerState.REVIEWER;
    addReviewerInput.reviewer = user.email();
    reviewInput.reviewers = ImmutableList.of(addReviewerInput);

    change(r).current().review(reviewInput);
    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void reviewersAddedAsReviewersAgainAreNotAddedToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();

    change(r).addReviewer(user.id().toString());
    change(r)
        .attention(user.id().toString())
        .remove(new AttentionSetInput("removed and not re-added when re-adding as reviewer"));

    change(r).addReviewer(user.id().toString());

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet)
        .hasReasonThat()
        .isEqualTo("removed and not re-added when re-adding as reviewer");
  }

  @Test
  public void ccsAreIgnored() throws Exception {
    PushOneCommit.Result r = createChange();
    AddReviewerInput addReviewerInput = new AddReviewerInput();
    addReviewerInput.state = ReviewerState.CC;
    addReviewerInput.reviewer = user.email();

    change(r).addReviewer(addReviewerInput);

    assertThat(r.getChange().attentionSet()).isEmpty();
  }

  @Test
  public void ccsConsideredSameAsRemovedForExistingReviewers() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addReviewer(user.email());

    AddReviewerInput addReviewerInput = new AddReviewerInput();
    addReviewerInput.state = ReviewerState.CC;
    addReviewerInput.reviewer = user.email();
    change(r).addReviewer(addReviewerInput);

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer/Cc was removed");
  }

  @Test
  public void robotReadyForReviewAddsAllReviewersToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setWorkInProgress();
    change(r).addReviewer(user.email());

    TestAccount robot =
        accountCreator.create(
            "robot1", "robot1@example.com", "Ro Bot", "Ro", "Service Users", "Administrators");
    requestScopeOperations.setApiUser(robot.id());
    change(r).setReadyForReview();
    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Change was marked ready for review");
  }

  @Test
  public void readyForReviewAddsAllReviewersToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setWorkInProgress();
    change(r).addReviewer(user.email());

    change(r).setReadyForReview();
    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Change was marked ready for review");
  }

  @Test
  public void readyForReviewWhileRemovingReviewerRemovesThemToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setWorkInProgress();
    change(r).addReviewer(user.email());

    ReviewInput reviewInput = ReviewInput.create().setReady(true);
    AddReviewerInput addReviewerInput = new AddReviewerInput();
    addReviewerInput.state = ReviewerState.CC;
    addReviewerInput.reviewer = user.email();
    reviewInput.reviewers = ImmutableList.of(addReviewerInput);
    change(r).addToAttentionSet(new AttentionSetInput(user.email(), "reason"));
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer/Cc was removed");
  }

  @Test
  public void readyForReviewWhileAddingReviewerAddsThemToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setWorkInProgress();

    ReviewInput reviewInput = ReviewInput.create().setReady(true).reviewer(user.email());
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer was added");
  }

  @Test
  public void reviewersAreNotAddedForNoReasonBecauseOfAnUpdate() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addToAttentionSet(new AttentionSetInput(user.email(), "user"));
    change(r).attention(user.id().toString()).remove(new AttentionSetInput("removed"));

    HashtagsInput hashtagsInput = new HashtagsInput();
    hashtagsInput.add = ImmutableSet.of("tag");
    change(r).setHashtags(hashtagsInput);

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("removed");
  }

  @Test
  public void reviewAddsManuallyAddedUserToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    ReviewInput reviewInput = ReviewInput.create().addUserToAttentionSet(user.email(), "reason");

    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");

    // No emails for adding to attention set were sent.
    email.getMessages().isEmpty();
  }

  @Test
  public void reviewRemovesManuallyRemovedUserFromAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addToAttentionSet(new AttentionSetInput(user.email(), "reason"));
    requestScopeOperations.setApiUser(user.id());

    ReviewInput reviewInput =
        ReviewInput.create().removeUserFromAttentionSet(user.email(), "reason");
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");

    // No emails for removing from attention set were sent.
    email.getMessages().isEmpty();
  }

  @Test
  public void reviewWithManualAdditionToAttentionSetFailsWithoutReason() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addToAttentionSet(new AttentionSetInput(user.email(), "reason"));

    ReviewInput reviewInput = ReviewInput.create().addUserToAttentionSet(user.email(), "");

    BadRequestException exception =
        assertThrows(BadRequestException.class, () -> change(r).current().review(reviewInput));

    assertThat(exception.getMessage()).isEqualTo("missing field: reason");
  }

  @Test
  public void reviewWithManualAdditionToAttentionSetFailsWithoutUser() throws Exception {
    PushOneCommit.Result r = createChange();
    ReviewInput reviewInput = ReviewInput.create().addUserToAttentionSet("", "reason");

    BadRequestException exception =
        assertThrows(BadRequestException.class, () -> change(r).current().review(reviewInput));

    assertThat(exception.getMessage()).isEqualTo("missing field: user");
  }

  @Test
  public void reviewAddReviewerWhileRemovingFromAttentionSetJustRemovesUser() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addToAttentionSet(new AttentionSetInput(user.email(), "addition"));

    ReviewInput reviewInput =
        ReviewInput.create()
            .reviewer(user.email())
            .removeUserFromAttentionSet(user.email(), "reason");

    change(r).current().review(reviewInput);

    // Attention set updates that relate to the admin (the person who replied) are filtered out.
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");
  }

  @Test
  public void cantAddAndRemoveSameUser() throws Exception {
    PushOneCommit.Result r = createChange();
    ReviewInput reviewInput =
        ReviewInput.create()
            .removeUserFromAttentionSet(user.email(), "reason")
            .addUserToAttentionSet(user.username(), "reason");

    BadRequestException exception =
        assertThrows(BadRequestException.class, () -> change(r).current().review(reviewInput));

    assertThat(exception.getMessage())
        .isEqualTo(
            "user can not be added/removed twice, and can not be added and removed at the same"
                + " time");
  }

  @Test
  public void cantRemoveSameUserTwice() throws Exception {
    PushOneCommit.Result r = createChange();
    ReviewInput reviewInput =
        ReviewInput.create()
            .removeUserFromAttentionSet(user.email(), "reason1")
            .removeUserFromAttentionSet(user.username(), "reason2");

    BadRequestException exception =
        assertThrows(BadRequestException.class, () -> change(r).current().review(reviewInput));

    assertThat(exception.getMessage())
        .isEqualTo(
            "user can not be added/removed twice, and can not be added and removed at the same"
                + " time");
  }

  @Test
  public void reviewDoesNotAddReviewerWithoutAutomaticRules() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    ReviewInput reviewInput = ReviewInput.recommend().blockAutomaticAttentionSetRules();

    change(r).current().review(reviewInput);
    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void reviewDoesNotAddReviewer() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    ReviewInput reviewInput = ReviewInput.recommend();

    change(r).current().review(reviewInput);
    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void cantAddSameUserTwice() throws Exception {
    PushOneCommit.Result r = createChange();
    ReviewInput reviewInput =
        ReviewInput.create()
            .addUserToAttentionSet(user.email(), "reason1")
            .addUserToAttentionSet(user.username(), "reason2");

    BadRequestException exception =
        assertThrows(BadRequestException.class, () -> change(r).current().review(reviewInput));

    assertThat(exception.getMessage())
        .isEqualTo(
            "user can not be added/removed twice, and can not be added and removed at the same"
                + " time");
  }

  @Test
  public void reviewRemoveFromAttentionSetWhileMarkingReadyForReviewJustRemovesUser()
      throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setWorkInProgress();
    change(r).addReviewer(user.email());
    change(r).addToAttentionSet(new AttentionSetInput(user.email(), "reason"));

    ReviewInput reviewInput =
        ReviewInput.create().setReady(true).removeUserFromAttentionSet(user.email(), "reason");

    change(r).current().review(reviewInput);

    // Attention set updates that relate to the admin (the person who replied) are filtered out.
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");
  }

  @Test
  public void reviewAddToAttentionSetWhileMarkingWorkInProgressJustAddsUser() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addReviewer(user.email());

    ReviewInput reviewInput =
        ReviewInput.create().setWorkInProgress(true).addUserToAttentionSet(user.email(), "reason");

    change(r).attention(user.email()).remove(new AttentionSetInput("removal"));
    change(r).current().review(reviewInput);

    // Attention set updates that relate to the admin (the person who replied) are filtered out.
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");
  }

  @Test
  public void reviewRemovesUserFromAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addToAttentionSet(new AttentionSetInput(admin.email(), "reason"));

    ReviewInput reviewInput = new ReviewInput();
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("removed on reply");
  }

  @Test
  public void reviewAddUserToAttentionSetWhileReplyingJustAddsUser() throws Exception {
    PushOneCommit.Result r = createChange();

    ReviewInput reviewInput = ReviewInput.create().addUserToAttentionSet(admin.email(), "reason");
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");
  }

  @Test
  public void reviewWhileAddingThemselvesAsReviewerStillRemovesThem() throws Exception {
    PushOneCommit.Result r = createChange();

    requestScopeOperations.setApiUser(user.id());

    change(r).addToAttentionSet(new AttentionSetInput(user.email(), "reason"));
    ReviewInput reviewInput = ReviewInput.create().reviewer(user.email());
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("removed on reply");
  }

  @Test
  public void reviewWhileAddingThemselvesAsReviewerDoesNotAddThem() throws Exception {
    PushOneCommit.Result r = createChange();

    requestScopeOperations.setApiUser(user.id());

    ReviewInput reviewInput = ReviewInput.create().reviewer(user.email());
    change(r).current().review(reviewInput);

    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void repliesAddsOwner() throws Exception {
    PushOneCommit.Result r = createChange();

    requestScopeOperations.setApiUser(user.id());

    ReviewInput reviewInput = new ReviewInput();
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Someone else replied on the change");
  }

  @Test
  public void repliesDoNotAddOwnerWhenChangeIsClosed() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).abandon();
    requestScopeOperations.setApiUser(user.id());

    ReviewInput reviewInput = new ReviewInput();
    change(r).current().review(reviewInput);

    assertThat(getAttentionSetUpdatesForUser(r, admin)).isEmpty();
  }

  @Test
  public void repliesDoNotAddOwnerWhenChangeIsWorkInProgress() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setWorkInProgress();
    requestScopeOperations.setApiUser(user.id());

    ReviewInput reviewInput = new ReviewInput();
    change(r).current().review(reviewInput);

    assertThat(getAttentionSetUpdatesForUser(r, admin)).isEmpty();
  }

  @Test
  public void repliesDoNotAddOwnerWhenChangeIsBecomingWorkInProgress() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(accountCreator.admin2().id());

    ReviewInput reviewInput = ReviewInput.create().setWorkInProgress(true);
    change(r).current().review(reviewInput);

    assertThat(getAttentionSetUpdatesForUser(r, admin)).isEmpty();
  }

  @Test
  public void repliesAddOwnerWhenChangeIsBecomingReadyForReview() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setWorkInProgress();
    requestScopeOperations.setApiUser(accountCreator.admin2().id());

    ReviewInput reviewInput = ReviewInput.create().setReady(true);
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Someone else replied on the change");
  }

  @Test
  public void repliesAddsOwnerAndUploader() throws Exception {
    // Create change with owner: admin
    PushOneCommit.Result r = createChange();
    r = amendChangeWithUploader(r, project, user);

    TestAccount user2 = accountCreator.user2();
    requestScopeOperations.setApiUser(user2.id());

    change(r).attention(user.email()).remove(new AttentionSetInput("reason"));
    ReviewInput reviewInput = new ReviewInput();
    change(r).current().review(reviewInput);

    reviewInput = new ReviewInput();
    change(r).current().review(reviewInput);

    // Uploader added
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Someone else replied on the change");

    // Owner added
    attentionSet = Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Someone else replied on the change");
  }

  @Test
  public void reviewIgnoresRobotCommentsForAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    testCommentHelper.addRobotComment(
        r.getChangeId(),
        TestCommentHelper.createRobotCommentInputWithMandatoryFields(Patch.COMMIT_MSG));

    requestScopeOperations.setApiUser(admin.id());
    change(r)
        .current()
        .review(
            reviewInReplyToComment(
                Iterables.getOnlyElement(
                        gApi.changes().id(r.getChangeId()).current().robotCommentsAsList())
                    .id));
    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void reviewAddsAllUsersInCommentThread() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    change(r).current().review(reviewWithComment());

    TestAccount user2 = accountCreator.user2();

    requestScopeOperations.setApiUser(user2.id());
    change(r)
        .current()
        .review(
            reviewInReplyToComment(
                Iterables.getOnlyElement(
                        gApi.changes().id(r.getChangeId()).current().commentsAsList())
                    .id));

    change(r).attention(user.email()).remove(new AttentionSetInput("removal"));
    requestScopeOperations.setApiUser(admin.id());
    change(r)
        .current()
        .review(
            reviewInReplyToComment(
                gApi.changes().id(r.getChangeId()).current().commentsAsList().get(1).id));

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet)
        .hasReasonThat()
        .isEqualTo("Someone else replied on a comment you posted");

    attentionSet = Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user2));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user2.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet)
        .hasReasonThat()
        .isEqualTo("Someone else replied on a comment you posted");
  }

  @Test
  public void reviewAddsAllUsersInCommentThreadWhenOriginalCommentIsARobotComment()
      throws Exception {
    PushOneCommit.Result result = createChange();
    testCommentHelper.addRobotComment(
        result.getChangeId(),
        TestCommentHelper.createRobotCommentInputWithMandatoryFields(Patch.COMMIT_MSG));

    requestScopeOperations.setApiUser(user.id());
    // Reply to the robot comment.
    change(result)
        .current()
        .review(
            reviewInReplyToComment(
                Iterables.getOnlyElement(
                        gApi.changes().id(result.getChangeId()).current().robotCommentsAsList())
                    .id));

    requestScopeOperations.setApiUser(admin.id());
    // Reply to the human comment. which was a reply to the robot comment.
    change(result)
        .current()
        .review(
            reviewInReplyToComment(
                Iterables.getOnlyElement(
                        gApi.changes().id(result.getChangeId()).current().commentsAsList())
                    .id));

    // The user which replied to the robot comment was added to the attention set.
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(result, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet)
        .hasReasonThat()
        .isEqualTo("Someone else replied on a comment you posted");
  }

  @Test
  public void reviewAddsAllUsersInCommentThreadEvenOfDifferentChildBranch() throws Exception {
    Account.Id changeOwner = accountOperations.newAccount().create();
    Change.Id changeId = changeOperations.newChange().owner(changeOwner).create();
    Account.Id user1 = accountOperations.newAccount().create();
    Account.Id user2 = accountOperations.newAccount().create();
    Account.Id user3 = accountOperations.newAccount().create();
    Account.Id user4 = accountOperations.newAccount().create();
    // Add users as reviewers.
    gApi.changes().id(changeId.get()).addReviewer(user1.toString());
    gApi.changes().id(changeId.get()).addReviewer(user2.toString());
    gApi.changes().id(changeId.get()).addReviewer(user3.toString());
    gApi.changes().id(changeId.get()).addReviewer(user4.toString());
    // Add a comment thread with branches. Such threads occur if people reply in parallel without
    // having seen/loaded the reply of another person.
    String root =
        changeOperations.change(changeId).currentPatchset().newComment().author(user1).create();
    String sibling1 =
        changeOperations
            .change(changeId)
            .currentPatchset()
            .newComment()
            .author(user2)
            .parentUuid(root)
            .create();
    String sibling2 =
        changeOperations
            .change(changeId)
            .currentPatchset()
            .newComment()
            .author(user3)
            .parentUuid(root)
            .create();
    changeOperations
        .change(changeId)
        .currentPatchset()
        .newComment()
        .author(user4)
        .parentUuid(sibling2)
        .create();
    // Clear the attention set. Necessary as we used Gerrit APIs above which affect the attention
    // set.
    AttentionSetInput clearAttention = new AttentionSetInput("clear attention set");
    gApi.changes().id(changeId.get()).attention(user1.toString()).remove(clearAttention);
    gApi.changes().id(changeId.get()).attention(user2.toString()).remove(clearAttention);
    gApi.changes().id(changeId.get()).attention(user3.toString()).remove(clearAttention);
    gApi.changes().id(changeId.get()).attention(user4.toString()).remove(clearAttention);

    requestScopeOperations.setApiUser(changeOwner);
    // Simulate that this reply is a child of sibling1 and thus parallel to sibling2 and its child.
    gApi.changes().id(changeId.get()).current().review(reviewInReplyToComment(sibling1));

    List<AttentionSetUpdate> attentionSetUpdates = getAttentionSetUpdates(changeId);
    assertThat(attentionSetUpdates)
        .comparingElementsUsing(hasAccount())
        .containsExactly(user1, user2, user3, user4);
  }

  @Test
  public void reviewAddsAllUsersInCommentThreadWhenPostedAsDraft() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    change(r).current().review(reviewWithComment());

    requestScopeOperations.setApiUser(admin.id());
    testCommentHelper.addDraft(
        r.getChangeId(),
        testCommentHelper.newDraft(
            "message",
            Iterables.getOnlyElement(gApi.changes().id(r.getChangeId()).current().commentsAsList())
                .id));

    ReviewInput reviewInput = new ReviewInput();
    reviewInput.drafts = ReviewInput.DraftHandling.PUBLISH;
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet)
        .hasReasonThat()
        .isEqualTo("Someone else replied on a comment you posted");
  }

  @Test
  public void reviewDoesNotAddUsersInACommentThreadThatAreNotActiveInTheChange() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    change(r).current().review(reviewWithComment());
    change(r).reviewer(user.id().toString()).remove(new DeleteReviewerInput());

    requestScopeOperations.setApiUser(admin.id());
    change(r)
        .current()
        .review(
            reviewInReplyToComment(
                Iterables.getOnlyElement(
                        gApi.changes().id(r.getChangeId()).current().commentsAsList())
                    .id));

    // The user was to be added, but was not added since that user is no longer a
    // reviewer/cc/owner/uploader.
    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void ownerRepliesWhileRemovingReviewerRemovesFromAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addReviewer(user.email());

    ReviewInput reviewInput = ReviewInput.create().reviewer(user.email(), ReviewerState.CC, false);
    change(r).current().review(reviewInput);

    // cc removed
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer/Cc was removed");
  }

  @Test
  public void uploaderRepliesAddsOwner() throws Exception {
    PushOneCommit.Result r = createChange();
    r = amendChangeWithUploader(r, project, user);

    // Add reviewer and cc
    TestAccount reviewer = accountCreator.user2();
    TestAccount cc = accountCreator.admin2();
    ReviewInput reviewInput = new ReviewInput().blockAutomaticAttentionSetRules();
    reviewInput = reviewInput.reviewer(reviewer.email());
    reviewInput.reviewer(cc.email(), ReviewerState.CC, false);
    change(r).current().review(reviewInput);

    requestScopeOperations.setApiUser(user.id());

    change(r).current().review(new ReviewInput());

    // Reviewer and CC not added since the uploader didn't reply to their comments
    assertThat(getAttentionSetUpdatesForUser(r, cc)).isEmpty();
    assertThat(getAttentionSetUpdatesForUser(r, reviewer)).isEmpty();

    // Owner added
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Someone else replied on the change");
  }

  @Test
  public void repliesWhileAddingAsReviewerStillRemovesUser() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addToAttentionSet(new AttentionSetInput(user.email(), "remove"));

    requestScopeOperations.setApiUser(user.id());
    ReviewInput reviewInput = ReviewInput.recommend();
    change(r).current().review(reviewInput);

    // reviewer removed
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("removed on reply");
  }

  @Test
  public void attentionSetUnchangedWithIgnoreAutomaticAttentionSetRules() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addToAttentionSet(new AttentionSetInput(admin.email(), "reason"));
    change(r)
        .current()
        .review(
            ReviewInput.create()
                .reviewer(admin.email(), ReviewerState.CC, false)
                .blockAutomaticAttentionSetRules());

    // admin is still in the attention set, although replies remove from attention set, and removing
    // from reviewer also should remove from attention set.
    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");
  }

  @Test
  public void ownerNotAddedAsReviewerToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).current().review(ReviewInput.approve());
    assertThat(getAttentionSetUpdatesForUser(r, admin)).isEmpty();
  }

  @Test
  public void ownerNotAddedAsReviewerToAttentionSetWithoutAutomaticRules() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).current().review(ReviewInput.approve().blockAutomaticAttentionSetRules());
    assertThat(getAttentionSetUpdatesForUser(r, admin)).isEmpty();
  }

  @Test
  public void uploaderNotAddedAsReviewerToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    amendChangeWithUploader(r, project, user);
    requestScopeOperations.setApiUser(user.id());

    change(r).current().review(ReviewInput.recommend());
    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void uploaderNotAddedAsReviewerToAttentionSetWithoutAutomaticRules() throws Exception {
    PushOneCommit.Result r = createChange();
    amendChangeWithUploader(r, project, user);
    requestScopeOperations.setApiUser(user.id());

    change(r).current().review(ReviewInput.recommend().blockAutomaticAttentionSetRules());
    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void attentionSetStillChangesWithIgnoreAutomaticAttentionSetRulesWithInputList()
      throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addToAttentionSet(new AttentionSetInput(admin.email(), "reason"));
    change(r)
        .current()
        .review(
            ReviewInput.create()
                .removeUserFromAttentionSet(admin.email(), "removed")
                .blockAutomaticAttentionSetRules());

    // Admin is still removed although we block default attention set rules, since we remove
    // the admin manually.
    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("removed");
  }

  @Test
  public void robotsNotAddedToAttentionSet() throws Exception {
    TestAccount robot =
        accountCreator.create("robot1", "robot1@example.com", "Ro Bot", "Ro", "Service Users");
    PushOneCommit.Result r = createChange();

    // Throw an error when adding a robot explicitly.
    BadRequestException exception =
        assertThrows(
            BadRequestException.class,
            () -> change(r).addToAttentionSet(new AttentionSetInput(robot.email(), "reason")));
    assertThat(exception.getMessage())
        .isEqualTo(
            "robot1@example.com is a robot, and robots can't be added to the attention set.");

    // Robots are not added implicitly.
    change(r).addReviewer(robot.email());
    assertThat(r.getChange().attentionSet()).isEmpty();
  }

  @Test
  public void robotAddingAReviewerChangeAttentionSet() throws Exception {
    TestAccount robot =
        accountCreator.create("robot2", "robot2@example.com", "Ro Bot", "Ro", "Service Users");
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(robot.id());
    change(r).addReviewer(user.id().toString());

    // Bots can still change the attention set, just not when replying.
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer was added");
  }

  @Test
  public void robotReviewDoesNotChangeAttentionSet() throws Exception {
    TestAccount robot =
        accountCreator.create("robot2", "robot2@example.com", "Ro Bot", "Ro", "Service Users");
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(robot.id());
    change(r).current().review(ReviewInput.recommend());

    assertThat(r.getChange().attentionSet()).isEmpty();
  }

  @Test
  public void robotReviewWithNegativeLabelAddsOwner() throws Exception {
    TestAccount robot =
        accountCreator.create("robot2", "robot2@example.com", "Ro Bot", "Ro", "Service Users");
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(robot.id());
    change(r).current().review(ReviewInput.dislike());

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("A robot voted negatively on a label");
  }

  @Test
  public void robotCommentDoesNotAddOwnerOnClosedChanges() throws Exception {
    TestAccount robot =
        accountCreator.create("robot2", "robot2@example.com", "Ro Bot", "Ro", "Service Users");
    PushOneCommit.Result r = createChange();
    gApi.changes().id(r.getChangeId()).abandon();

    requestScopeOperations.setApiUser(robot.id());
    ReviewInput reviewInput = new ReviewInput();
    ReviewInput.RobotCommentInput robotCommentInput =
        TestCommentHelper.createRobotCommentInputWithMandatoryFields("a.txt");
    reviewInput.robotComments = ImmutableMap.of("a.txt", ImmutableList.of(robotCommentInput));
    change(r).current().review(reviewInput);

    assertThat(r.getChange().attentionSet()).isEmpty();
  }

  @Test
  public void robotCanChangeAttentionSetExplicitly() throws Exception {
    TestAccount robot =
        accountCreator.create("robot2", "robot2@example.com", "Ro Bot", "Ro", "Service Users");
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(robot.id());
    change(r).current().review(new ReviewInput().addUserToAttentionSet(admin.email(), "reason"));

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");
  }

  @Test
  public void addUsersToAttentionSetInPrivateChanges() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setPrivate(true);
    change(r).current().review(new ReviewInput().addUserToAttentionSet(user.email(), "reason"));

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");
  }

  @Test
  public void addUsersAsReviewerAndAttentionSetInPrivateChanges() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setPrivate(true);
    change(r).current().review(new ReviewInput().reviewer(user.email()));

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer was added");
  }

  @Test
  public void attentionSetEmailFooter() throws Exception {
    PushOneCommit.Result r = createChange();

    // Add user to attention set. They receive an email with the attention footer.
    change(r).addReviewer(user.id().toString());
    assertThat(Iterables.getOnlyElement(sender.getMessages()).body())
        .contains("Gerrit-Attention: " + user.fullName());
    sender.clear();

    // Irrelevant reply, User is still in the attention set.
    change(r).current().review(ReviewInput.approve());
    assertThat(Iterables.getOnlyElement(sender.getMessages()).body())
        .contains("Gerrit-Attention: " + user.fullName());
    sender.clear();

    // Abandon the change which removes user from attention set; there is an email but without the
    // attention footer.
    change(r).abandon();
    assertThat(Iterables.getOnlyElement(sender.getMessages()).body())
        .doesNotContain("Gerrit-Attention: " + user.fullName());
    sender.clear();
  }

  @Test
  @GerritConfig(name = "change.enableAttentionSet", value = "true")
  public void attentionSetEmailHeader() throws Exception {
    PushOneCommit.Result r = createChange();
    TestAccount user2 = accountCreator.user2();
    // Add user and user2 to the attention set.
    change(r)
        .current()
        .review(
            ReviewInput.create().reviewer(user.email()).reviewer(accountCreator.user2().email()));
    assertThat(Iterables.getOnlyElement(sender.getMessages()).body())
        .contains(
            "Attention is currently required from: "
                + user2.fullName()
                + ", "
                + user.fullName()
                + ".");
    assertThat(Iterables.getOnlyElement(sender.getMessages()).htmlBody())
        .contains(
            "Attention is currently required from: "
                + user2.fullName()
                + ", "
                + user.fullName()
                + ".");
    sender.clear();

    // Irrelevant reply, User and User2 are still in the attention set.
    change(r).current().review(ReviewInput.approve());
    assertThat(Iterables.getOnlyElement(sender.getMessages()).body())
        .contains(
            "Attention is currently required from: "
                + user2.fullName()
                + ", "
                + user.fullName()
                + ".");
    assertThat(Iterables.getOnlyElement(sender.getMessages()).htmlBody())
        .contains(
            "Attention is currently required from: "
                + user2.fullName()
                + ", "
                + user.fullName()
                + ".");
    sender.clear();

    // Abandon the change which removes user from attention set; there is an email but without the
    // attention footer.
    change(r).abandon();
    assertThat(Iterables.getOnlyElement(sender.getMessages()).body())
        .doesNotContain("Attention is currently required");
    assertThat(Iterables.getOnlyElement(sender.getMessages()).htmlBody())
        .doesNotContain("Attention is currently required");
    sender.clear();
  }

  @Test
  @GerritConfig(name = "change.enableAttentionSet", value = "false")
  public void noReferenceToAttentionSetInEmailsWhenDisabled() throws Exception {
    PushOneCommit.Result r = createChange();
    // Add user and to the attention set.
    change(r).addReviewer(user.id().toString());

    // Attention set is not referenced.
    assertThat(Iterables.getOnlyElement(sender.getMessages()).body())
        .doesNotContain("Attention is currently required");
    assertThat(Iterables.getOnlyElement(sender.getMessages()).htmlBody())
        .doesNotContain("Attention is currently required");
    sender.clear();
  }

  @Test
  public void attentionSetWithEmailFilter() throws Exception {
    PushOneCommit.Result r = createChange();

    // Add preference for the user such that they only receive an email on changes that require
    // their attention.
    setEmailStrategyForUser(EmailStrategy.ATTENTION_SET_ONLY);

    // Add user to attention set. They receive an email since they are in the attention set.
    change(r).addReviewer(user.id().toString());
    assertThat(sender.getMessages()).isNotEmpty();
    sender.clear();

    // Irrelevant reply, User is still in the attention set, thus got another email.
    change(r).current().review(ReviewInput.approve());
    assertThat(sender.getMessages()).isNotEmpty();
    sender.clear();

    // Abandon the change which removes user from attention set; the user doesn't receive an email
    // since they are not in the attention set.
    change(r).abandon();
    assertThat(sender.getMessages()).isEmpty();
  }

  @Test
  public void attentionSetWithEmailFilterImpactingOnlyChangeEmails() throws Exception {
    // Add preference for the user such that they only receive an email on changes that require
    // their attention.
    setEmailStrategyForUser(EmailStrategy.ATTENTION_SET_ONLY);

    // Ensure emails that don't relate to changes are still sent.
    gApi.accounts().id(user.id().get()).generateHttpPassword();
    assertThat(sender.getMessages()).isNotEmpty();
  }

  @Test
  public void outsideAttentionSet_watchProjectEmailReceived() throws Exception {
    setEmailStrategyForUser(EmailStrategy.ATTENTION_SET_ONLY);

    requestScopeOperations.setApiUser(user.id());
    watch(project.get());

    createChange();

    assertThat(sender.getMessages()).isNotEmpty();
    sender.clear();
  }

  private void setEmailStrategyForUser(EmailStrategy es) throws Exception {
    requestScopeOperations.setApiUser(user.id());
    GeneralPreferencesInfo prefs = gApi.accounts().self().getPreferences();
    prefs.emailStrategy = es;
    gApi.accounts().self().setPreferences(prefs);
    requestScopeOperations.setApiUser(admin.id());
  }

  private List<AttentionSetUpdate> getAttentionSetUpdatesForUser(
      PushOneCommit.Result r, TestAccount account) {
    return getAttentionSetUpdates(r.getChange().getId()).stream()
        .filter(a -> a.account().equals(account.id()))
        .collect(Collectors.toList());
  }

  private List<AttentionSetUpdate> getAttentionSetUpdates(Change.Id changeId) {
    List<ChangeData> changeData = changeQueryProvider.get().byLegacyChangeId(changeId);
    if (changeData.size() != 1) {
      throw new IllegalStateException(
          String.format("Not exactly one change found for ID %s.", changeId));
    }
    return new ArrayList<>(Iterables.getOnlyElement(changeData).attentionSet());
  }

  private ReviewInput reviewWithComment() {
    return reviewInReplyToComment(null);
  }

  private ReviewInput reviewInReplyToComment(@Nullable String id) {
    ReviewInput.CommentInput comment = new ReviewInput.CommentInput();
    comment.side = Side.REVISION;
    comment.path = Patch.COMMIT_MSG;
    comment.message = "comment";
    comment.updated = TimeUtil.nowTs();
    comment.inReplyTo = id;
    ReviewInput reviewInput = new ReviewInput();
    reviewInput.comments = ImmutableMap.of(Patch.COMMIT_MSG, ImmutableList.of(comment));
    return reviewInput;
  }

  private Correspondence<AttentionSetUpdate, Account.Id> hasAccount() {
    return NullAwareCorrespondence.transforming(AttentionSetUpdate::account, "hasAccount");
  }
}
