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

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.gerrit.extensions.client.ReviewerState.CC;
import static com.google.gerrit.extensions.client.ReviewerState.REMOVED;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.util.Comparator.comparing;
import static java.util.Objects.requireNonNull;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.google.common.collect.Streams;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.entities.Address;
import com.google.gerrit.entities.BooleanProjectConfig;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.GroupDescription;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.PatchSetApproval;
import com.google.gerrit.extensions.api.changes.DeleteReviewerInput;
import com.google.gerrit.extensions.api.changes.NotifyHandling;
import com.google.gerrit.extensions.api.changes.ReviewerInfo;
import com.google.gerrit.extensions.api.changes.ReviewerInput;
import com.google.gerrit.extensions.api.changes.ReviewerResult;
import com.google.gerrit.extensions.client.ReviewerState;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountLoader;
import com.google.gerrit.server.account.AccountResolver;
import com.google.gerrit.server.account.GroupMembers;
import com.google.gerrit.server.change.ReviewerModifier.FailureBehavior;
import com.google.gerrit.server.change.ReviewerModifier.InternalReviewerInput;
import com.google.gerrit.server.change.ReviewerModifier.ReviewerModification;
import com.google.gerrit.server.change.ReviewerModifier.ReviewerModificationList;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.group.GroupResolver;
import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.mail.send.OutgoingEmailValidator;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.permissions.ChangePermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.RefPermission;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.update.ChangeContext;
import com.google.gerrit.server.update.PostUpdateContext;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Stream;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;

public class ReviewerModifier {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  public static final int DEFAULT_MAX_REVIEWERS_WITHOUT_CHECK = 10;
  public static final int DEFAULT_MAX_REVIEWERS = 20;

  /**
   * Controls which failures should be ignored.
   *
   * <p>If a failure is ignored the operation succeeds, but the reviewer is not added. If not
   * ignored a failure means that the operation fails.
   */
  public enum FailureBehavior {
    // All failures cause the operation to fail.
    FAIL,

    // Only not found failures cause the operation to fail, all other failures are ignored.
    IGNORE_EXCEPT_NOT_FOUND,

    // All failures are ignored.
    IGNORE_ALL;
  }

  private enum FailureType {
    NOT_FOUND,
    OTHER;
  }

  // TODO(dborowitz): Subclassing is not the right way to do this. We should instead use an internal
  // type in the public interfaces of ReviewerModifier, rather than passing around the REST API type
  // internally.
  public static class InternalReviewerInput extends ReviewerInput {
    /**
     * Behavior when identifying reviewers fails for any reason <em>besides</em> the input not
     * resolving to an account/group/email.
     */
    public FailureBehavior otherFailureBehavior = FailureBehavior.FAIL;

    /** Whether the visibility check for the reviewer account should be skipped. */
    public boolean skipVisibilityCheck = false;
  }

  public static InternalReviewerInput newReviewerInput(
      String reviewer, ReviewerState state, NotifyHandling notify) {
    InternalReviewerInput in = new InternalReviewerInput();
    in.reviewer = reviewer;
    in.state = state;
    in.notify = notify;
    return in;
  }

  public static Optional<InternalReviewerInput> newReviewerInputFromCommitIdentity(
      Change change,
      ObjectId commitId,
      @Nullable Account.Id accountId,
      NotifyHandling notify,
      Account.Id mostRecentUploader) {
    if (accountId == null || accountId.equals(mostRecentUploader)) {
      // If git ident couldn't be resolved to a user, or if it's not forged, do nothing.
      return Optional.empty();
    }

    logger.atFine().log(
        "Adding account %d from author/committer identity of commit %s as cc to change %d",
        accountId.get(), commitId.name(), change.getChangeId());

    InternalReviewerInput in = new InternalReviewerInput();
    in.reviewer = accountId.toString();
    in.state = CC;
    in.notify = notify;
    in.otherFailureBehavior = FailureBehavior.IGNORE_ALL;
    return Optional.of(in);
  }

  private final AccountResolver accountResolver;
  private final PermissionBackend permissionBackend;
  private final GroupResolver groupResolver;
  private final GroupMembers groupMembers;
  private final AccountLoader.Factory accountLoaderFactory;
  private final Config cfg;
  private final ReviewerJson json;
  private final ProjectCache projectCache;
  private final Provider<AnonymousUser> anonymousProvider;
  private final AddReviewersOp.Factory addReviewersOpFactory;
  private final OutgoingEmailValidator validator;
  private final DeleteReviewerOp.Factory deleteReviewerOpFactory;
  private final DeleteReviewerByEmailOp.Factory deleteReviewerByEmailOpFactory;

  @Inject
  ReviewerModifier(
      AccountResolver accountResolver,
      PermissionBackend permissionBackend,
      GroupResolver groupResolver,
      GroupMembers groupMembers,
      AccountLoader.Factory accountLoaderFactory,
      @GerritServerConfig Config cfg,
      ReviewerJson json,
      ProjectCache projectCache,
      Provider<AnonymousUser> anonymousProvider,
      AddReviewersOp.Factory addReviewersOpFactory,
      OutgoingEmailValidator validator,
      DeleteReviewerOp.Factory deleteReviewerOpFactory,
      DeleteReviewerByEmailOp.Factory deleteReviewerByEmailOpFactory) {
    this.accountResolver = accountResolver;
    this.permissionBackend = permissionBackend;
    this.groupResolver = groupResolver;
    this.groupMembers = groupMembers;
    this.accountLoaderFactory = accountLoaderFactory;
    this.cfg = cfg;
    this.json = json;
    this.projectCache = projectCache;
    this.anonymousProvider = anonymousProvider;
    this.addReviewersOpFactory = addReviewersOpFactory;
    this.validator = validator;
    this.deleteReviewerOpFactory = deleteReviewerOpFactory;
    this.deleteReviewerByEmailOpFactory = deleteReviewerByEmailOpFactory;
  }

  /**
   * Prepare application of a single {@link ReviewerInput}.
   *
   * @param notes change notes.
   * @param user user performing the reviewer addition.
   * @param input input describing user or group to add as a reviewer.
   * @param allowGroup whether to allow
   * @return handle describing the addition operation. If the {@code op} field is present, this
   *     operation may be added to a {@code BatchUpdate}. Otherwise, the {@code error} field
   *     contains information about an error that occurred
   */
  public ReviewerModification prepare(
      ChangeNotes notes, CurrentUser user, ReviewerInput input, boolean allowGroup)
      throws IOException, PermissionBackendException, ConfigInvalidException {
    try (TraceContext.TraceTimer ignored =
        TraceContext.newTimer(getClass().getSimpleName() + "#prepare", Metadata.empty())) {
      if (Strings.nullToEmpty(input.reviewer).trim().isEmpty()) {
        return fail(input, FailureType.NOT_FOUND, "reviewer user identifier is required");
      }

      boolean confirmed = input.confirmed();
      boolean allowByEmail =
          projectCache
              .get(notes.getProjectName())
              .orElseThrow(illegalState(notes.getProjectName()))
              .is(BooleanProjectConfig.ENABLE_REVIEWER_BY_EMAIL);

      ReviewerModification byAccountId = byAccountId(input, notes, user);

      ReviewerModification wholeGroup = null;
      if (!byAccountId.exactMatchFound) {
        wholeGroup = addWholeGroup(input, notes, user, confirmed, allowGroup, allowByEmail);
        if (wholeGroup != null && wholeGroup.exactMatchFound) {
          return wholeGroup;
        }
      }

      if (wholeGroup != null
          && byAccountId.failureType == FailureType.NOT_FOUND
          && wholeGroup.failureType == FailureType.NOT_FOUND) {
        return fail(
            byAccountId.input,
            FailureType.NOT_FOUND,
            byAccountId.result.error + "\n" + wholeGroup.result.error);
      }

      if (byAccountId.failureType != FailureType.NOT_FOUND) {
        return byAccountId;
      }
      if (wholeGroup != null) {
        return wholeGroup;
      }

      return addByEmail(input, notes, user);
    }
  }

  public ReviewerModification ccCurrentUser(CurrentUser user, RevisionResource revision) {
    return new ReviewerModification(
        newReviewerInput(user.getUserName().orElse(null), CC, NotifyHandling.NONE),
        revision.getNotes(),
        revision.getUser(),
        ImmutableSet.of(user.asIdentifiedUser().getAccount()),
        null,
        true,
        false);
  }

  @Nullable
  private ReviewerModification byAccountId(ReviewerInput input, ChangeNotes notes, CurrentUser user)
      throws PermissionBackendException, IOException, ConfigInvalidException {
    IdentifiedUser reviewerUser;
    boolean exactMatchFound = false;
    try {
      if (ReviewerState.REMOVED.equals(input.state)
          || (input instanceof InternalReviewerInput
              && ((InternalReviewerInput) input).skipVisibilityCheck)) {
        reviewerUser =
            accountResolver.resolveIncludeInactiveIgnoreVisibility(input.reviewer).asUniqueUser();
      } else {
        // First search only active accounts to see if only one unique account is returned
        AccountResolver.Result accountResolverResult = accountResolver.resolve(input.reviewer);

        if (accountResolverResult.asList().isEmpty()) {
          // Fallback to searching inactive account
          accountResolverResult = accountResolver.resolveIncludeInactive(input.reviewer);
        }

        reviewerUser = accountResolverResult.asUniqueUser();
      }
      if (input.reviewer.equalsIgnoreCase(reviewerUser.getName())
          || input.reviewer.equals(String.valueOf(reviewerUser.getAccountId()))) {
        exactMatchFound = true;
      }
    } catch (UnprocessableEntityException e) {
      // Caller might choose to ignore this NOT_FOUND result if they find another result e.g. by
      // group, but if not, the error message will be useful.
      return fail(input, FailureType.NOT_FOUND, e.getMessage());
    }

    // If the reviewer is removed, we do not have to perform the visibility check on the change
    if (ReviewerState.REMOVED.equals(input.state)
        || isValidReviewer(notes.getChange().getDest(), reviewerUser.getAccount())) {
      return new ReviewerModification(
          input,
          notes,
          user,
          ImmutableSet.of(reviewerUser.getAccount()),
          null,
          exactMatchFound,
          false);
    }
    return fail(
        input,
        FailureType.OTHER,
        MessageFormat.format(ChangeMessages.reviewerCantSeeChange, input.reviewer));
  }

  @Nullable
  private ReviewerModification addWholeGroup(
      ReviewerInput input,
      ChangeNotes notes,
      CurrentUser user,
      boolean confirmed,
      boolean allowGroup,
      boolean allowByEmail)
      throws IOException, PermissionBackendException {
    if (!allowGroup) {
      return null;
    }

    GroupDescription.Basic group;
    try {
      // TODO(dborowitz): This currently doesn't work in the push path because InternalGroupBackend
      // depends on the Provider<CurrentUser> which returns anonymous in that path.
      group = groupResolver.parse(input.reviewer);
    } catch (UnprocessableEntityException e) {
      if (!allowByEmail) {
        return fail(
            input,
            FailureType.NOT_FOUND,
            MessageFormat.format(ChangeMessages.reviewerNotFoundUserOrGroup, input.reviewer));
      }
      return null;
    }

    if (!isLegalReviewerGroup(group.getGroupUUID())) {
      return fail(
          input,
          FailureType.OTHER,
          MessageFormat.format(ChangeMessages.groupIsNotAllowed, group.getName()));
    }

    if (input.state().equals(REMOVED)) {
      return fail(
          input,
          FailureType.OTHER,
          MessageFormat.format(ChangeMessages.groupRemovalIsNotAllowed, group.getName()));
    }

    Set<Account> reviewers = new HashSet<>();
    Set<Account> members;
    try {
      members = groupMembers.listAccounts(group.getGroupUUID(), notes.getProjectName());
    } catch (NoSuchProjectException e) {
      return fail(input, FailureType.OTHER, e.getMessage());
    }

    // if maxAllowed is set to 0, it is allowed to add any number of
    // reviewers
    int maxAllowed = cfg.getInt("addreviewer", "maxAllowed", DEFAULT_MAX_REVIEWERS);
    if (maxAllowed > 0 && members.size() > maxAllowed) {
      logger.atFine().log(
          "Adding %d group members is not allowed (maxAllowed = %d)", members.size(), maxAllowed);
      return fail(
          input,
          FailureType.OTHER,
          MessageFormat.format(ChangeMessages.groupHasTooManyMembers, group.getName()));
    }

    // if maxWithoutCheck is set to 0, we never ask for confirmation
    int maxWithoutConfirmation =
        cfg.getInt("addreviewer", "maxWithoutConfirmation", DEFAULT_MAX_REVIEWERS_WITHOUT_CHECK);
    if (!confirmed && maxWithoutConfirmation > 0 && members.size() > maxWithoutConfirmation) {
      logger.atFine().log(
          "Adding %d group members as reviewer requires confirmation (maxWithoutConfirmation = %d)",
          members.size(), maxWithoutConfirmation);
      return fail(
          input,
          FailureType.OTHER,
          true,
          MessageFormat.format(
              ChangeMessages.groupManyMembersConfirmation, group.getName(), members.size()));
    }

    for (Account member : members) {
      if (isValidReviewer(notes.getChange().getDest(), member)) {
        reviewers.add(member);
      }
    }

    return new ReviewerModification(input, notes, user, reviewers, null, true, true);
  }

  @Nullable
  private ReviewerModification addByEmail(ReviewerInput input, ChangeNotes notes, CurrentUser user)
      throws PermissionBackendException {
    if (!permissionBackend
        .user(anonymousProvider.get())
        .change(notes)
        .test(ChangePermission.READ)) {
      return fail(
          input,
          FailureType.OTHER,
          MessageFormat.format(ChangeMessages.reviewerCantSeeChange, input.reviewer));
    }

    Address adr = Address.tryParse(input.reviewer);
    if (adr == null || !validator.isValid(adr.email())) {
      return fail(
          input,
          FailureType.NOT_FOUND,
          MessageFormat.format(ChangeMessages.reviewerInvalid, input.reviewer));
    }
    return new ReviewerModification(input, notes, user, null, ImmutableList.of(adr), true, false);
  }

  private boolean isValidReviewer(BranchNameKey branch, Account member)
      throws PermissionBackendException {
    // Check ref permission instead of change permission, since change permissions take into
    // account the private bit, whereas adding a user as a reviewer is explicitly allowing them to
    // see private changes.
    return permissionBackend.absentUser(member.id()).ref(branch).test(RefPermission.READ);
  }

  private ReviewerModification fail(ReviewerInput input, FailureType failureType, String error) {
    return fail(input, failureType, false, error);
  }

  private ReviewerModification fail(
      ReviewerInput input, FailureType failureType, boolean confirm, String error) {
    ReviewerModification addition = new ReviewerModification(input, failureType);
    addition.result.confirm = confirm ? true : null;
    addition.result.error = error;
    return addition;
  }

  public class ReviewerModification {
    public final ReviewerResult result;
    @Nullable public final ReviewerOp op;
    public final ImmutableSet<Account> reviewers;
    public final ImmutableSet<Address> reviewersByEmail;
    @Nullable final IdentifiedUser caller;
    final boolean exactMatchFound;
    private final ReviewerInput input;
    @Nullable private final FailureType failureType;

    private ReviewerModification(ReviewerInput input, FailureType failureType) {
      this.input = input;
      this.failureType = requireNonNull(failureType);
      result = new ReviewerResult(input.reviewer);
      op = null;
      reviewers = ImmutableSet.of();
      reviewersByEmail = ImmutableSet.of();
      caller = null;
      exactMatchFound = false;
    }

    private ReviewerModification(
        ReviewerInput input,
        ChangeNotes notes,
        CurrentUser caller,
        @Nullable Iterable<Account> reviewers,
        @Nullable Iterable<Address> reviewersByEmail,
        boolean exactMatchFound,
        boolean forGroup) {
      checkArgument(
          reviewers != null || reviewersByEmail != null,
          "must have either reviewers or reviewersByEmail");

      this.input = input;
      this.failureType = null;
      result = new ReviewerResult(input.reviewer);
      if (!state().equals(REMOVED)) {
        // Always silently ignore adding the owner as any type of reviewer on their own change. They
        // may still be implicitly added as a reviewer if they vote, but not via the reviewer API.
        this.reviewers = reviewersAsList(notes, reviewers, /* omitChangeOwner= */ true);
      } else {
        this.reviewers = reviewersAsList(notes, reviewers, /* omitChangeOwner= */ false);
      }
      this.reviewersByEmail =
          reviewersByEmail == null ? ImmutableSet.of() : ImmutableSet.copyOf(reviewersByEmail);
      this.caller = caller.asIdentifiedUser();
      if (state().equals(REMOVED)) {
        // only one is set.
        checkState(
            (this.reviewers.size() == 1 && this.reviewersByEmail.isEmpty())
                || (this.reviewers.isEmpty() && this.reviewersByEmail.size() == 1));
        if (this.reviewers.size() >= 1) {
          checkState(this.reviewers.size() == 1);
          DeleteReviewerInput deleteReviewerInput = new DeleteReviewerInput();
          deleteReviewerInput.notify = input.notify;
          deleteReviewerInput.notifyDetails = input.notifyDetails;
          op =
              deleteReviewerOpFactory.create(
                  Iterables.getOnlyElement(this.reviewers.asList()), deleteReviewerInput);
        } else {
          checkState(this.reviewersByEmail.size() == 1);
          op =
              deleteReviewerByEmailOpFactory.create(
                  Iterables.getOnlyElement(this.reviewersByEmail.asList()));
        }
      } else {
        op =
            addReviewersOpFactory.create(
                this.reviewers.stream().map(Account::id).collect(toImmutableSet()),
                this.reviewersByEmail,
                state(),
                forGroup);
      }
      this.exactMatchFound = exactMatchFound;
    }

    private ImmutableSet<Account> reviewersAsList(
        ChangeNotes notes, @Nullable Iterable<Account> reviewers, boolean omitChangeOwner) {
      if (reviewers == null) {
        return ImmutableSet.of();
      }

      Stream<Account> reviewerStream = Streams.stream(reviewers);
      if (omitChangeOwner) {
        reviewerStream =
            reviewerStream.filter(account -> !account.id().equals(notes.getChange().getOwner()));
      }
      return reviewerStream.collect(toImmutableSet());
    }

    public void gatherResults(ChangeData cd) throws PermissionBackendException {
      checkState(op != null, "addition did not result in an update op");
      checkState(op.getResult() != null, "op did not return a result");

      // Generate result details and fill AccountLoader. This occurs outside
      // the Op because the accounts are in a different table.
      ReviewerOp.Result opResult = op.getResult();
      switch (state()) {
        case CC -> {
          result.ccs = Lists.newArrayListWithCapacity(opResult.addedCCs().size());
          for (Account.Id accountId : opResult.addedCCs()) {
            result.ccs.add(json.format(new ReviewerInfo(accountId.get()), accountId, cd));
          }
          accountLoaderFactory.create(true).fill(result.ccs);
          for (Address a : opResult.addedCCsByEmail()) {
            result.ccs.add(new AccountInfo(a.name(), a.email()));
          }
        }
        case REVIEWER -> {
          result.reviewers = Lists.newArrayListWithCapacity(opResult.addedReviewers().size());
          for (PatchSetApproval psa : opResult.addedReviewers()) {
            // New reviewers have value 0, don't bother normalizing.
            result.reviewers.add(
                json.format(
                    new ReviewerInfo(psa.accountId().get()),
                    psa.accountId(),
                    cd,
                    ImmutableList.of(psa)));
          }
          accountLoaderFactory.create(true).fill(result.reviewers);
          for (Address a : opResult.addedReviewersByEmail()) {
            result.reviewers.add(ReviewerInfo.byEmail(a.name(), a.email()));
          }
        }
        case REMOVED -> {
          if (opResult.deletedReviewer().isPresent()) {
            result.removed =
                json.format(
                    new ReviewerInfo(opResult.deletedReviewer().get().get()),
                    opResult.deletedReviewer().get(),
                    cd);
            accountLoaderFactory.create(true).fill(ImmutableList.of(result.removed));
          } else if (opResult.deletedReviewerByEmail().isPresent()) {
            result.removed =
                new AccountInfo(
                    opResult.deletedReviewerByEmail().get().name(),
                    opResult.deletedReviewerByEmail().get().email());
          }
        }
        default ->
            throw new IllegalStateException(
                String.format("Illegal ReviewerState argument is %s", state().name()));
      }
    }

    public ReviewerState state() {
      return input.state();
    }

    public boolean isFailure() {
      return failureType != null;
    }

    public boolean isIgnorableFailure() {
      checkState(failureType != null);
      FailureBehavior behavior =
          (input instanceof InternalReviewerInput)
              ? ((InternalReviewerInput) input).otherFailureBehavior
              : FailureBehavior.FAIL;
      return behavior == FailureBehavior.IGNORE_ALL
          || (failureType == FailureType.OTHER
              && behavior == FailureBehavior.IGNORE_EXCEPT_NOT_FOUND);
    }
  }

  public static boolean isLegalReviewerGroup(AccountGroup.UUID groupUUID) {
    return groupUUID.isInternalGroup() || SystemGroupBackend.PROJECT_OWNERS.equals(groupUUID);
  }

  public ReviewerModificationList prepare(
      ChangeNotes notes,
      CurrentUser user,
      Iterable<? extends ReviewerInput> inputs,
      boolean allowGroup)
      throws IOException, PermissionBackendException, ConfigInvalidException {
    // Process CC ops before reviewer ops, so a user that appears in both lists ends up as a
    // reviewer; the last call to ChangeUpdate#putReviewer wins. This can happen if the caller
    // specifies the same string twice, or less obviously if they specify multiple groups with
    // overlapping members.
    // TODO(dborowitz): Consider changing interface to allow excluding reviewers that were
    // previously processed, to proactively prevent overlap so we don't have to rely on this subtle
    // behavior.
    ImmutableList<ReviewerInput> sorted =
        Streams.stream(inputs)
            .sorted(
                comparing(
                    ReviewerInput::state,
                    Ordering.explicit(ReviewerState.CC, ReviewerState.REVIEWER)))
            .collect(toImmutableList());
    List<ReviewerModification> additions = new ArrayList<>();
    for (ReviewerInput input : sorted) {
      ReviewerModification addition = prepare(notes, user, input, allowGroup);
      if (addition.op != null) {
        // Assume any callers preparing a list of batch insertions are handling their own email.
        addition.op.suppressEmail();
      }
      additions.add(addition);
    }
    return new ReviewerModificationList(additions);
  }

  // TODO(dborowitz): This class works, but ultimately feels wrong. It seems like an op but isn't
  // really an op, it's a collection of ops, and it's only called from the body of other ops. We
  // could make this class an op, but we would still have AddReviewersOp. Better would probably be
  // to design a single op that supports combining multiple ReviewerInputs together. That would
  // probably also subsume the Addition class itself, which would be a good thing.
  public static class ReviewerModificationList {
    private final ImmutableList<ReviewerModification> modifications;

    private ReviewerModificationList(List<ReviewerModification> modifications) {
      this.modifications = ImmutableList.copyOf(modifications);
    }

    public ImmutableList<ReviewerModification> getFailures() {
      return modifications.stream()
          .filter(a -> a.isFailure() && !a.isIgnorableFailure())
          .collect(toImmutableList());
    }

    // We never call updateRepo on the addition ops, which is only ok because it's a no-op.

    public void updateChange(ChangeContext ctx, PatchSet patchSet)
        throws RestApiException, IOException, PermissionBackendException {
      for (ReviewerModification addition : modifications()) {
        addition.op.setPatchSet(patchSet);

        @SuppressWarnings("unused")
        var unused = addition.op.updateChange(ctx);
      }
    }

    public void postUpdate(PostUpdateContext ctx) throws Exception {
      for (ReviewerModification addition : modifications()) {
        if (addition.op != null) {
          addition.op.postUpdate(ctx);
        }
      }
    }

    public <T> ImmutableSet<T> flattenResults(
        Function<ReviewerOp.Result, ? extends Collection<T>> func) {
      modifications()
          .forEach(
              a ->
                  checkArgument(
                      a.op != null && a.op.getResult() != null, "missing result on %s", a));
      return modifications().stream()
          .map(a -> a.op.getResult())
          .map(func)
          .flatMap(Collection::stream)
          .collect(toImmutableSet());
    }

    private ImmutableList<ReviewerModification> modifications() {
      return modifications.stream()
          .filter(
              a -> {
                if (a.isFailure()) {
                  if (a.isIgnorableFailure()) {
                    return false;
                  }
                  // Shouldn't happen, caller should have checked that there were no errors.
                  throw new IllegalStateException("error in addition: " + a.result.error);
                }
                return true;
              })
          .collect(toImmutableList());
    }
  }
}
