// 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.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;

import com.google.gerrit.entities.Account;
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.ApprovalsUtil;
import com.google.gerrit.server.account.AccountResolver;
import com.google.gerrit.server.change.AddToAttentionSetOp;
import com.google.gerrit.server.change.AttentionSetUnchangedOp;
import com.google.gerrit.server.change.RemoveFromAttentionSetOp;
import com.google.gerrit.server.change.ReviewerAdder;
import com.google.gerrit.server.change.RevisionResource;
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.inject.Inject;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.jgit.errors.ConfigInvalidException;

/**
 * This class is used by {@link PostReview} to update the attention set when performing a review.
 */
public class PostReviewAttentionSet {

  private final PermissionBackend permissionBackend;
  private final AddToAttentionSetOp.Factory addToAttentionSetOpFactory;
  private final RemoveFromAttentionSetOp.Factory removeFromAttentionSetOpFactory;
  private final ApprovalsUtil approvalsUtil;
  private final AccountResolver accountResolver;

  @Inject
  PostReviewAttentionSet(
      PermissionBackend permissionBackend,
      AddToAttentionSetOp.Factory addToAttentionSetOpFactory,
      RemoveFromAttentionSetOp.Factory removeFromAttentionSetOpFactory,
      ApprovalsUtil approvalsUtil,
      AccountResolver accountResolver) {
    this.permissionBackend = permissionBackend;
    this.addToAttentionSetOpFactory = addToAttentionSetOpFactory;
    this.removeFromAttentionSetOpFactory = removeFromAttentionSetOpFactory;
    this.approvalsUtil = approvalsUtil;
    this.accountResolver = accountResolver;
  }

  /**
   * Adjusts the attention set by adding and removing users. 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.
   */
  public void updateAttentionSet(
      BatchUpdate bu,
      RevisionResource revision,
      ReviewInput input,
      List<ReviewerAdder.ReviewerAddition> reviewerResults)
      throws BadRequestException, IOException, PermissionBackendException,
          UnprocessableEntityException, ConfigInvalidException {
    processManualUpdates(bu, revision, input);
    if (input.ignoreDefaultAttentionSetRules) {

      // If We ignore default attention set rules it means we need to pass this information to
      // ChangeUpdate. Also, we should stop all other attention set update that are part of
      // this method (that happen in PostReview.
      bu.addOp(revision.getChange().getId(), new AttentionSetUnchangedOp());
      return;
    }
    processRules(bu, revision, input, reviewerResults);
  }

  /**
   * Process the default rules of the attention set. All of the default rules except adding/removing
   * reviewers and entering/exiting WIP state are done here, and the rest are done in {@link
   * ChangeUpdate}
   */
  private void processRules(
      BatchUpdate bu,
      RevisionResource revision,
      ReviewInput input,
      List<ReviewerAdder.ReviewerAddition> reviewerResults) {
    // Replying removes the publishing user from the attention set.
    RemoveFromAttentionSetOp removeFromAttentionSetOp =
        removeFromAttentionSetOpFactory.create(revision.getAccountId(), "removed on reply");
    bu.addOp(revision.getChange().getId(), removeFromAttentionSetOp);

    // The rest of the conditions only apply if the change is ready for review
    if (!isReadyForReview(revision, input)) {
      return;
    }
    Account.Id uploader = revision.getPatchSet().uploader();
    Account.Id owner = revision.getChange().getOwner();
    Account.Id currentUser = revision.getAccountId();
    if (currentUser.equals(uploader) && !uploader.equals(owner)) {
      // When the uploader replies, add the owner to the attention set.
      AddToAttentionSetOp addToAttentionSetOp =
          addToAttentionSetOpFactory.create(owner, "uploader replied");
      bu.addOp(revision.getChange().getId(), addToAttentionSetOp);
    }
    if (currentUser.equals(uploader) || currentUser.equals(owner)) {
      // When the owner or uploader replies, add the reviewers to the attention set.
      // Filter by users that are currently reviewers.
      Set<Account.Id> finalCCs =
          reviewerResults.stream()
              .filter(r -> r.result.ccs == null)
              .map(r -> r.reviewers)
              .flatMap(x -> x.stream())
              .collect(toSet());
      for (Account.Id reviewer :
          approvalsUtil.getReviewers(revision.getChangeResource().getNotes()).byState(REVIEWER)
              .stream()
              .filter(r -> !finalCCs.contains(r))
              .collect(toList())) {
        AddToAttentionSetOp addToAttentionSetOp =
            addToAttentionSetOpFactory.create(reviewer, "owner or uploader replied");
        bu.addOp(revision.getChange().getId(), addToAttentionSetOp);
      }
    }
    if (!currentUser.equals(uploader) && !currentUser.equals(owner)) {
      // When neither the uploader nor the owner (reviewer or cc) replies, add the owner and the
      // uploader to the attention set.
      AddToAttentionSetOp addToAttentionSetOp =
          addToAttentionSetOpFactory.create(owner, "reviewer or cc replied");
      bu.addOp(revision.getChange().getId(), addToAttentionSetOp);

      if (owner.get() != uploader.get()) {
        addToAttentionSetOp = addToAttentionSetOpFactory.create(uploader, "reviewer or cc replied");
        bu.addOp(revision.getChange().getId(), addToAttentionSetOp);
      }
    }
  }

  /** Process the manual updates of the attention set. */
  private void processManualUpdates(BatchUpdate bu, RevisionResource revision, 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, revision, 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, revision, add, accountsChangedInCommit);
      }
    }
  }

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

  private void addToAttentionSet(
      BatchUpdate bu,
      RevisionResource revision,
      AttentionSetInput add,
      Set<Account.Id> accountsChangedInCommitv)
      throws BadRequestException, IOException, PermissionBackendException,
          UnprocessableEntityException, ConfigInvalidException {
    AttentionSetUtil.validateInput(add);
    Account.Id attentionUserId =
        getAccountIdAndValidateUser(revision, add.user, accountsChangedInCommitv);

    AddToAttentionSetOp addToAttentionSetOp =
        addToAttentionSetOpFactory.create(attentionUserId, add.reason);
    bu.addOp(revision.getChange().getId(), addToAttentionSetOp);
  }

  private void removeFromAttentionSet(
      BatchUpdate bu,
      RevisionResource revision,
      AttentionSetInput remove,
      Set<Account.Id> accountsChangedInCommit)
      throws BadRequestException, IOException, PermissionBackendException,
          UnprocessableEntityException, ConfigInvalidException {
    AttentionSetUtil.validateInput(remove);
    Account.Id attentionUserId =
        getAccountIdAndValidateUser(revision, remove.user, accountsChangedInCommit);

    RemoveFromAttentionSetOp removeFromAttentionSetOp =
        removeFromAttentionSetOpFactory.create(attentionUserId, remove.reason);
    bu.addOp(revision.getChange().getId(), removeFromAttentionSetOp);
  }

  private Account.Id getAccountIdAndValidateUser(
      RevisionResource revision, String user, Set<Account.Id> accountsChangedInCommit)
      throws ConfigInvalidException, IOException, PermissionBackendException,
          UnprocessableEntityException, BadRequestException {
    Account.Id attentionUserId = accountResolver.resolve(user).asUnique().account().id();
    try {
      permissionBackend
          .absentUser(attentionUserId)
          .change(revision.getNotes())
          .check(ChangePermission.READ);
    } catch (AuthException e) {
      throw new UnprocessableEntityException(
          "Can't add to attention set: Read not permitted for " + attentionUserId, e);
    }
    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;
  }
}
