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

import static com.google.common.base.Preconditions.checkState;
import static com.google.gerrit.extensions.client.ReviewerState.CC;
import static java.util.stream.Collectors.toList;

import com.google.auto.value.AutoValue;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Streams;
import com.google.common.flogger.FluentLogger;
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.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.IdentifiedUser;
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.change.ChangeResource;
import com.google.gerrit.server.extensions.events.ReviewerAdded;
import com.google.gerrit.server.mail.send.AddReviewerSender;
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.Provider;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;

public class PostReviewersOp implements BatchUpdateOp {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  public interface Factory {
    PostReviewersOp create(
        ChangeResource rsrc,
        Set<Account.Id> reviewers,
        Collection<Address> reviewersByEmail,
        ReviewerState state,
        @Nullable NotifyHandling notify,
        ListMultimap<RecipientType, Account.Id> accountsToNotify);
  }

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

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

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

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

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

      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 AddReviewerSender.Factory addReviewerSenderFactory;
  private final NotesMigration migration;
  private final Provider<IdentifiedUser> user;
  private final Provider<ReviewDb> dbProvider;
  private final ChangeResource rsrc;
  private final Set<Account.Id> reviewers;
  private final Collection<Address> reviewersByEmail;
  private final ReviewerState state;
  private final NotifyHandling notify;
  private final ListMultimap<RecipientType, Account.Id> accountsToNotify;

  private List<PatchSetApproval> addedReviewers = new ArrayList<>();
  private Collection<Account.Id> addedCCs = new ArrayList<>();
  private Collection<Address> addedCCsByEmail = new ArrayList<>();
  private PatchSet patchSet;
  private Result opResult;

  @Inject
  PostReviewersOp(
      ApprovalsUtil approvalsUtil,
      PatchSetUtil psUtil,
      ReviewerAdded reviewerAdded,
      AccountCache accountCache,
      ProjectCache projectCache,
      AddReviewerSender.Factory addReviewerSenderFactory,
      NotesMigration migration,
      Provider<IdentifiedUser> user,
      Provider<ReviewDb> dbProvider,
      @Assisted ChangeResource rsrc,
      @Assisted Set<Account.Id> reviewers,
      @Assisted Collection<Address> reviewersByEmail,
      @Assisted ReviewerState state,
      @Assisted @Nullable NotifyHandling notify,
      @Assisted ListMultimap<RecipientType, Account.Id> accountsToNotify) {
    this.approvalsUtil = approvalsUtil;
    this.psUtil = psUtil;
    this.reviewerAdded = reviewerAdded;
    this.accountCache = accountCache;
    this.projectCache = projectCache;
    this.addReviewerSenderFactory = addReviewerSenderFactory;
    this.migration = migration;
    this.user = user;
    this.dbProvider = dbProvider;

    this.rsrc = rsrc;
    this.reviewers = reviewers;
    this.reviewersByEmail = reviewersByEmail;
    this.state = state;
    this.notify = notify;
    this.accountsToNotify = accountsToNotify;
  }

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

    for (Address a : reviewersByEmail) {
      ctx.getUpdate(ctx.getChange().currentPatchSetId())
          .putReviewerByEmail(a, ReviewerStateInternal.fromReviewerState(state));
    }

    patchSet = psUtil.current(dbProvider.get(), rsrc.getNotes());
    return true;
  }

  @Override
  public void postUpdate(Context ctx) throws Exception {
    opResult =
        Result.builder()
            .setAddedReviewers(ImmutableList.copyOf(addedReviewers))
            .setAddedCCs(ImmutableList.copyOf(addedCCs))
            .build();
    emailReviewers(
        rsrc.getChange(),
        Lists.transform(addedReviewers, PatchSetApproval::getAccountId),
        addedCCs == null ? ImmutableList.of() : addedCCs,
        reviewersByEmail,
        addedCCsByEmail,
        notify,
        accountsToNotify,
        !rsrc.getChange().isWorkInProgress());
    if (!addedReviewers.isEmpty()) {
      List<AccountState> reviewers =
          addedReviewers
              .stream()
              .map(r -> accountCache.get(r.getAccountId()))
              .flatMap(Streams::stream)
              .collect(toList());
      reviewerAdded.fire(rsrc.getChange(), patchSet, reviewers, ctx.getAccount(), ctx.getWhen());
    }
  }

  public void emailReviewers(
      Change change,
      Collection<Account.Id> added,
      Collection<Account.Id> copied,
      Collection<Address> addedByEmail,
      Collection<Address> copiedByEmail,
      NotifyHandling notify,
      ListMultimap<RecipientType, Account.Id> accountsToNotify,
      boolean readyForReview) {
    if (added.isEmpty() && copied.isEmpty() && addedByEmail.isEmpty() && copiedByEmail.isEmpty()) {
      return;
    }

    // Email the reviewers
    //
    // The user knows they added themselves, don't bother emailing them.
    List<Account.Id> toMail = Lists.newArrayListWithCapacity(added.size());
    Account.Id userId = user.get().getAccountId();
    for (Account.Id id : added) {
      if (!id.equals(userId)) {
        toMail.add(id);
      }
    }
    List<Account.Id> toCopy = Lists.newArrayListWithCapacity(copied.size());
    for (Account.Id id : copied) {
      if (!id.equals(userId)) {
        toCopy.add(id);
      }
    }
    if (toMail.isEmpty() && toCopy.isEmpty() && addedByEmail.isEmpty() && copiedByEmail.isEmpty()) {
      return;
    }

    try {
      AddReviewerSender cm = addReviewerSenderFactory.create(change.getProject(), change.getId());
      // Default to silent operation on WIP changes.
      NotifyHandling defaultNotifyHandling =
          readyForReview ? NotifyHandling.ALL : NotifyHandling.NONE;
      cm.setNotify(MoreObjects.firstNonNull(notify, defaultNotifyHandling));
      cm.setAccountsToNotify(accountsToNotify);
      cm.setFrom(userId);
      cm.addReviewers(toMail);
      cm.addReviewersByEmail(addedByEmail);
      cm.addExtraCC(toCopy);
      cm.addExtraCCByEmail(copiedByEmail);
      cm.send();
    } catch (Exception err) {
      logger.atSevere().withCause(err).log(
          "Cannot send email to new reviewers of change %s", change.getId());
    }
  }

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