// 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.collect.ImmutableList.toImmutableList;

import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Address;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.config.SendEmailExecutor;
import com.google.gerrit.server.mail.send.MessageIdGenerator;
import com.google.gerrit.server.mail.send.ModifyReviewerSender;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

@Singleton
public class ModifyReviewersEmail {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  private final ModifyReviewerSender.Factory addReviewerSenderFactory;
  private final ExecutorService sendEmailsExecutor;
  private final MessageIdGenerator messageIdGenerator;

  @Inject
  ModifyReviewersEmail(
      ModifyReviewerSender.Factory addReviewerSenderFactory,
      @SendEmailExecutor ExecutorService sendEmailsExecutor,
      MessageIdGenerator messageIdGenerator) {
    this.addReviewerSenderFactory = addReviewerSenderFactory;
    this.sendEmailsExecutor = sendEmailsExecutor;
    this.messageIdGenerator = messageIdGenerator;
  }

  public void emailReviewersAsync(
      IdentifiedUser user,
      Change change,
      Collection<Account.Id> added,
      Collection<Account.Id> copied,
      Collection<Account.Id> removed,
      Collection<Address> addedByEmail,
      Collection<Address> copiedByEmail,
      Collection<Address> removedByEmail,
      NotifyResolver.Result notify) {
    // The user knows they added/removed themselves, don't bother emailing them.
    Account.Id userId = user.getAccountId();
    ImmutableList<Account.Id> immutableToMail =
        added.stream().filter(id -> !id.equals(userId)).collect(toImmutableList());
    ImmutableList<Account.Id> immutableToCopy =
        copied.stream().filter(id -> !id.equals(userId)).collect(toImmutableList());
    ImmutableList<Account.Id> immutableToRemove =
        removed.stream().filter(id -> !id.equals(userId)).collect(toImmutableList());
    if (immutableToMail.isEmpty()
        && immutableToCopy.isEmpty()
        && immutableToRemove.isEmpty()
        && addedByEmail.isEmpty()
        && copiedByEmail.isEmpty()
        && removedByEmail.isEmpty()) {
      return;
    }

    // Make immutable copies of collections and hand over only immutable data types to the other
    // thread.
    Change.Id cId = change.getId();
    Project.NameKey projectNameKey = change.getProject();
    ImmutableList<Address> immutableAddedByEmail = ImmutableList.copyOf(addedByEmail);
    ImmutableList<Address> immutableCopiedByEmail = ImmutableList.copyOf(copiedByEmail);
    ImmutableList<Address> immutableRemovedByEmail = ImmutableList.copyOf(removedByEmail);

    @SuppressWarnings("unused")
    Future<?> possiblyIgnoredError =
        sendEmailsExecutor.submit(
            () -> {
              try {
                ModifyReviewerSender emailSender =
                    addReviewerSenderFactory.create(projectNameKey, cId);
                emailSender.setNotify(notify);
                emailSender.setFrom(userId);
                emailSender.addReviewers(immutableToMail);
                emailSender.addReviewersByEmail(immutableAddedByEmail);
                emailSender.addExtraCC(immutableToCopy);
                emailSender.addExtraCCByEmail(immutableCopiedByEmail);
                emailSender.addRemovedReviewers(immutableToRemove);
                emailSender.addRemovedByEmailReviewers(immutableRemovedByEmail);
                emailSender.setMessageId(
                    messageIdGenerator.fromChangeUpdate(
                        change.getProject(), change.currentPatchSetId()));
                emailSender.send();
              } catch (Exception err) {
                logger.atSevere().withCause(err).log(
                    "Cannot send email to new reviewers of change %s", change.getId());
              }
            });
  }
}
