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

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

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.LabelType;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
import com.google.gerrit.plugins.codeowners.api.CodeOwnerConfigValidationPolicy;
import com.google.gerrit.plugins.codeowners.api.MergeCommitStrategy;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerBackend;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerReference;
import com.google.gerrit.plugins.codeowners.backend.FallbackCodeOwners;
import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.eclipse.jgit.lib.Config;

/**
 * The configuration of the code-owners plugin.
 *
 * <p>The global configuration of the code-owners plugin is stored in the {@code gerrit.config} file
 * in the {@code plugin.code-owners} subsection.
 *
 * <p>In addition there is configuration on project level that is stored in {@code
 * code-owners.config} files that are stored in the {@code refs/meta/config} branches of the
 * projects.
 *
 * <p>Parameters that are not set for a project are inherited from the parent project.
 */
@Singleton
public class CodeOwnersPluginConfiguration {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  @VisibleForTesting public static final String SECTION_CODE_OWNERS = "codeOwners";

  @VisibleForTesting
  static final String KEY_ENABLE_EXPERIMENTAL_REST_ENDPOINTS = "enableExperimentalRestEndpoints";

  private final String pluginName;
  private final PluginConfigFactory pluginConfigFactory;
  private final ProjectCache projectCache;
  private final GeneralConfig generalConfig;
  private final StatusConfig statusConfig;
  private final BackendConfig backendConfig;
  private final RequiredApprovalConfig requiredApprovalConfig;
  private final OverrideApprovalConfig overrideApprovalConfig;

  @Inject
  CodeOwnersPluginConfiguration(
      @PluginName String pluginName,
      PluginConfigFactory pluginConfigFactory,
      ProjectCache projectCache,
      GeneralConfig generalConfig,
      StatusConfig statusConfig,
      BackendConfig backendConfig,
      RequiredApprovalConfig requiredApprovalConfig,
      OverrideApprovalConfig overrideApprovalConfig) {
    this.pluginName = pluginName;
    this.pluginConfigFactory = pluginConfigFactory;
    this.projectCache = projectCache;
    this.generalConfig = generalConfig;
    this.statusConfig = statusConfig;
    this.backendConfig = backendConfig;
    this.requiredApprovalConfig = requiredApprovalConfig;
    this.overrideApprovalConfig = overrideApprovalConfig;
  }

  /**
   * Gets the file extension that is configured for the given project.
   *
   * @param project the project for which the configured file extension should be returned
   * @return the file extension that is configured for the given project
   */
  public Optional<String> getFileExtension(Project.NameKey project) {
    requireNonNull(project, "project");
    return generalConfig.getFileExtension(getPluginConfig(project));
  }

  /**
   * Checks whether code owner configs in the given project are read-only.
   *
   * @param project the project for it should be checked whether code owner configs are read-only
   * @return whether code owner configs in the given project are read-only
   */
  public boolean areCodeOwnerConfigsReadOnly(Project.NameKey project) {
    requireNonNull(project, "project");
    return generalConfig.getReadOnly(getPluginConfig(project));
  }

  /**
   * Whether code owner configs should be validated when a commit is received.
   *
   * @param project the project for it should be checked whether code owner configs should be
   *     validated when a commit is received
   * @return whether code owner configs should be validated when a commit is received
   */
  public CodeOwnerConfigValidationPolicy getCodeOwnerConfigValidationPolicyForCommitReceived(
      Project.NameKey project) {
    requireNonNull(project, "project");
    return generalConfig.getCodeOwnerConfigValidationPolicyForCommitReceived(
        project, getPluginConfig(project));
  }

  /**
   * Whether code owner configs should be validated when a change is submitted.
   *
   * @param project the project for it should be checked whether code owner configs should be
   *     validated when a change is submitted
   * @return whether code owner configs should be validated when a change is submitted
   */
  public CodeOwnerConfigValidationPolicy getCodeOwnerConfigValidationPolicyForSubmit(
      Project.NameKey project) {
    requireNonNull(project, "project");
    return generalConfig.getCodeOwnerConfigValidationPolicyForSubmit(
        project, getPluginConfig(project));
  }

  /**
   * Gets the merge commit strategy for the given project.
   *
   * @param project the project for which the merge commit strategy should be retrieved
   * @return the merge commit strategy for the given project
   */
  public MergeCommitStrategy getMergeCommitStrategy(Project.NameKey project) {
    requireNonNull(project, "project");
    return generalConfig.getMergeCommitStrategy(project, getPluginConfig(project));
  }

  /**
   * Gets the fallback code owners for the given project.
   *
   * @param project the project for which the fallback code owners should be retrieved
   * @return the fallback code owners for the given project
   */
  public FallbackCodeOwners getFallbackCodeOwners(Project.NameKey project) {
    requireNonNull(project, "project");
    return generalConfig.getFallbackCodeOwners(project, getPluginConfig(project));
  }

  /**
   * Checks whether an implicit code owner approval from the last uploader is assumed.
   *
   * @param project the project for it should be checked whether implict approvals are enabled
   * @return whether an implicit code owner approval from the last uploader is assumed
   */
  public boolean areImplicitApprovalsEnabled(Project.NameKey project) {
    requireNonNull(project, "project");
    LabelType requiredLabel = getRequiredApproval(project).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",
          project, requiredLabel);
      return false;
    }
    return generalConfig.getEnableImplicitApprovals(getPluginConfig(project));
  }

  /**
   * Gets the global code owners of the given project.
   *
   * @param project the project for which the global code owners should be returned
   * @return the global code owners of the given project
   */
  public ImmutableSet<CodeOwnerReference> getGlobalCodeOwners(Project.NameKey project) {
    requireNonNull(project, "project");
    return generalConfig.getGlobalCodeOwners(getPluginConfig(project));
  }

  /**
   * Gets the override info URL that is configured for the given project.
   *
   * @param project the project for which the configured override info URL should be returned
   * @return the override info URL that is configured for the given project
   */
  public Optional<String> getOverrideInfoUrl(Project.NameKey project) {
    requireNonNull(project, "project");
    return generalConfig.getOverrideInfoUrl(getPluginConfig(project));
  }

  /**
   * Returns the email domains that are allowed to be used for code owners.
   *
   * @return the email domains that are allowed to be used for code owners, an empty set if all
   *     email domains are allowed (if {@code plugin.code-owners.allowedEmailDomain} is not set or
   *     set to an empty value)
   */
  public ImmutableSet<String> getAllowedEmailDomains() {
    return generalConfig.getAllowedEmailDomains();
  }

  /**
   * Whether the code owners functionality is disabled for the given branch.
   *
   * <p>Callers must ensure that the project of the specified branch exists. If the project doesn't
   * exist the call fails with {@link IllegalStateException}.
   *
   * <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 branchNameKey the branch and project 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(BranchNameKey branchNameKey) {
    requireNonNull(branchNameKey, "branchNameKey");

    Config pluginConfig = getPluginConfig(branchNameKey.project());

    boolean isDisabled = statusConfig.isDisabledForBranch(pluginConfig, branchNameKey);
    if (isDisabled) {
      return true;
    }

    return isDisabled(branchNameKey.project());
  }

  /**
   * Whether the code owners functionality is disabled for the given project.
   *
   * <p>Callers must ensure that the project of the specified branch exists. If the project doesn't
   * exist the call fails with {@link IllegalStateException}.
   *
   * <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.
   *
   * @param project the project 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 project,
   *     otherwise {@code false}
   */
  public boolean isDisabled(Project.NameKey project) {
    requireNonNull(project, "project");

    Config pluginConfig = getPluginConfig(project);
    return statusConfig.isDisabledForProject(pluginConfig, project);
  }

  /**
   * Returns the configured {@link CodeOwnerBackend} for the given branch.
   *
   * <p>Callers must ensure that the project of the specified branch exists. If the project doesn't
   * exist the call fails with {@link IllegalStateException}.
   *
   * <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 branchNameKey project and 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(BranchNameKey branchNameKey) {
    Config pluginConfig = getPluginConfig(branchNameKey.project());

    // check if a branch specific backend is configured
    Optional<CodeOwnerBackend> codeOwnerBackend =
        backendConfig.getBackendForBranch(pluginConfig, branchNameKey);
    if (codeOwnerBackend.isPresent()) {
      return codeOwnerBackend.get();
    }

    return getBackend(branchNameKey.project());
  }

  /**
   * Returns the configured {@link CodeOwnerBackend} for the given project.
   *
   * <p>Callers must ensure that the project exists. If the project doesn't exist the call fails
   * with {@link IllegalStateException}.
   *
   * <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.
   *
   * @param project project for which the configured code owner backend should be returned
   * @return the {@link CodeOwnerBackend} that should be used for the project
   */
  public CodeOwnerBackend getBackend(Project.NameKey project) {
    Config pluginConfig = getPluginConfig(project);

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

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

  /**
   * Returns the approval that is required from code owners to approve the files in a change of the
   * given project.
   *
   * <p>Defines which approval counts as code owner approval.
   *
   * <p>Callers must ensure that the project of the specified branch exists. If the project doesn't
   * exist the call fails with {@link IllegalStateException}.
   *
   * <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.
   *
   * @param project project for which the required approval should be returned
   * @return the required code owner approval that should be used for the given project
   */
  public RequiredApproval getRequiredApproval(Project.NameKey project) {
    ImmutableList<RequiredApproval> configuredRequiredApprovalConfig =
        getConfiguredRequiredApproval(requiredApprovalConfig, project);
    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(project).orElseThrow(illegalState(project));
    return requiredApprovalConfig.createDefault(projectState);
  }

  /**
   * Returns the approvals that are required to override the code owners submit check for a change
   * of the given project.
   *
   * <p>If multiple approvals are returned, any of them is sufficient to override the code owners
   * submit check.
   *
   * <p>Callers must ensure that the project of the specified branch exists. If the project doesn't
   * exist the call fails with {@link IllegalStateException}.
   *
   * <p>The override approval configuration is evaluated in the following order:
   *
   * <ul>
   *   <li>override approval configuration for project (with inheritance)
   *   <li>globally configured override approval
   * </ul>
   *
   * <p>The first override approval configuration that exists counts and the evaluation is stopped.
   *
   * @param project project for which the override approval should be returned
   * @return the override approvals that should be used for the given project, an empty set if no
   *     override approval is configured, in this case the override functionality is disabled
   */
  public ImmutableSet<RequiredApproval> getOverrideApproval(Project.NameKey project) {
    try {
      return filterOutDuplicateRequiredApprovals(
          getConfiguredRequiredApproval(overrideApprovalConfig, project));
    } catch (InvalidPluginConfigurationException e) {
      logger.atWarning().withCause(e).log(
          "Ignoring invalid override approval configuration for project %s."
              + " Overrides are disabled.",
          project.get());
    }

    return ImmutableSet.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 ImmutableSet<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 ImmutableSet.copyOf(requiredApprovalsByLabel.values());
  }

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

  /**
   * Checks whether experimental REST endpoints are enabled.
   *
   * @throws MethodNotAllowedException thrown if experimental REST endpoints are disabled
   */
  public void checkExperimentalRestEndpointsEnabled() throws MethodNotAllowedException {
    if (!areExperimentalRestEndpointsEnabled()) {
      throw new MethodNotAllowedException("experimental code owners REST endpoints are disabled");
    }
  }

  /** Whether experimental REST endpoints are enabled. */
  public boolean areExperimentalRestEndpointsEnabled() {
    try {
      return pluginConfigFactory
          .getFromGerritConfig(pluginName)
          .getBoolean(KEY_ENABLE_EXPERIMENTAL_REST_ENDPOINTS, /* defaultValue= */ false);
    } catch (IllegalArgumentException e) {
      logger.atWarning().withCause(e).log(
          "Value '%s' in gerrit.config (parameter plugin.%s.%s) is invalid.",
          pluginConfigFactory
              .getFromGerritConfig(pluginName)
              .getString(KEY_ENABLE_EXPERIMENTAL_REST_ENDPOINTS),
          pluginName,
          KEY_ENABLE_EXPERIMENTAL_REST_ENDPOINTS);
      return false;
    }
  }

  /**
   * Reads and returns the config from the {@code code-owners.config} file in {@code
   * refs/meta/config} branch of the given project.
   *
   * @param project the project for which the code owners configurations should be returned
   * @return the code owners configurations for the given project
   */
  private Config getPluginConfig(Project.NameKey project) {
    try {
      return pluginConfigFactory.getProjectPluginConfigWithInheritance(project, pluginName);
    } catch (NoSuchProjectException e) {
      throw new IllegalStateException(
          String.format(
              "cannot get %s plugin config for non-existing project %s", pluginName, project),
          e);
    }
  }
}
