// 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.config;

import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.util.Objects.requireNonNull;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.LabelType;
import com.google.gerrit.entities.Project;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerBackend;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerReference;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnersInternalServerErrorException;
import com.google.gerrit.plugins.codeowners.backend.EnableImplicitApprovals;
import com.google.gerrit.plugins.codeowners.backend.FallbackCodeOwners;
import com.google.gerrit.plugins.codeowners.common.CodeOwnerConfigValidationPolicy;
import com.google.gerrit.plugins.codeowners.common.MergeCommitStrategy;
import com.google.gerrit.server.account.Emails;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.eclipse.jgit.lib.Config;

/** Snapshot of the project-specific code-owners plugin configuration. */
public class CodeOwnersPluginProjectConfigSnapshot {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  public interface Factory {
    CodeOwnersPluginProjectConfigSnapshot create(Project.NameKey projectName);
  }

  private final ProjectCache projectCache;
  private final Emails emails;
  private final BackendConfig backendConfig;
  private final GeneralConfig generalConfig;
  private final OverrideApprovalConfig overrideApprovalConfig;
  private final RequiredApprovalConfig requiredApprovalConfig;
  private final StatusConfig statusConfig;
  private final Project.NameKey projectName;
  private final Config pluginConfig;

  @Nullable private Optional<String> fileExtension;
  @Nullable private Boolean codeOwnerConfigsReadOnly;
  @Nullable private Boolean exemptPureReverts;
  @Nullable private Boolean rejectNonResolvableCodeOwners;
  @Nullable private Boolean rejectNonResolvableImports;

  @Nullable
  private CodeOwnerConfigValidationPolicy codeOwnerConfigValidationPolicyForCommitReceived;

  @Nullable private CodeOwnerConfigValidationPolicy codeOwnerConfigValidationPolicyForSubmit;
  @Nullable private MergeCommitStrategy mergeCommitStrategy;
  @Nullable private FallbackCodeOwners fallbackCodeOwners;
  @Nullable private Integer maxPathsInChangeMessages;
  @Nullable private ImmutableSet<CodeOwnerReference> globalCodeOwners;
  @Nullable private ImmutableSet<Account.Id> exemptedAccounts;
  @Nullable private Optional<String> overrideInfoUrl;
  @Nullable private Optional<String> invalidCodeOwnerConfigInfoUrl;
  private Map<String, Boolean> disabledByBranch = new HashMap<>();
  @Nullable private Boolean isDisabled;
  private Map<String, CodeOwnerBackend> backendByBranch = new HashMap<>();
  @Nullable private CodeOwnerBackend backend;
  @Nullable private Boolean implicitApprovalsEnabled;
  @Nullable private RequiredApproval requiredApproval;
  @Nullable private ImmutableSortedSet<RequiredApproval> overrideApprovals;

  @Inject
  CodeOwnersPluginProjectConfigSnapshot(
      CodeOwnersPluginConfig.Factory codeOwnersPluginConfigFactory,
      ProjectCache projectCache,
      Emails emails,
      BackendConfig backendConfig,
      GeneralConfig generalConfig,
      OverrideApprovalConfig overrideApprovalConfig,
      RequiredApprovalConfig requiredApprovalConfig,
      StatusConfig statusConfig,
      @Assisted Project.NameKey projectName) {
    this.projectCache = projectCache;
    this.emails = emails;
    this.backendConfig = backendConfig;
    this.generalConfig = generalConfig;
    this.overrideApprovalConfig = overrideApprovalConfig;
    this.requiredApprovalConfig = requiredApprovalConfig;
    this.statusConfig = statusConfig;
    this.projectName = projectName;
    this.pluginConfig = codeOwnersPluginConfigFactory.create(projectName).get();
  }

  /** Gets the file extension of code owner config files, if any configured. */
  public Optional<String> getFileExtension() {
    if (fileExtension == null) {
      fileExtension = generalConfig.getFileExtension(pluginConfig);
    }
    return fileExtension;
  }

  /** Whether code owner configs are read-only. */
  public boolean areCodeOwnerConfigsReadOnly() {
    if (codeOwnerConfigsReadOnly == null) {
      codeOwnerConfigsReadOnly = generalConfig.getReadOnly(projectName, pluginConfig);
    }
    return codeOwnerConfigsReadOnly;
  }

  /** Whether pure revert changes are exempted from needing code owner approvals for submit. */
  public boolean arePureRevertsExempted() {
    if (exemptPureReverts == null) {
      exemptPureReverts = generalConfig.getExemptPureReverts(projectName, pluginConfig);
    }
    return exemptPureReverts;
  }

  /**
   * Whether newly added non-resolvable code owners should be rejected on commit received and
   * submit.
   *
   * @param branchName the branch for which it should be checked whether non-resolvable code owners
   *     should be rejected
   */
  public boolean rejectNonResolvableCodeOwners(String branchName) {
    if (rejectNonResolvableCodeOwners == null) {
      rejectNonResolvableCodeOwners = readRejectNonResolvableCodeOwners(branchName);
    }
    return rejectNonResolvableCodeOwners;
  }

  private boolean readRejectNonResolvableCodeOwners(String branchName) {
    requireNonNull(branchName, "branchName");

    Optional<Boolean> branchSpecificFlag =
        generalConfig.getRejectNonResolvableCodeOwnersForBranch(
            BranchNameKey.create(projectName, branchName), pluginConfig);
    if (branchSpecificFlag.isPresent()) {
      return branchSpecificFlag.get();
    }

    return generalConfig.getRejectNonResolvableCodeOwners(projectName, pluginConfig);
  }

  /**
   * Whether newly added non-resolvable imports should be rejected on commit received and submit.
   *
   * @param branchName the branch for which it should be checked whether non-resolvable imports
   *     should be rejected
   */
  public boolean rejectNonResolvableImports(String branchName) {
    if (rejectNonResolvableImports == null) {
      rejectNonResolvableImports = readRejectNonResolvableImports(branchName);
    }
    return rejectNonResolvableImports;
  }

  private boolean readRejectNonResolvableImports(String branchName) {
    requireNonNull(branchName, "branchName");

    Optional<Boolean> branchSpecificFlag =
        generalConfig.getRejectNonResolvableImportsForBranch(
            BranchNameKey.create(projectName, branchName), pluginConfig);
    if (branchSpecificFlag.isPresent()) {
      return branchSpecificFlag.get();
    }

    return generalConfig.getRejectNonResolvableImports(projectName, pluginConfig);
  }

  /**
   * Whether code owner configs should be validated when a commit is received.
   *
   * @param branchName the branch for which it should be checked whether code owner configs should
   *     be validated on commit received
   */
  public CodeOwnerConfigValidationPolicy getCodeOwnerConfigValidationPolicyForCommitReceived(
      String branchName) {
    if (codeOwnerConfigValidationPolicyForCommitReceived == null) {
      codeOwnerConfigValidationPolicyForCommitReceived =
          readCodeOwnerConfigValidationPolicyForCommitReceived(branchName);
    }
    return codeOwnerConfigValidationPolicyForCommitReceived;
  }

  private CodeOwnerConfigValidationPolicy readCodeOwnerConfigValidationPolicyForCommitReceived(
      String branchName) {
    requireNonNull(branchName, "branchName");

    Optional<CodeOwnerConfigValidationPolicy> branchSpecificPolicy =
        generalConfig.getCodeOwnerConfigValidationPolicyForCommitReceivedForBranch(
            BranchNameKey.create(projectName, branchName), pluginConfig);
    if (branchSpecificPolicy.isPresent()) {
      return branchSpecificPolicy.get();
    }

    return generalConfig.getCodeOwnerConfigValidationPolicyForCommitReceived(
        projectName, pluginConfig);
  }

  /**
   * Whether code owner configs should be validated when a change is submitted.
   *
   * @param branchName the branch for which it should be checked whether code owner configs should
   *     be validated on submit
   */
  public CodeOwnerConfigValidationPolicy getCodeOwnerConfigValidationPolicyForSubmit(
      String branchName) {
    if (codeOwnerConfigValidationPolicyForSubmit == null) {
      codeOwnerConfigValidationPolicyForSubmit =
          readCodeOwnerConfigValidationPolicyForSubmit(branchName);
    }
    return codeOwnerConfigValidationPolicyForSubmit;
  }

  private CodeOwnerConfigValidationPolicy readCodeOwnerConfigValidationPolicyForSubmit(
      String branchName) {
    requireNonNull(branchName, "branchName");

    Optional<CodeOwnerConfigValidationPolicy> branchSpecificPolicy =
        generalConfig.getCodeOwnerConfigValidationPolicyForSubmitForBranch(
            BranchNameKey.create(projectName, branchName), pluginConfig);
    if (branchSpecificPolicy.isPresent()) {
      return branchSpecificPolicy.get();
    }

    return generalConfig.getCodeOwnerConfigValidationPolicyForSubmit(projectName, pluginConfig);
  }

  /** Gets the merge commit strategy. */
  public MergeCommitStrategy getMergeCommitStrategy() {
    if (mergeCommitStrategy == null) {
      mergeCommitStrategy = generalConfig.getMergeCommitStrategy(projectName, pluginConfig);
    }
    return mergeCommitStrategy;
  }

  /** Gets the fallback code owners. */
  public FallbackCodeOwners getFallbackCodeOwners() {
    if (fallbackCodeOwners == null) {
      fallbackCodeOwners = generalConfig.getFallbackCodeOwners(projectName, pluginConfig);
    }
    return fallbackCodeOwners;
  }

  /** Gets the max paths in change messages. */
  public int getMaxPathsInChangeMessages() {
    if (maxPathsInChangeMessages == null) {
      maxPathsInChangeMessages =
          generalConfig.getMaxPathsInChangeMessages(projectName, pluginConfig);
    }
    return maxPathsInChangeMessages;
  }

  /** Gets the global code owners. */
  public ImmutableSet<CodeOwnerReference> getGlobalCodeOwners() {
    if (globalCodeOwners == null) {
      globalCodeOwners = generalConfig.getGlobalCodeOwners(pluginConfig);
    }
    return globalCodeOwners;
  }

  /** Gets the accounts that are exempted from requiring code owner approvals. */
  public ImmutableSet<Account.Id> getExemptedAccounts() {
    if (exemptedAccounts == null) {
      exemptedAccounts = lookupExemptedAccounts();
    }
    return exemptedAccounts;
  }

  private ImmutableSet<Account.Id> lookupExemptedAccounts() {
    ImmutableSet<String> exemptedUsers = generalConfig.getExemptedUsers(pluginConfig);

    try {
      ImmutableSetMultimap<String, Account.Id> exemptedAccounts =
          emails.getAccountsFor(exemptedUsers.toArray(new String[0]));

      exemptedUsers.stream()
          .filter(exemptedUser -> !exemptedAccounts.containsKey(exemptedUser))
          .forEach(
              exemptedUser ->
                  logger.atWarning().log(
                      "Ignoring exempted user %s for project %s: not found",
                      exemptedUser, projectName));

      return ImmutableSet.copyOf(exemptedAccounts.values());
    } catch (IOException e) {
      throw new CodeOwnersInternalServerErrorException(
          String.format(
              "Failed to resolve exempted users %s on project %s", exemptedUsers, projectName),
          e);
    }
  }

  /** Gets the override info URL that is configured. */
  public Optional<String> getOverrideInfoUrl() {
    if (overrideInfoUrl == null) {
      overrideInfoUrl = generalConfig.getOverrideInfoUrl(pluginConfig);
    }
    return overrideInfoUrl;
  }

  /** Gets the invalid code owner config info URL that is configured. */
  public Optional<String> getInvalidCodeOwnerConfigInfoUrl() {
    if (invalidCodeOwnerConfigInfoUrl == null) {
      invalidCodeOwnerConfigInfoUrl = generalConfig.getInvalidCodeOwnerConfigInfoUrl(pluginConfig);
    }
    return invalidCodeOwnerConfigInfoUrl;
  }

  /**
   * Whether the code owners functionality is disabled for the given branch.
   *
   * <p>The configuration is evaluated in the following order:
   *
   * <ul>
   *   <li>disabled configuration for the branch (with inheritance)
   *   <li>disabled configuration for the project (with inheritance)
   *   <li>hard-coded default (not disabled)
   * </ul>
   *
   * <p>The first disabled configuration that exists counts and the evaluation is stopped.
   *
   * @param branchName the branch for which it should be checked whether the code owners
   *     functionality is disabled
   * @return {@code true} if the code owners functionality is disabled for the given branch,
   *     otherwise {@code false}
   */
  public boolean isDisabled(String branchName) {
    requireNonNull(branchName, "branchName");

    BranchNameKey branchNameKey = BranchNameKey.create(projectName, branchName);
    return disabledByBranch.computeIfAbsent(
        branchNameKey.branch(),
        b -> {
          boolean isDisabled = statusConfig.isDisabledForBranch(pluginConfig, branchNameKey);
          if (isDisabled) {
            return true;
          }
          return isDisabled();
        });
  }

  /**
   * Whether the code owners functionality is disabled for the given project.
   *
   * <p>The configuration is evaluated in the following order:
   *
   * <ul>
   *   <li>disabled configuration for the project (with inheritance)
   *   <li>hard-coded default (not disabled)
   * </ul>
   *
   * <p>The first disabled configuration that exists counts and the evaluation is stopped.
   *
   * @return {@code true} if the code owners functionality is disabled, otherwise {@code false}
   */
  public boolean isDisabled() {
    if (isDisabled == null) {
      isDisabled = statusConfig.isDisabledForProject(pluginConfig, projectName);
    }
    return isDisabled;
  }

  /**
   * Returns the configured {@link CodeOwnerBackend} for the given branch.
   *
   * <p>The code owner backend configuration is evaluated in the following order:
   *
   * <ul>
   *   <li>backend configuration for branch (with inheritance, first by full branch name, then by
   *       short branch name)
   *   <li>backend configuration for project (with inheritance)
   *   <li>default backend (first globally configured backend, then hard-coded default backend)
   * </ul>
   *
   * <p>The first code owner backend configuration that exists counts and the evaluation is stopped.
   *
   * @param branchName the branch for which the configured code owner backend should be returned
   * @return the {@link CodeOwnerBackend} that should be used for the branch
   */
  public CodeOwnerBackend getBackend(String branchName) {
    requireNonNull(branchName, "branchName");

    BranchNameKey branchNameKey = BranchNameKey.create(projectName, branchName);
    return backendByBranch.computeIfAbsent(
        branchNameKey.branch(),
        b -> {
          Optional<CodeOwnerBackend> codeOwnerBackend =
              backendConfig.getBackendForBranch(
                  pluginConfig, BranchNameKey.create(projectName, branchName));
          if (codeOwnerBackend.isPresent()) {
            return codeOwnerBackend.get();
          }
          return getBackend();
        });
  }

  /**
   * Returns the configured {@link CodeOwnerBackend}.
   *
   * <p>The code owner backend configuration is evaluated in the following order:
   *
   * <ul>
   *   <li>backend configuration for project (with inheritance)
   *   <li>default backend (first globally configured backend, then hard-coded default backend)
   * </ul>
   *
   * <p>The first code owner backend configuration that exists counts and the evaluation is stopped.
   *
   * @return the {@link CodeOwnerBackend} that should be used
   */
  public CodeOwnerBackend getBackend() {
    if (backend == null) {
      backend = readBackend();
    }
    return backend;
  }

  private CodeOwnerBackend readBackend() {
    // check if a project specific backend is configured
    Optional<CodeOwnerBackend> codeOwnerBackend =
        backendConfig.getBackendForProject(pluginConfig, projectName);
    if (codeOwnerBackend.isPresent()) {
      return codeOwnerBackend.get();
    }

    // fall back to the default backend
    return backendConfig.getDefaultBackend();
  }

  /** Checks whether an implicit code owner approval from the last uploader is assumed. */
  public boolean areImplicitApprovalsEnabled() {
    if (implicitApprovalsEnabled == null) {
      implicitApprovalsEnabled = readImplicitApprovalsEnabled();
    }
    return implicitApprovalsEnabled;
  }

  private boolean readImplicitApprovalsEnabled() {
    EnableImplicitApprovals enableImplicitApprovals =
        generalConfig.getEnableImplicitApprovals(projectName, pluginConfig);
    switch (enableImplicitApprovals) {
      case FALSE:
        logger.atFine().log("implicit approvals on project %s are disabled", projectName);
        return false;
      case TRUE:
        LabelType requiredLabel = getRequiredApproval().labelType();
        if (requiredLabel.isIgnoreSelfApproval()) {
          logger.atFine().log(
              "ignoring implicit approval configuration on project %s since the label of the required"
                  + " approval (%s) is configured to ignore self approvals",
              projectName, requiredLabel);
          return false;
        }
        return true;
      case FORCED:
        logger.atFine().log("implicit approvals on project %s are enforced", projectName);
        return true;
    }
    throw new IllegalStateException(
        String.format(
            "unknown value %s for enableImplicitApprovals configuration in project %s",
            enableImplicitApprovals, projectName));
  }

  /**
   * Returns the approval that is required from code owners to approve the files in a change.
   *
   * <p>Defines which approval counts as code owner approval.
   *
   * <p>The code owner required approval configuration is evaluated in the following order:
   *
   * <ul>
   *   <li>required approval configuration for project (with inheritance)
   *   <li>globally configured required approval
   *   <li>hard-coded default required approval
   * </ul>
   *
   * <p>The first required code owner approval configuration that exists counts and the evaluation
   * is stopped.
   *
   * <p>If the code owner configuration contains multiple required approvals values, the last value
   * is used.
   *
   * @return the required code owner approval that should be used
   */
  public RequiredApproval getRequiredApproval() {
    if (requiredApproval == null) {
      requiredApproval = readRequiredApproval();
    }
    return requiredApproval;
  }

  private RequiredApproval readRequiredApproval() {
    ImmutableList<RequiredApproval> configuredRequiredApprovalConfig =
        getConfiguredRequiredApproval(requiredApprovalConfig);
    if (!configuredRequiredApprovalConfig.isEmpty()) {
      // There can be only one required approval. If multiple ones are configured just use the last
      // one, this is also what Config#getString(String, String, String) does.
      return Iterables.getLast(configuredRequiredApprovalConfig);
    }

    // fall back to hard-coded default required approval
    ProjectState projectState =
        projectCache.get(projectName).orElseThrow(illegalState(projectName));
    return requiredApprovalConfig.createDefault(projectState);
  }

  /**
   * Returns the approvals that are required to override the code owners submit check for a change.
   *
   * <p>If multiple approvals are returned, any of them is sufficient to override the code owners
   * submit check.
   *
   * <p>The override approval configuration is read from:
   *
   * <ul>
   *   <li>the override approval configuration for project (with inheritance)
   *   <li>the globally configured override approval
   * </ul>
   *
   * <p>Override approvals that are configured on project-level extend the inherited override
   * approval configuration.
   *
   * <p>The returned override approvals are sorted alphabetically by their string representation
   * (e.g. {@code Owners-Override+1}).
   *
   * @return the override approvals that should be used, an empty set if no override approval is
   *     configured, in this case the override functionality is disabled
   */
  public ImmutableSortedSet<RequiredApproval> getOverrideApprovals() {
    if (overrideApprovals == null) {
      overrideApprovals = readOverrideApprovals();
    }
    return overrideApprovals;
  }

  private ImmutableSortedSet<RequiredApproval> readOverrideApprovals() {
    try {
      return ImmutableSortedSet.copyOf(
          filterOutDuplicateRequiredApprovals(
              getConfiguredRequiredApproval(overrideApprovalConfig)));
    } catch (InvalidPluginConfigurationException e) {
      logger.atWarning().withCause(e).log(
          "Ignoring invalid override approval configuration for project %s."
              + " Overrides are disabled.",
          projectName.get());
    }

    return ImmutableSortedSet.of();
  }

  /**
   * Filters out duplicate required approvals from the input list.
   *
   * <p>The following entries are considered as duplicate:
   *
   * <ul>
   *   <li>exact identical required approvals (e.g. "Code-Review+2" and "Code-Review+2")
   *   <li>required approvals with the same label name and a higher value (e.g. "Code-Review+2" is
   *       not needed if "Code-Review+1" is already contained, since "Code-Review+1" covers all
   *       "Code-Review" approvals >= 1)
   * </ul>
   */
  private Collection<RequiredApproval> filterOutDuplicateRequiredApprovals(
      ImmutableList<RequiredApproval> requiredApprovals) {
    Map<String, RequiredApproval> requiredApprovalsByLabel = new HashMap<>();
    for (RequiredApproval requiredApproval : requiredApprovals) {
      String labelName = requiredApproval.labelType().getName();
      RequiredApproval otherRequiredApproval = requiredApprovalsByLabel.get(labelName);
      if (otherRequiredApproval != null
          && otherRequiredApproval.value() <= requiredApproval.value()) {
        continue;
      }
      requiredApprovalsByLabel.put(labelName, requiredApproval);
    }
    return requiredApprovalsByLabel.values();
  }

  /**
   * Gets the required approvals that are configured.
   *
   * @param requiredApprovalConfig the config from which the required approvals should be read
   * @return the required approvals that are configured, an empty list if no required approvals are
   *     configured
   */
  private ImmutableList<RequiredApproval> getConfiguredRequiredApproval(
      AbstractRequiredApprovalConfig requiredApprovalConfig) {
    ProjectState projectState =
        projectCache.get(projectName).orElseThrow(illegalState(projectName));
    return requiredApprovalConfig.get(projectState, pluginConfig);
  }
}
