// Copyright (C) 2017 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.gerrit.extensions.client.ReviewerState.CC;
import static com.google.gerrit.extensions.client.ReviewerState.REVIEWER;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toList;

import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Streams;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.api.changes.NotifyHandling;
import com.google.gerrit.extensions.api.changes.RecipientType;
import com.google.gerrit.extensions.client.ReviewerState;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.mail.Address;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.extensions.events.ReviewerAdded;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.notedb.ReviewerStateInternal;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.update.BatchUpdateOp;
import com.google.gerrit.server.update.ChangeContext;
import com.google.gerrit.server.update.Context;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Set;

public class AddReviewersOp implements BatchUpdateOp {
  public interface Factory {

    /**
     * Create a new op.
     *
     * <p>Users may be added by account or by email addresses, as determined by {@code accountIds}
     * and {@code addresses}. The reviewer state for both accounts and email addresses is determined
     * by {@code state}.
     *
     * @param accountIds account IDs to add.
     * @param addresses email addresses to add.
     * @param state resulting reviewer state.
     * @param notify notification handling.
     * @param accountsToNotify additional accounts to notify.
     * @return batch update operation.
     */
    AddReviewersOp create(
        Set<Account.Id> accountIds,
        Collection<Address> addresses,
        ReviewerState state,
        @Nullable NotifyHandling notify,
        ListMultimap<RecipientType, Account.Id> accountsToNotify);
  }

  @AutoValue
  public abstract static class Result {
    public abstract ImmutableList<PatchSetApproval> addedReviewers();

    public abstract ImmutableList<Address> addedReviewersByEmail();

    public abstract ImmutableList<Account.Id> addedCCs();

    public abstract ImmutableList<Address> addedCCsByEmail();

    static Builder builder() {
      return new AutoValue_AddReviewersOp_Result.Builder();
    }

    @AutoValue.Builder
    abstract static class Builder {
      abstract Builder setAddedReviewers(Iterable<PatchSetApproval> addedReviewers);

      abstract Builder setAddedReviewersByEmail(Iterable<Address> addedReviewersByEmail);

      abstract Builder setAddedCCs(Iterable<Account.Id> addedCCs);

      abstract Builder setAddedCCsByEmail(Iterable<Address> addedCCsByEmail);

      abstract Result build();
    }
  }

  private final ApprovalsUtil approvalsUtil;
  private final PatchSetUtil psUtil;
  private final ReviewerAdded reviewerAdded;
  private final AccountCache accountCache;
  private final ProjectCache projectCache;
  private final AddReviewersEmail addReviewersEmail;
  private final NotesMigration migration;
  private final Set<Account.Id> accountIds;
  private final Collection<Address> addresses;
  private final ReviewerState state;
  private final NotifyHandling notify;
  private final ListMultimap<RecipientType, Account.Id> accountsToNotify;

  // Unlike addedCCs, addedReviewers is a PatchSetApproval because the AddReviewerResult returned
  // via the REST API is supposed to include vote information.
  private List<PatchSetApproval> addedReviewers = ImmutableList.of();
  private Collection<Address> addedReviewersByEmail = ImmutableList.of();
  private Collection<Account.Id> addedCCs = ImmutableList.of();
  private Collection<Address> addedCCsByEmail = ImmutableList.of();

  private Change change;
  private PatchSet patchSet;
  private Result opResult;

  @Inject
  AddReviewersOp(
      ApprovalsUtil approvalsUtil,
      PatchSetUtil psUtil,
      ReviewerAdded reviewerAdded,
      AccountCache accountCache,
      ProjectCache projectCache,
      AddReviewersEmail addReviewersEmail,
      NotesMigration migration,
      @Assisted Set<Account.Id> accountIds,
      @Assisted Collection<Address> addresses,
      @Assisted ReviewerState state,
      @Assisted @Nullable NotifyHandling notify,
      @Assisted ListMultimap<RecipientType, Account.Id> accountsToNotify) {
    checkArgument(state == REVIEWER || state == CC, "must be %s or %s: %s", REVIEWER, CC, state);
    this.approvalsUtil = approvalsUtil;
    this.psUtil = psUtil;
    this.reviewerAdded = reviewerAdded;
    this.accountCache = accountCache;
    this.projectCache = projectCache;
    this.addReviewersEmail = addReviewersEmail;
    this.migration = migration;

    this.accountIds = accountIds;
    this.addresses = addresses;
    this.state = state;
    this.notify = notify;
    this.accountsToNotify = accountsToNotify;
  }

  void setPatchSet(PatchSet patchSet) {
    this.patchSet = requireNonNull(patchSet);
  }

  @Override
  public boolean updateChange(ChangeContext ctx)
      throws RestApiException, OrmException, IOException {
    change = ctx.getChange();
    if (!accountIds.isEmpty()) {
      if (migration.readChanges() && state == CC) {
        addedCCs =
            approvalsUtil.addCcs(
                ctx.getNotes(), ctx.getUpdate(change.currentPatchSetId()), accountIds);
      } else {
        addedReviewers =
            approvalsUtil.addReviewers(
                ctx.getDb(),
                ctx.getNotes(),
                ctx.getUpdate(change.currentPatchSetId()),
                projectCache.checkedGet(change.getProject()).getLabelTypes(change.getDest()),
                change,
                accountIds);
      }
    }

    ImmutableList<Address> addressesToAdd = ImmutableList.of();
    ReviewerStateInternal internalState = ReviewerStateInternal.fromReviewerState(state);
    if (migration.readChanges()) {
      // TODO(dborowitz): This behavior should live in ApprovalsUtil or something, like addCcs does.
      ImmutableSet<Address> existing = ctx.getNotes().getReviewersByEmail().byState(internalState);
      addressesToAdd =
          addresses.stream().filter(a -> !existing.contains(a)).collect(toImmutableList());

      if (state == CC) {
        addedCCsByEmail = addressesToAdd;
      } else {
        addedReviewersByEmail = addressesToAdd;
      }
      for (Address a : addressesToAdd) {
        ctx.getUpdate(change.currentPatchSetId()).putReviewerByEmail(a, internalState);
      }
    }
    if (addedCCs.isEmpty() && addedReviewers.isEmpty() && addressesToAdd.isEmpty()) {
      return false;
    }

    checkAdded();

    if (patchSet == null) {
      patchSet = requireNonNull(psUtil.current(ctx.getDb(), ctx.getNotes()));
    }
    return true;
  }

  private void checkAdded() {
    // Should only affect either reviewers or CCs, not both. But the logic in updateChange is
    // complex, so programmer error is conceivable.
    boolean addedAnyReviewers = !addedReviewers.isEmpty() || !addedReviewersByEmail.isEmpty();
    boolean addedAnyCCs = !addedCCs.isEmpty() || !addedCCsByEmail.isEmpty();
    checkState(
        !(addedAnyReviewers && addedAnyCCs),
        "should not have added both reviewers and CCs:\n"
            + "Arguments:\n"
            + "  accountIds=%s\n"
            + "  addresses=%s\n"
            + "Results:\n"
            + "  addedReviewers=%s\n"
            + "  addedReviewersByEmail=%s\n"
            + "  addedCCs=%s\n"
            + "  addedCCsByEmail=%s",
        accountIds,
        addresses,
        addedReviewers,
        addedReviewersByEmail,
        addedCCs,
        addedCCsByEmail);
  }

  @Override
  public void postUpdate(Context ctx) throws Exception {
    opResult =
        Result.builder()
            .setAddedReviewers(addedReviewers)
            .setAddedReviewersByEmail(addedReviewersByEmail)
            .setAddedCCs(addedCCs)
            .setAddedCCsByEmail(addedCCsByEmail)
            .build();
    addReviewersEmail.emailReviewers(
        ctx.getUser().asIdentifiedUser(),
        change,
        Lists.transform(addedReviewers, PatchSetApproval::getAccountId),
        addedCCs,
        addedReviewersByEmail,
        addedCCsByEmail,
        notify,
        accountsToNotify,
        !change.isWorkInProgress());
    if (!addedReviewers.isEmpty()) {
      List<AccountState> reviewers =
          addedReviewers.stream()
              .map(r -> accountCache.get(r.getAccountId()))
              .flatMap(Streams::stream)
              .collect(toList());
      reviewerAdded.fire(change, patchSet, reviewers, ctx.getAccount(), ctx.getWhen());
    }
  }

  public Result getResult() {
    checkState(opResult != null, "Batch update wasn't executed yet");
    return opResult;
  }
}
