// Copyright (C) 2020 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.Objects.requireNonNull;

import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.LegacySubmitRequirement;
import com.google.gerrit.entities.SubmitRecord;
import com.google.gerrit.extensions.annotations.Exports;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.metrics.Timer0;
import com.google.gerrit.plugins.codeowners.backend.config.CodeOwnersPluginConfiguration;
import com.google.gerrit.plugins.codeowners.backend.config.InvalidPluginConfigurationException;
import com.google.gerrit.plugins.codeowners.metrics.CodeOwnerMetrics;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.patch.DiffNotAvailableException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.rules.SubmitRule;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.IOException;
import java.nio.file.InvalidPathException;
import java.util.Optional;

/** Submit rule that checks that all files in a change have been approved by their code owners. */
@Singleton
class CodeOwnerSubmitRule implements SubmitRule {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  public static class Module extends AbstractModule {
    @Override
    public void configure() {
      bind(SubmitRule.class)
          .annotatedWith(Exports.named("CodeOwnerSubmitRule"))
          .to(CodeOwnerSubmitRule.class);
    }
  }

  private static final LegacySubmitRequirement SUBMIT_REQUIREMENT =
      LegacySubmitRequirement.builder()
          .setFallbackText("Code Owners")
          .setType("code-owners")
          .build();

  private final CodeOwnersPluginConfiguration codeOwnersPluginConfiguration;
  private final CodeOwnerApprovalCheck codeOwnerApprovalCheck;
  private final CodeOwnerMetrics codeOwnerMetrics;

  @Inject
  CodeOwnerSubmitRule(
      CodeOwnersPluginConfiguration codeOwnersPluginConfiguration,
      CodeOwnerApprovalCheck codeOwnerApprovalCheck,
      CodeOwnerMetrics codeOwnerMetrics) {
    this.codeOwnersPluginConfiguration = codeOwnersPluginConfiguration;
    this.codeOwnerApprovalCheck = codeOwnerApprovalCheck;
    this.codeOwnerMetrics = codeOwnerMetrics;
  }

  @Override
  public Optional<SubmitRecord> evaluate(ChangeData changeData) {
    try {
      requireNonNull(changeData, "changeData");

      if (changeData.change().isClosed()) {
        return Optional.empty();
      }

      try (Timer0.Context ctx = codeOwnerMetrics.runCodeOwnerSubmitRule.start()) {
        codeOwnerMetrics.countCodeOwnerSubmitRuleRuns.increment();
        logger.atFine().log(
            "run code owner submit rule (project = %s, change = %d)",
            changeData.project().get(), changeData.getId().get());

        if (codeOwnersPluginConfiguration
            .getProjectConfig(changeData.project())
            .isDisabled(changeData.change().getDest().branch())) {
          logger.atFine().log(
              "code owners functionality is disabled for branch %s", changeData.change().getDest());
          return Optional.empty();
        }

        return Optional.of(getSubmitRecord(changeData.notes()));
      }
    } catch (RestApiException e) {
      logger.atFine().withCause(e).log(
          String.format(
              "Couldn't evaluate code owner statuses for patch set %d of change %d.",
              changeData.currentPatchSet().id().get(), changeData.change().getId().get()));
      return Optional.of(notReady());
    } catch (Exception e) {
      // Whether the exception should be treated as RULE_ERROR.
      // RULE_ERROR must only be returned if the exception is caused by user misconfiguration (e.g.
      // an invalid OWNERS file), but not for internal server errors.
      boolean isRuleError = false;

      String cause = e.getClass().getSimpleName();
      String errorMessage = "Failed to evaluate code owner statuses";
      if (changeData != null) {
        errorMessage +=
            String.format(
                " for patch set %d of change %d",
                changeData.currentPatchSet().id().get(), changeData.change().getId().get());
      }
      Optional<InvalidPathException> invalidPathException =
          CodeOwnersExceptionHook.getInvalidPathException(e);
      Optional<InvalidPluginConfigurationException> invalidPluginConfigurationException =
          CodeOwnersExceptionHook.getInvalidPluginConfigurationCause(e);
      Optional<InvalidCodeOwnerConfigException> invalidCodeOwnerConfigException =
          CodeOwners.getInvalidCodeOwnerConfigCause(e);
      if (invalidPathException.isPresent()) {
        isRuleError = true;
        cause = "invalid_path";
        errorMessage += String.format(" (cause: %s)", invalidPathException.get().getMessage());
      } else if (invalidPluginConfigurationException.isPresent()) {
        isRuleError = true;
        cause = "invalid_plugin_configuration";
        errorMessage +=
            String.format(" (cause: %s)", invalidPluginConfigurationException.get().getMessage());
      } else if (invalidCodeOwnerConfigException.isPresent()) {
        isRuleError = true;
        codeOwnerMetrics.countInvalidCodeOwnerConfigFiles.increment(
            invalidCodeOwnerConfigException.get().getProjectName().get(),
            invalidCodeOwnerConfigException.get().getRef(),
            invalidCodeOwnerConfigException.get().getCodeOwnerConfigFilePath());

        cause = "invalid_code_owner_config_file";
        errorMessage +=
            String.format(" (cause: %s)", invalidCodeOwnerConfigException.get().getMessage());

        Optional<String> invalidCodeOwnerConfigInfoUrl =
            codeOwnersPluginConfiguration
                .getProjectConfig(invalidCodeOwnerConfigException.get().getProjectName())
                .getInvalidCodeOwnerConfigInfoUrl();
        if (invalidCodeOwnerConfigInfoUrl.isPresent()) {
          errorMessage +=
              String.format(".\nFor help check %s", invalidCodeOwnerConfigInfoUrl.get());
        }
      }
      errorMessage += ".";

      if (isRuleError) {
        codeOwnerMetrics.countCodeOwnerSubmitRuleErrors.increment(cause);

        logger.atWarning().log(errorMessage);
        return Optional.of(ruleError(errorMessage));
      }
      throw new CodeOwnersInternalServerErrorException(errorMessage, e);
    }
  }

  private SubmitRecord getSubmitRecord(ChangeNotes changeNotes)
      throws ResourceConflictException, IOException, DiffNotAvailableException {
    requireNonNull(changeNotes, "changeNotes");
    return codeOwnerApprovalCheck.isSubmittable(changeNotes) ? ok() : notReady();
  }

  private static SubmitRecord ok() {
    SubmitRecord submitRecord = new SubmitRecord();
    submitRecord.status = SubmitRecord.Status.OK;
    submitRecord.requirements = ImmutableList.of(SUBMIT_REQUIREMENT);
    return submitRecord;
  }

  private static SubmitRecord notReady() {
    SubmitRecord submitRecord = new SubmitRecord();
    submitRecord.status = SubmitRecord.Status.NOT_READY;
    submitRecord.requirements = ImmutableList.of(SUBMIT_REQUIREMENT);
    return submitRecord;
  }

  private static SubmitRecord ruleError(String reason) {
    SubmitRecord submitRecord = new SubmitRecord();
    submitRecord.errorMessage = reason;
    submitRecord.status = SubmitRecord.Status.RULE_ERROR;
    return submitRecord;
  }
}
