// 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.server.restapi.change;

import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static java.util.Objects.requireNonNull;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.collect.Sets.SetView;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.AttentionSetUpdate;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.extensions.api.changes.AttentionSetInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.server.CommentsUtil;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.DraftCommentsReader;
import com.google.gerrit.server.account.AccountResolver;
import com.google.gerrit.server.account.ServiceUserClassifier;
import com.google.gerrit.server.approval.ApprovalsUtil;
import com.google.gerrit.server.change.AddToAttentionSetOp;
import com.google.gerrit.server.change.AttentionSetUnchangedOp;
import com.google.gerrit.server.change.AttentionSetUpdateCondition;
import com.google.gerrit.server.change.CommentThread;
import com.google.gerrit.server.change.CommentThreads;
import com.google.gerrit.server.change.RemoveFromAttentionSetOp;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeUpdate;
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.update.BatchUpdate;
import com.google.gerrit.server.util.AttentionSetUtil;
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.inject.Inject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.jgit.errors.ConfigInvalidException;

/**
 * This class is used to update the attention set when performing a review or replying on a change.
 */
public class ReplyAttentionSetUpdates {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  private final PermissionBackend permissionBackend;
  private final AddToAttentionSetOp.Factory addToAttentionSetOpFactory;
  private final RemoveFromAttentionSetOp.Factory removeFromAttentionSetOpFactory;
  private final ApprovalsUtil approvalsUtil;
  private final AccountResolver accountResolver;
  private final ServiceUserClassifier serviceUserClassifier;
  private final CommentsUtil commentsUtil;
  private final DraftCommentsReader draftCommentsReader;

  @Inject
  ReplyAttentionSetUpdates(
      PermissionBackend permissionBackend,
      AddToAttentionSetOp.Factory addToAttentionSetOpFactory,
      RemoveFromAttentionSetOp.Factory removeFromAttentionSetOpFactory,
      ApprovalsUtil approvalsUtil,
      AccountResolver accountResolver,
      ServiceUserClassifier serviceUserClassifier,
      CommentsUtil commentsUtil,
      DraftCommentsReader draftCommentsReader) {
    this.permissionBackend = permissionBackend;
    this.addToAttentionSetOpFactory = addToAttentionSetOpFactory;
    this.removeFromAttentionSetOpFactory = removeFromAttentionSetOpFactory;
    this.approvalsUtil = approvalsUtil;
    this.accountResolver = accountResolver;
    this.serviceUserClassifier = serviceUserClassifier;
    this.commentsUtil = commentsUtil;
    this.draftCommentsReader = draftCommentsReader;
  }

  /** Adjusts the attention set but only based on the automatic rules. */
  public void processAutomaticAttentionSetRulesOnReply(
      BatchUpdate bu,
      ChangeNotes changeNotes,
      boolean readyForReview,
      CurrentUser currentUser,
      List<HumanComment> commentsToBePublished) {
    if (serviceUserClassifier.isServiceUser(currentUser.getAccountId())) {
      return;
    }
    processRules(
        bu,
        /* postReviewOp= */ null,
        changeNotes,
        readyForReview,
        currentUser,
        commentsToBePublished.stream().collect(toImmutableSet()));
  }

  /**
   * Adjusts the attention set when a review is posted.
   *
   * <p>If the same user should be added and removed or added/removed twice, the user will only be
   * added/removed once, based on first addition/removal.
   *
   * @param postReviewOp the {@link PostReviewOp} that is being executed before the attention set
   *     updates
   */
  public void updateAttentionSetOnPostReview(
      BatchUpdate bu,
      PostReviewOp postReviewOp,
      ChangeNotes changeNotes,
      ReviewInput input,
      CurrentUser currentUser)
      throws BadRequestException, IOException, PermissionBackendException,
          UnprocessableEntityException, ConfigInvalidException {
    requireNonNull(postReviewOp, "postReviewOp must not be null");

    processManualUpdates(bu, changeNotes, input);
    if (input.ignoreAutomaticAttentionSetRules) {

      // If we ignore automatic attention set rules it means we need to pass this information to
      // ChangeUpdate. Also, we should stop all other attention set updates that are part of
      // this method and happen in PostReview.
      bu.addOp(changeNotes.getChangeId(), new AttentionSetUnchangedOp());
      return;
    }
    boolean isReadyForReview = isReadyForReview(changeNotes, input);

    if (isReadyForReview && serviceUserClassifier.isServiceUser(currentUser.getAccountId())) {
      botsWithNegativeLabelsAddOwnerAndUploader(bu, postReviewOp, changeNotes);
      return;
    }

    processRules(
        bu,
        postReviewOp,
        changeNotes,
        isReadyForReview,
        currentUser,
        getAllNewComments(changeNotes, input, currentUser));
  }

  private ImmutableSet<HumanComment> getAllNewComments(
      ChangeNotes changeNotes, ReviewInput input, CurrentUser currentUser) {
    Set<HumanComment> newComments = new HashSet<>();
    if (input.comments != null) {
      for (ReviewInput.CommentInput commentInput :
          input.comments.values().stream().flatMap(x -> x.stream()).collect(Collectors.toList())) {
        newComments.add(
            commentsUtil.newHumanComment(
                changeNotes,
                currentUser,
                TimeUtil.now(),
                commentInput.path,
                commentInput.patchSet == null
                    ? changeNotes.getChange().currentPatchSetId()
                    : PatchSet.id(changeNotes.getChange().getId(), commentInput.patchSet),
                commentInput.side(),
                commentInput.message,
                commentInput.unresolved,
                commentInput.inReplyTo,
                CommentsUtil.createFixSuggestionsFromInput(commentInput.fixSuggestions)));
      }
    }
    List<HumanComment> drafts = new ArrayList<>();
    if (input.drafts == ReviewInput.DraftHandling.PUBLISH) {
      drafts =
          draftCommentsReader.getDraftsByPatchSetAndDraftAuthor(
              changeNotes, changeNotes.getChange().currentPatchSetId(), currentUser.getAccountId());
    }
    if (input.drafts == ReviewInput.DraftHandling.PUBLISH_ALL_REVISIONS) {
      drafts =
          draftCommentsReader.getDraftsByChangeAndDraftAuthor(
              changeNotes, currentUser.getAccountId());
    }
    return Stream.concat(newComments.stream(), drafts.stream()).collect(toImmutableSet());
  }

  /**
   * Process the automatic rules of the attention set.
   *
   * <p>All of the automatic rules except adding/removing reviewers and entering/exiting WIP state
   * are done here, and the rest are done in {@link ChangeUpdate}.
   *
   * @param postReviewOp {@link PostReviewOp} that is being executed before the attention set
   *     updates, may be {@code null}
   */
  private void processRules(
      BatchUpdate bu,
      @Nullable PostReviewOp postReviewOp,
      ChangeNotes changeNotes,
      boolean readyForReview,
      CurrentUser currentUser,
      ImmutableSet<HumanComment> allNewComments) {
    updateAttentionSetForCurrentUser(bu, postReviewOp, changeNotes, currentUser);

    // The rest of the conditions only apply if the change is open.
    if (changeNotes.getChange().getStatus().isClosed()) {
      // We still add the owner if a new comment thread was created, on closed changes.
      if (allNewComments.stream().anyMatch(c -> c.parentUuid == null)) {
        addToAttentionSet(
            bu,
            changeNotes,
            changeNotes.getChange().getOwner(),
            "A new comment thread was created",
            false);
      }
      return;
    }
    // The rest of the conditions only apply if the change is ready for review and reply is not
    // posted by a bot.
    if (!readyForReview || serviceUserClassifier.isServiceUser(currentUser.getAccountId())) {
      return;
    }

    addOwnerAndUploaderToAttentionSetIfSomeoneElseReplied(
        bu, postReviewOp, changeNotes, currentUser, readyForReview, allNewComments);
    addAllAuthorsOfCommentThreads(bu, changeNotes, allNewComments);
  }

  /**
   * Updates the attention set for the current user.
   *
   * <p>Removes the current user from the attention set (since they replied) unless they voted on an
   * outdated patch set and some of the votes were not copied to the current patch set (in this case
   * they should be in the attention set to re-apply their votes).
   *
   * <p>If the current user voted on an outdated patch set and some of the votes were not copied to
   * the current patch set:
   *
   * <ul>
   *   <li>the current user is added to the attention set (if they are not in the attention set yet)
   *       or
   *   <li>the reason for the current user to be in the attention set is updated (if they are
   *       already in the attention set).
   * </ul>
   */
  private void updateAttentionSetForCurrentUser(
      BatchUpdate bu,
      @Nullable PostReviewOp postReviewOp,
      ChangeNotes changeNotes,
      CurrentUser currentUser) {
    if (postReviewOp == null) {
      // Replying removes the current user from the attention set.
      removeFromAttentionSet(
          bu, changeNotes, currentUser.getAccountId(), "removed on reply", false);
    } else {
      // If the current user voted on an outdated patch set and some of the votes were not copied to
      // the current patch set the current user should stay in the attention set, or be added to the
      // attention set. In case the user stays in the attention set, this updates the reason for
      // being in the attention set.
      AttentionSetUpdateCondition addOrKeepCondition =
          () ->
              postReviewOp
                  .getResult()
                  .appliedVotesOnOutdatedPatchSetThatWereNotCopiedToCurrentPatchSet();
      maybeAddToAttentionSet(
          bu,
          addOrKeepCondition,
          changeNotes,
          currentUser.getAccountId(),
          "Some votes were not copied to the current patch set",
          false);

      // Otherwise replying removes the current user from the attention set.
      AttentionSetUpdateCondition removeCondition = () -> !addOrKeepCondition.check();
      maybeRemoveFromAttentionSet(
          bu, removeCondition, changeNotes, currentUser.getAccountId(), "removed on reply", false);
    }
  }

  /**
   * Adds the owner and uploader to the attention set if someone else replied.
   *
   * <p>Replying means they either updated the votes on the current patch set (either directly on
   * the current patch set or the votes were copied to the current patch set), they posted a change
   * message, they marked the change as ready or they posted new comments.
   */
  private void addOwnerAndUploaderToAttentionSetIfSomeoneElseReplied(
      BatchUpdate bu,
      @Nullable PostReviewOp postReviewOp,
      ChangeNotes changeNotes,
      CurrentUser currentUser,
      boolean readyForReview,
      ImmutableSet<HumanComment> allNewComments) {
    AttentionSetUpdateCondition condition =
        postReviewOp != null
            ? () ->
                postReviewOp.getResult().updatedAnyVoteOnCurrentPatchSet()
                    || postReviewOp.getResult().postedChangeMessage()
                    || (changeNotes.getChange().isWorkInProgress() && readyForReview)
                    || !allNewComments.isEmpty()
            : () ->
                (changeNotes.getChange().isWorkInProgress() && readyForReview)
                    || !allNewComments.isEmpty();

    Account.Id owner = changeNotes.getChange().getOwner();
    if (!currentUser.getAccountId().equals(owner)) {
      maybeAddToAttentionSet(
          bu, condition, changeNotes, owner, "Someone else replied on the change", false);
    }

    Account.Id uploader = changeNotes.getCurrentPatchSet().uploader();
    if (!owner.equals(uploader) && !currentUser.getAccountId().equals(uploader)) {
      maybeAddToAttentionSet(
          bu, condition, changeNotes, uploader, "Someone else replied on the change", false);
    }
  }

  /** Adds all authors of all comment threads that received a reply during this update */
  private void addAllAuthorsOfCommentThreads(
      BatchUpdate bu, ChangeNotes changeNotes, ImmutableSet<HumanComment> allNewComments) {
    List<HumanComment> publishedComments = commentsUtil.publishedHumanCommentsByChange(changeNotes);
    ImmutableSet<CommentThread<HumanComment>> repliedToCommentThreads =
        CommentThreads.forComments(publishedComments).getThreadsForChildren(allNewComments);

    ImmutableSet<Account.Id> repliedToUsers =
        repliedToCommentThreads.stream()
            .map(CommentThread::comments)
            .flatMap(Collection::stream)
            .map(comment -> comment.author.getId())
            .collect(toImmutableSet());
    ImmutableSet<Account.Id> possibleUsersToAdd = approvalsUtil.getReviewers(changeNotes).all();
    SetView<Account.Id> usersToAdd = Sets.intersection(possibleUsersToAdd, repliedToUsers);

    for (Account.Id user : usersToAdd) {
      addToAttentionSet(
          bu, changeNotes, user, "Someone else replied on a comment you posted", false);
    }
  }

  /** Process the manual updates of the attention set. */
  private void processManualUpdates(BatchUpdate bu, ChangeNotes changeNotes, ReviewInput input)
      throws BadRequestException, IOException, PermissionBackendException,
          UnprocessableEntityException, ConfigInvalidException {
    Set<Account.Id> accountsChangedInCommit = new HashSet<>();
    // If we specify a user to remove, and the user is in the attention set, we remove it.
    if (input.removeFromAttentionSet != null) {
      for (AttentionSetInput remove : input.removeFromAttentionSet) {
        removeFromAttentionSet(bu, changeNotes, remove, accountsChangedInCommit);
      }
    }

    // If we don't specify a user to remove, but we specify addition for that user, the user will be
    // added if they are not in the attention set yet.
    if (input.addToAttentionSet != null) {
      for (AttentionSetInput add : input.addToAttentionSet) {
        addToAttentionSet(bu, changeNotes, add, accountsChangedInCommit);
      }
    }
  }

  /**
   * Bots don't process automatic rules, the only attention set change they do is this rule: Add
   * owner and uploader when a bot votes negatively on the current patch set, but only if the change
   * is open.
   */
  private void botsWithNegativeLabelsAddOwnerAndUploader(
      BatchUpdate bu, PostReviewOp postReviewOp, ChangeNotes changeNotes) {
    if (changeNotes.getChange().isClosed()) {
      return;
    }

    AttentionSetUpdateCondition condition =
        () -> postReviewOp.getResult().updatedAnyNegativeVoteOnCurrentPatchSet();

    Account.Id owner = changeNotes.getChange().getOwner();
    maybeAddToAttentionSet(
        bu, condition, changeNotes, owner, "A robot voted negatively on a label", false);

    Account.Id uploader = changeNotes.getCurrentPatchSet().uploader();
    if (!owner.equals(uploader)) {
      maybeAddToAttentionSet(
          bu, condition, changeNotes, uploader, "A robot voted negatively on a label", false);
    }
  }

  /**
   * Adds the user to the attention set
   *
   * @param bu BatchUpdate to perform the updates to the attention set
   * @param changeNotes current change
   * @param user user to add to the attention set
   * @param reason reason for adding
   * @param notify whether or not to notify about this addition
   */
  private void addToAttentionSet(
      BatchUpdate bu, ChangeNotes changeNotes, Account.Id user, String reason, boolean notify) {
    AddToAttentionSetOp addToAttentionSet = addToAttentionSetOpFactory.create(user, reason, notify);
    bu.addOp(changeNotes.getChangeId(), addToAttentionSet);
  }

  /**
   * Adds the user to the attention set if the given condition is true.
   *
   * @param bu BatchUpdate to perform the updates to the attention set
   * @param condition condition that decides whether the attention set update should be performed
   * @param changeNotes current change
   * @param user user to add to the attention set
   * @param reason reason for adding
   * @param notify whether or not to notify about this addition
   */
  private void maybeAddToAttentionSet(
      BatchUpdate bu,
      AttentionSetUpdateCondition condition,
      ChangeNotes changeNotes,
      Account.Id user,
      String reason,
      boolean notify) {
    AddToAttentionSetOp addToAttentionSet =
        addToAttentionSetOpFactory.create(user, reason, notify).setCondition(condition);
    bu.addOp(changeNotes.getChangeId(), addToAttentionSet);
  }

  /**
   * Removes the user from the attention set
   *
   * @param bu BatchUpdate to perform the updates to the attention set.
   * @param changeNotes current change.
   * @param user user to add remove from the attention set.
   * @param reason reason for removing.
   * @param notify whether or not to notify about this removal.
   */
  private void removeFromAttentionSet(
      BatchUpdate bu, ChangeNotes changeNotes, Account.Id user, String reason, boolean notify) {
    RemoveFromAttentionSetOp removeFromAttentionSetOp =
        removeFromAttentionSetOpFactory.create(user, reason, notify);
    bu.addOp(changeNotes.getChangeId(), removeFromAttentionSetOp);
  }

  /**
   * Removes the user from the attention set if the given condition is true.
   *
   * @param bu BatchUpdate to perform the updates to the attention set.
   * @param condition condition that decides whether the attention set update should be performed
   * @param changeNotes current change.
   * @param user user to add remove from the attention set.
   * @param reason reason for removing.
   * @param notify whether or not to notify about this removal.
   */
  private void maybeRemoveFromAttentionSet(
      BatchUpdate bu,
      AttentionSetUpdateCondition condition,
      ChangeNotes changeNotes,
      Account.Id user,
      String reason,
      boolean notify) {
    RemoveFromAttentionSetOp removeFromAttentionSetOp =
        removeFromAttentionSetOpFactory.create(user, reason, notify).setCondition(condition);
    bu.addOp(changeNotes.getChangeId(), removeFromAttentionSetOp);
  }

  private static boolean isReadyForReview(ChangeNotes changeNotes, ReviewInput input) {
    return (!changeNotes.getChange().isWorkInProgress() && !input.workInProgress) || input.ready;
  }

  private void addToAttentionSet(
      BatchUpdate bu,
      ChangeNotes changeNotes,
      AttentionSetInput add,
      Set<Account.Id> accountsChangedInCommit)
      throws BadRequestException, IOException, PermissionBackendException,
          UnprocessableEntityException, ConfigInvalidException {
    AttentionSetUtil.validateInput(add);
    try {
      Account.Id attentionUserId =
          getAccountIdAndValidateUser(
              changeNotes, add.user, accountsChangedInCommit, AttentionSetUpdate.Operation.ADD);
      addToAttentionSet(bu, changeNotes, attentionUserId, add.reason, false);
    } catch (AccountResolver.UnresolvableAccountException ex) {
      // This happens only when the account doesn't exist. Silently ignore it. If we threw an error
      // message here, then it would be possible to probe whether an account exists.
    } catch (AuthException ex) {
      // adding users without permission to the attention set should fail silently.
      logger.atFine().log("%s", ex.getMessage());
    }
  }

  private void removeFromAttentionSet(
      BatchUpdate bu,
      ChangeNotes changeNotes,
      AttentionSetInput remove,
      Set<Account.Id> accountsChangedInCommit)
      throws BadRequestException, IOException, PermissionBackendException,
          UnprocessableEntityException, ConfigInvalidException {
    AttentionSetUtil.validateInput(remove);
    try {
      Account.Id attentionUserId =
          getAccountIdAndValidateUser(
              changeNotes,
              remove.user,
              accountsChangedInCommit,
              AttentionSetUpdate.Operation.REMOVE);
      removeFromAttentionSet(bu, changeNotes, attentionUserId, remove.reason, false);
    } catch (AccountResolver.UnresolvableAccountException ex) {
      // This happens only when the account doesn't exist. Silently ignore it. If we threw an error
      // message here, then it would be possible to probe whether an account exists.
    } catch (AuthException ex) {
      // this should never happen since removing users with permissions should work.
      logger.atSevere().log("%s", ex.getMessage());
    }
  }

  private Account.Id getAccountId(
      ChangeNotes changeNotes, String user, AttentionSetUpdate.Operation operation)
      throws ConfigInvalidException, IOException, UnprocessableEntityException,
          PermissionBackendException, AuthException {
    Account.Id attentionUserId = accountResolver.resolve(user).asUnique().account().id();
    try {
      permissionBackend
          .absentUser(attentionUserId)
          .change(changeNotes)
          .check(ChangePermission.READ);
    } catch (AuthException e) {
      // If the change is private, it is okay to add the user to the attention set since that
      // person will be granted visibility when a reviewer.
      if (!changeNotes.getChange().isPrivate()) {

        // Removing users without access is allowed, adding is not allowed
        if (operation == AttentionSetUpdate.Operation.ADD) {
          throw new AuthException(
              "Can't modify attention set: Read not permitted for " + attentionUserId, e);
        }
      }
    }
    return attentionUserId;
  }

  private Account.Id getAccountIdAndValidateUser(
      ChangeNotes changeNotes,
      String user,
      Set<Account.Id> accountsChangedInCommit,
      AttentionSetUpdate.Operation operation)
      throws ConfigInvalidException, IOException, PermissionBackendException,
          UnprocessableEntityException, BadRequestException, AuthException {
    try {
      Account.Id attentionUserId = getAccountId(changeNotes, user, operation);
      if (accountsChangedInCommit.contains(attentionUserId)) {
        throw new BadRequestException(
            String.format(
                "%s can not be added/removed twice, and can not be added and "
                    + "removed at the same time",
                user));
      }
      accountsChangedInCommit.add(attentionUserId);
      return attentionUserId;
    } catch (AccountResolver.UnresolvableAccountException ex) {
      // This can only happen if this user can't see the account or the account doesn't exist.
      // Silently modify the account's attention set anyway, if the account exists.
      return accountResolver.resolveIgnoreVisibility(user).asUnique().account().id();
    }
  }
}
