// Copyright (C) 2021 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.plugins.codeowners.backend;

import static java.util.stream.Collectors.joining;

import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.ChangeMessage;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.events.ReviewerAddedListener;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.metrics.Timer0;
import com.google.gerrit.plugins.codeowners.backend.config.CodeOwnersPluginConfigSnapshot;
import com.google.gerrit.plugins.codeowners.backend.config.CodeOwnersPluginConfiguration;
import com.google.gerrit.plugins.codeowners.metrics.CodeOwnerMetrics;
import com.google.gerrit.plugins.codeowners.util.JgitPath;
import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.BatchUpdateOp;
import com.google.gerrit.server.update.ChangeContext;
import com.google.gerrit.server.update.RetryHelper;
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

/**
 * Callback that is invoked when a user is added as a reviewer.
 *
 * <p>If a code owner was added as reviewer add a change message that lists the files that are owned
 * by the reviewer.
 */
@Singleton
public class CodeOwnersOnAddReviewer implements ReviewerAddedListener {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  private static final String TAG_ADD_REVIEWER =
      ChangeMessagesUtil.AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "code-owners:addReviewer";

  private final CodeOwnersPluginConfiguration codeOwnersPluginConfiguration;
  private final CodeOwnerApprovalCheck codeOwnerApprovalCheck;
  private final Provider<CurrentUser> userProvider;
  private final RetryHelper retryHelper;
  private final ChangeNotes.Factory changeNotesFactory;
  private final AccountCache accountCache;
  private final ChangeMessagesUtil changeMessageUtil;
  private final CodeOwnerMetrics codeOwnerMetrics;

  @Inject
  CodeOwnersOnAddReviewer(
      CodeOwnersPluginConfiguration codeOwnersPluginConfiguration,
      CodeOwnerApprovalCheck codeOwnerApprovalCheck,
      Provider<CurrentUser> userProvider,
      RetryHelper retryHelper,
      ChangeNotes.Factory changeNotesFactory,
      AccountCache accountCache,
      ChangeMessagesUtil changeMessageUtil,
      CodeOwnerMetrics codeOwnerMetrics) {
    this.codeOwnersPluginConfiguration = codeOwnersPluginConfiguration;
    this.codeOwnerApprovalCheck = codeOwnerApprovalCheck;
    this.userProvider = userProvider;
    this.retryHelper = retryHelper;
    this.changeNotesFactory = changeNotesFactory;
    this.accountCache = accountCache;
    this.changeMessageUtil = changeMessageUtil;
    this.codeOwnerMetrics = codeOwnerMetrics;
  }

  @Override
  public void onReviewersAdded(Event event) {
    Change.Id changeId = Change.id(event.getChange()._number);
    Project.NameKey projectName = Project.nameKey(event.getChange().project);

    CodeOwnersPluginConfigSnapshot codeOwnersConfig =
        codeOwnersPluginConfiguration.getProjectConfig(projectName);
    int maxPathsInChangeMessages = codeOwnersConfig.getMaxPathsInChangeMessages();
    if (codeOwnersConfig.isDisabled(event.getChange().branch) || maxPathsInChangeMessages <= 0) {
      return;
    }

    try (Timer0.Context ctx = codeOwnerMetrics.addChangeMessageOnAddReviewer.start()) {
      retryHelper
          .changeUpdate(
              "addCodeOwnersMessageOnAddReviewer",
              updateFactory -> {
                try (BatchUpdate batchUpdate =
                    updateFactory.create(projectName, userProvider.get(), TimeUtil.nowTs())) {
                  batchUpdate.addOp(
                      changeId, new Op(event.getReviewers(), maxPathsInChangeMessages));
                  batchUpdate.execute();
                }
                return null;
              })
          .call();
    } catch (Exception e) {
      logger.atSevere().withCause(e).log(
          String.format(
              "Failed to post code-owners change message for reviewer on change %s in project %s.",
              changeId, projectName));
    }
  }

  private class Op implements BatchUpdateOp {
    private final List<AccountInfo> reviewers;
    private final int limit;

    Op(List<AccountInfo> reviewers, int limit) {
      this.reviewers = reviewers;
      this.limit = limit;
    }

    @Override
    public boolean updateChange(ChangeContext ctx) throws Exception {
      String message =
          reviewers.stream()
              .map(accountInfo -> Account.id(accountInfo._accountId))
              .map(
                  reviewerAccountId ->
                      buildMessageForReviewer(
                          ctx.getProject(), ctx.getChange().getId(), reviewerAccountId))
              .filter(Optional::isPresent)
              .map(Optional::get)
              .collect(joining("\n"));

      if (message.isEmpty()) {
        return false;
      }

      ChangeMessage changeMessage = ChangeMessagesUtil.newMessage(ctx, message, TAG_ADD_REVIEWER);
      changeMessageUtil.addChangeMessage(
          ctx.getUpdate(ctx.getChange().currentPatchSetId()), changeMessage);
      return true;
    }

    private Optional<String> buildMessageForReviewer(
        Project.NameKey projectName, Change.Id changeId, Account.Id reviewerAccountId) {
      ChangeNotes changeNotes = changeNotesFactory.create(projectName, changeId);

      ImmutableList<Path> ownedPaths;
      try {
        // limit + 1, so that we can show an indicator if there are more than <limit> files.
        ownedPaths =
            codeOwnerApprovalCheck.getOwnedPaths(
                changeNotes, changeNotes.getCurrentPatchSet(), reviewerAccountId, limit + 1);
      } catch (RestApiException e) {
        logger.atFine().withCause(e).log(
            "Couldn't compute owned paths of change %s for account %s",
            changeNotes.getChangeId(), reviewerAccountId.get());
        return Optional.empty();
      }

      if (ownedPaths.isEmpty()) {
        // this reviewer doesn't own any of the modified paths
        return Optional.empty();
      }

      Account reviewerAccount = accountCache.getEvenIfMissing(reviewerAccountId).account();

      StringBuilder message = new StringBuilder();
      message.append(
          String.format(
              "%s who was added as reviewer owns the following files:\n",
              reviewerAccount.getName()));

      if (ownedPaths.size() <= limit) {
        appendPaths(message, ownedPaths.stream());
      } else {
        appendPaths(message, ownedPaths.stream().limit(limit));
        message.append("(more files)\n");
      }

      return Optional.of(message.toString());
    }

    private void appendPaths(StringBuilder message, Stream<Path> pathsToAppend) {
      pathsToAppend.forEach(
          path -> message.append(String.format("* %s\n", JgitPath.of(path).get())));
    }
  }
}
