// Copyright (C) 2019 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.checks;

import com.google.common.collect.ImmutableMap;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.exceptions.DuplicateKeyException;
import com.google.gerrit.extensions.api.changes.NotifyHandling;
import com.google.gerrit.extensions.api.changes.NotifyInfo;
import com.google.gerrit.extensions.api.changes.RecipientType;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.plugins.checks.Checks.GetCheckOptions;
import com.google.gerrit.plugins.checks.api.CombinedCheckState;
import com.google.gerrit.plugins.checks.email.CombinedCheckStateUpdatedSender;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.ServerInitiated;
import com.google.gerrit.server.UserInitiated;
import com.google.gerrit.server.change.NotifyResolver;
import com.google.gerrit.server.mail.send.MessageIdGenerator;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import java.io.IOException;
import java.util.Map;
import java.util.Optional;
import org.eclipse.jgit.errors.ConfigInvalidException;

/**
 * API to update checks.
 *
 * <p>Delegates the persistence of checks to the storage layer (see {@link ChecksStorageUpdate}).
 *
 * <p>This class contains additional business logic for updating checks which is independent of the
 * used storage layer (e.g. sending email notifications).
 */
public class ChecksUpdate {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  interface Factory {
    ChecksUpdate create(IdentifiedUser currentUser);

    ChecksUpdate createWithServerIdent();
  }

  private final ChecksStorageUpdate checksStorageUpdate;
  private final CombinedCheckStateCache combinedCheckStateCache;
  private final CombinedCheckStateUpdatedSender.Factory combinedCheckStateUpdatedSenderFactory;
  private final ChangeNotes.Factory notesFactory;
  private final PatchSetUtil psUtil;
  private final Checks checks;
  private final Checkers checkers;
  private final NotifyResolver notifyResolver;
  private final MessageIdGenerator messageIdGenerator;
  private final Optional<IdentifiedUser> currentUser;

  @AssistedInject
  ChecksUpdate(
      @UserInitiated ChecksStorageUpdate checksStorageUpdate,
      CombinedCheckStateCache combinedCheckStateCache,
      CombinedCheckStateUpdatedSender.Factory combinedCheckStateUpdatedSenderFactory,
      ChangeNotes.Factory notesFactory,
      PatchSetUtil psUtil,
      Checks checks,
      Checkers checkers,
      NotifyResolver notifyResolver,
      MessageIdGenerator messageIdGenerator,
      @Assisted IdentifiedUser currentUser) {
    this.checksStorageUpdate = checksStorageUpdate;
    this.combinedCheckStateCache = combinedCheckStateCache;
    this.combinedCheckStateUpdatedSenderFactory = combinedCheckStateUpdatedSenderFactory;
    this.notesFactory = notesFactory;
    this.psUtil = psUtil;
    this.checks = checks;
    this.checkers = checkers;
    this.notifyResolver = notifyResolver;
    this.messageIdGenerator = messageIdGenerator;
    this.currentUser = Optional.of(currentUser);
  }

  @AssistedInject
  ChecksUpdate(
      @ServerInitiated ChecksStorageUpdate checksStorageUpdate,
      CombinedCheckStateCache combinedCheckStateCache,
      CombinedCheckStateUpdatedSender.Factory combinedCheckStateUpdatedSenderFactory,
      ChangeNotes.Factory notesFactory,
      PatchSetUtil psUtil,
      Checks checks,
      Checkers checkers,
      NotifyResolver notifyResolver,
      MessageIdGenerator messageIdGenerator) {
    this.checksStorageUpdate = checksStorageUpdate;
    this.combinedCheckStateCache = combinedCheckStateCache;
    this.combinedCheckStateUpdatedSenderFactory = combinedCheckStateUpdatedSenderFactory;
    this.notesFactory = notesFactory;
    this.psUtil = psUtil;
    this.checks = checks;
    this.checkers = checkers;
    this.notifyResolver = notifyResolver;
    this.messageIdGenerator = messageIdGenerator;
    this.currentUser = Optional.empty();
  }

  public Check createCheck(
      CheckKey key,
      CheckUpdate checkUpdate,
      @Nullable NotifyHandling notifyHandling,
      @Nullable Map<RecipientType, NotifyInfo> notifyDetails)
      throws DuplicateKeyException, BadRequestException, IOException, ConfigInvalidException {
    CombinedCheckState oldCombinedCheckState =
        combinedCheckStateCache.get(key.repository(), key.patchSet());

    Check check = checksStorageUpdate.createCheck(key, checkUpdate);

    CombinedCheckState newCombinedCheckState =
        combinedCheckStateCache.get(key.repository(), key.patchSet());
    maybeSendEmail(
        notifyHandling, notifyDetails, check, oldCombinedCheckState, newCombinedCheckState);

    return check;
  }

  public Check updateCheck(
      CheckKey key,
      CheckUpdate checkUpdate,
      @Nullable NotifyHandling notifyHandling,
      @Nullable Map<RecipientType, NotifyInfo> notifyDetails)
      throws BadRequestException, IOException, ConfigInvalidException {
    CombinedCheckState oldCombinedCheckState =
        combinedCheckStateCache.get(key.repository(), key.patchSet());

    Check check = checksStorageUpdate.updateCheck(key, checkUpdate);

    CombinedCheckState newCombinedCheckState =
        combinedCheckStateCache.get(key.repository(), key.patchSet());
    maybeSendEmail(
        notifyHandling, notifyDetails, check, oldCombinedCheckState, newCombinedCheckState);

    return check;
  }

  private void maybeSendEmail(
      @Nullable NotifyHandling notifyHandling,
      @Nullable Map<RecipientType, NotifyInfo> notifyDetails,
      Check updatedCheck,
      CombinedCheckState oldCombinedCheckState,
      CombinedCheckState newCombinedCheckState)
      throws BadRequestException, IOException, ConfigInvalidException {
    if (oldCombinedCheckState == newCombinedCheckState) {
      // do not send an email if the combined check state was not updated
      return;
    }

    CheckKey checkKey = updatedCheck.key();
    ChangeNotes changeNotes =
        notesFactory.create(checkKey.repository(), checkKey.patchSet().changeId());
    if (!checkKey.patchSet().equals(changeNotes.getCurrentPatchSet().id())) {
      // do not send an email for non-current patch sets
      return;
    }

    notifyHandling =
        notifyHandling != null
            ? notifyHandling
            : newCombinedCheckState == CombinedCheckState.SUCCESSFUL
                    || newCombinedCheckState == CombinedCheckState.NOT_RELEVANT
                ? NotifyHandling.ALL
                : NotifyHandling.OWNER;
    NotifyResolver.Result notify = notifyResolver.resolve(notifyHandling, notifyDetails);

    try {
      CombinedCheckStateUpdatedSender sender =
          combinedCheckStateUpdatedSenderFactory.create(
              checkKey.repository(), checkKey.patchSet().changeId());

      if (currentUser.isPresent()) {
        sender.setFrom(currentUser.get().getAccountId());
      }

      PatchSet patchSet = psUtil.get(changeNotes, checkKey.patchSet());
      sender.setPatchSet(patchSet);
      sender.setCombinedCheckState(oldCombinedCheckState, newCombinedCheckState);
      sender.setCheck(
          checkers
              .getChecker(checkKey.checkerUuid())
              .orElseThrow(
                  () ->
                      new IllegalStateException(
                          String.format(
                              "checker %s of check %s not found",
                              checkKey.checkerUuid(), checkKey))),
          updatedCheck);
      sender.setNotify(notify);
      sender.setChecksByChecker(getAllChecksByChecker(checkKey));
      sender.setMessageId(
          messageIdGenerator.fromChangeUpdate(checkKey.repository(), checkKey.patchSet()));
      sender.send();
    } catch (Exception e) {
      logger.atSevere().withCause(e).log(
          "Cannot email update for change %s", checkKey.patchSet().changeId());
    }
  }

  private ImmutableMap<Checker, Check> getAllChecksByChecker(CheckKey checkKey)
      throws IllegalStateException, IOException, ConfigInvalidException {
    ImmutableMap.Builder<Checker, Check> checksByChecker = ImmutableMap.builder();
    for (Check check :
        checks.getChecks(
            checkKey.repository(), checkKey.patchSet(), GetCheckOptions.withBackfilling())) {
      Checker checker =
          checkers
              .getChecker(check.key().checkerUuid())
              .orElseThrow(
                  () ->
                      new IllegalStateException(
                          String.format(
                              "checker %s of check %s not found",
                              checkKey.checkerUuid(), check.key())));
      checksByChecker.put(checker, check);
    }
    return checksByChecker.build();
  }
}
