// 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.plugins.codeowners.config.CodeOwnersPluginConfiguration.SECTION_CODE_OWNERS;
import static java.util.Objects.requireNonNull;

import com.google.common.collect.ImmutableList;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.gerrit.server.git.validators.CommitValidationMessage;
import com.google.gerrit.server.git.validators.ValidationMessage;
import com.google.gerrit.server.project.ProjectLevelConfig;
import com.google.gerrit.server.project.ProjectState;
import org.eclipse.jgit.lib.Config;

/**
 * Base class to read the required approval configuration from {@code gerrit.config} and from {@code
 * code-owners.config} in {@code refs/meta/config}.
 *
 * <p>The default required approval is configured in {@code gerrit.config}.
 *
 * <p>On project-level the required approval is configured in {@code code-owners.config}.
 *
 * <p>Projects that have no required approval configuration inherit the configuration from their
 * parent projects.
 */
abstract class AbstractRequiredApprovalConfig {
  protected final String pluginName;

  private final PluginConfigFactory pluginConfigFactory;

  AbstractRequiredApprovalConfig(
      @PluginName String pluginName, PluginConfigFactory pluginConfigFactory) {
    this.pluginName = pluginName;
    this.pluginConfigFactory = pluginConfigFactory;
  }

  protected abstract String getConfigKey();

  /**
   * Reads the required approvals for the specified project from the given plugin config with
   * fallback to {@code gerrit.config}.
   *
   * @param projectState state of the project for which the required approvals should be read
   * @param pluginConfig the plugin config from which the required approvals should be read
   * @return the required approvals, an empty list if none was configured
   */
  ImmutableList<RequiredApproval> get(ProjectState projectState, Config pluginConfig) {
    requireNonNull(projectState, "projectState");
    requireNonNull(pluginConfig, "pluginConfig");

    ImmutableList.Builder<RequiredApproval> requiredApprovalList = ImmutableList.builder();
    String[] requiredApprovals =
        pluginConfig.getStringList(SECTION_CODE_OWNERS, /* subsection= */ null, getConfigKey());
    if (requiredApprovals.length > 0) {
      for (String requiredApproval : requiredApprovals) {
        try {
          requiredApprovalList.add(RequiredApproval.parse(projectState, requiredApproval));
        } catch (IllegalStateException | IllegalArgumentException e) {
          throw new InvalidPluginConfigurationException(
              pluginName,
              String.format(
                  "Required approval '%s' that is configured in %s.config"
                      + " (parameter %s.%s) is invalid: %s",
                  requiredApproval,
                  pluginName,
                  SECTION_CODE_OWNERS,
                  getConfigKey(),
                  e.getMessage()));
        }
      }
      return requiredApprovalList.build();
    }

    requiredApprovals =
        pluginConfigFactory.getFromGerritConfig(pluginName).getStringList(getConfigKey());
    if (requiredApprovals.length > 0) {
      for (String requiredApproval : requiredApprovals) {
        try {
          requiredApprovalList.add(RequiredApproval.parse(projectState, requiredApproval));
        } catch (IllegalStateException | IllegalArgumentException e) {
          throw new InvalidPluginConfigurationException(
              pluginName,
              String.format(
                  "Required approval '%s' that is configured in gerrit.config"
                      + " (parameter plugin.%s.%s) is invalid: %s",
                  requiredApproval, pluginName, getConfigKey(), e.getMessage()));
        }
      }
      return requiredApprovalList.build();
    }

    return ImmutableList.of();
  }

  /**
   * Validates the required approval configuration in the given project level configuration.
   *
   * @param fileName the name of the config file
   * @param projectLevelConfig the project level plugin configuration
   * @return list of validation messages for validation errors, empty list if there are no
   *     validation errors
   */
  ImmutableList<CommitValidationMessage> validateProjectLevelConfig(
      ProjectState projectState, String fileName, ProjectLevelConfig.Bare projectLevelConfig) {
    requireNonNull(projectState, "projectState");
    requireNonNull(fileName, "fileName");
    requireNonNull(projectLevelConfig, "projectLevelConfig");

    String[] requiredApprovals =
        projectLevelConfig
            .getConfig()
            .getStringList(SECTION_CODE_OWNERS, /* subsection= */ null, getConfigKey());
    ImmutableList.Builder<CommitValidationMessage> validationMessages = ImmutableList.builder();
    for (String requiredApproval : requiredApprovals) {
      try {
        RequiredApproval.parse(projectState, requiredApproval);
      } catch (IllegalArgumentException | IllegalStateException e) {
        validationMessages.add(
            new CommitValidationMessage(
                String.format(
                    "Required approval '%s' that is configured in %s (parameter %s.%s) is invalid: %s",
                    requiredApproval,
                    fileName,
                    SECTION_CODE_OWNERS,
                    getConfigKey(),
                    e.getMessage()),
                ValidationMessage.Type.ERROR));
      }
    }
    return validationMessages.build();
  }
}
