// Copyright (C) 2018 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.googlesource.gerrit.plugins.simplesubmitrules.config;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.LabelFunction;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.server.config.PluginConfig;
import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectConfig;
import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.simplesubmitrules.SimpleSubmitRulesConfig;
import com.googlesource.gerrit.plugins.simplesubmitrules.api.CommentsRules;
import com.googlesource.gerrit.plugins.simplesubmitrules.api.LabelDefinition;
import com.googlesource.gerrit.plugins.simplesubmitrules.api.SubmitConfig;
import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/** Codec class used to convert {@link SubmitConfig} from/to a Gerrit config */
@Singleton
public final class ConfigTranslator {
  private final ProjectCache projectCache;
  private final PluginConfigFactory pluginConfigFactory;
  private final String pluginName;

  @Inject
  public ConfigTranslator(
      ProjectCache projectCache,
      PluginConfigFactory pluginConfigFactory,
      @PluginName String pluginName) {
    this.projectCache = projectCache;
    this.pluginConfigFactory = pluginConfigFactory;
    this.pluginName = pluginName;
  }

  static void extractLabelCopyScoreRules(LabelType labelType, LabelDefinition labelDefinition) {
    labelDefinition.copyScoreRules = new HashSet<>();
    if (labelType.isCopyMinScore()) {
      labelDefinition.copyScoreRules.add(ProjectConfig.KEY_COPY_MIN_SCORE);
    }
    if (labelType.isCopyMaxScore()) {
      labelDefinition.copyScoreRules.add(ProjectConfig.KEY_COPY_MAX_SCORE);
    }
    if (labelType.isCopyAllScoresIfNoChange()) {
      labelDefinition.copyScoreRules.add(ProjectConfig.KEY_COPY_ALL_SCORES_IF_NO_CHANGE);
    }
    if (labelType.isCopyAllScoresIfNoCodeChange()) {
      labelDefinition.copyScoreRules.add(ProjectConfig.KEY_COPY_ALL_SCORES_IF_NO_CODE_CHANGE);
    }
    if (labelType.isCopyAllScoresOnMergeFirstParentUpdate()) {
      labelDefinition.copyScoreRules.add(
          ProjectConfig.KEY_COPY_ALL_SCORES_ON_MERGE_FIRST_PARENT_UPDATE);
    }
    if (labelType.isCopyAllScoresOnTrivialRebase()) {
      labelDefinition.copyScoreRules.add(ProjectConfig.KEY_COPY_ALL_SCORES_ON_TRIVIAL_REBASE);
    }
  }

  static void applyCopyScoreRulesTo(
      Set<String> copyScoreRules, Set<String> disallowedCopyScoreRules, LabelType labelType)
      throws BadRequestException {
    Set<String> disallowed =
        Sets.intersection(ImmutableSet.copyOf(copyScoreRules), disallowedCopyScoreRules);
    if (!disallowed.isEmpty()) {
      throw new BadRequestException("copy score rules " + disallowed + " are forbidden");
    }

    labelType.setCopyMinScore(copyScoreRules.contains(ProjectConfig.KEY_COPY_MIN_SCORE));
    labelType.setCopyMaxScore(copyScoreRules.contains(ProjectConfig.KEY_COPY_MAX_SCORE));
    labelType.setCopyAllScoresIfNoChange(
        copyScoreRules.contains(ProjectConfig.KEY_COPY_ALL_SCORES_IF_NO_CHANGE));
    labelType.setCopyAllScoresIfNoCodeChange(
        copyScoreRules.contains(ProjectConfig.KEY_COPY_ALL_SCORES_IF_NO_CODE_CHANGE));
    labelType.setCopyAllScoresOnMergeFirstParentUpdate(
        copyScoreRules.contains(ProjectConfig.KEY_COPY_ALL_SCORES_ON_MERGE_FIRST_PARENT_UPDATE));
    labelType.setCopyAllScoresOnTrivialRebase(
        copyScoreRules.contains(ProjectConfig.KEY_COPY_ALL_SCORES_ON_TRIVIAL_REBASE));
  }

  SubmitConfig convertFrom(ProjectState projectState) {
    SubmitConfig submitConfig = new SubmitConfig();
    PluginConfig config =
        pluginConfigFactory.getFromProjectConfigWithInheritance(projectState, pluginName);

    submitConfig.comments =
        new CommentsRules(
            config.getBoolean(SimpleSubmitRulesConfig.KEY_BLOCK_IF_UNRESOLVED_COMMENTS, false));

    projectState
        .getLabelTypes()
        .getLabelTypes()
        .forEach(
            labelType -> {
              extractLabelSettings(labelType, submitConfig);
            });

    return submitConfig;
  }

  void applyTo(SubmitConfig inConfig, ProjectConfig projectConfig)
      throws BadRequestException, IOException {
    PluginConfig hostPluginConfig = pluginConfigFactory.getFromGerritConfig(pluginName);
    PluginConfig projectPluginConfig = projectConfig.getPluginConfig(pluginName);

    applyCommentRulesTo(inConfig.comments, projectPluginConfig);
    applyLabelsTo(inConfig.labels, projectConfig, hostPluginConfig);
  }

  private void applyLabelsTo(
      Map<String, LabelDefinition> labels,
      ProjectConfig projectConfig,
      PluginConfig hostPluginConfig)
      throws BadRequestException, IOException {
    if (labels.isEmpty()) {
      return;
    }

    for (Map.Entry<String, LabelDefinition> entry : labels.entrySet()) {
      if (!projectConfig.getLabelSections().containsKey(entry.getKey())) {
        // The current project does not have this label. Try to copy it down from the inherited
        // labels to be able to modify it locally.
        Map<String, LabelType> copiedLabelTypes = projectConfig.getLabelSections();
        ProjectState projectState = projectCache.checkedGet(projectConfig.getName());
        projectState
            .getLabelTypes()
            .getLabelTypes()
            .stream()
            .filter(l -> l.getName().equals(entry.getKey()))
            .filter(l -> l.canOverride())
            .forEach(l -> copiedLabelTypes.put(l.getName(), copyLabelType(l)));
      }

      String label = entry.getKey();
      LabelDefinition definition = entry.getValue();
      LabelType labelType = projectConfig.getLabelSections().get(label);

      if (labelType == null) {
        throw new BadRequestException(
            "The label " + label + " does not exist. You can't change its config.");
      }

      if (definition.ignoreSelfApproval != null) {
        labelType.setIgnoreSelfApproval(definition.ignoreSelfApproval);
      }

      if (definition.getFunction().isPresent()) {
        Set<String> disallowedLabelFunctions =
            ImmutableSet.copyOf(
                hostPluginConfig.getStringList("disallowedLabelFunctions-" + label));
        LabelFunction function = definition.getFunction().get();
        if (disallowedLabelFunctions.contains(function.getFunctionName())) {
          throw new BadRequestException(function.getFunctionName() + " disallowed");
        }
        labelType.setFunction(function);
      }

      if (definition.copyScoreRules != null) {
        Set<String> disallowedCopyScoreRules =
            ImmutableSet.copyOf(
                hostPluginConfig.getStringList("disallowedCopyScoreRules-" + label));
        applyCopyScoreRulesTo(definition.copyScoreRules, disallowedCopyScoreRules, labelType);
      }
    }
  }

  private static void extractLabelSettings(LabelType labelType, SubmitConfig config) {
    if (labelType == null) {
      return;
    }

    LabelDefinition labelDefinition = new LabelDefinition();
    config.labels.put(labelType.getName(), labelDefinition);

    labelDefinition.function = labelType.getFunction().getFunctionName();
    extractLabelCopyScoreRules(labelType, labelDefinition);
    labelDefinition.ignoreSelfApproval = labelType.ignoreSelfApproval();
  }

  private static void applyCommentRulesTo(@Nullable CommentsRules comments, PluginConfig config) {
    if (comments == null) {
      return;
    }
    config.setBoolean(
        SimpleSubmitRulesConfig.KEY_BLOCK_IF_UNRESOLVED_COMMENTS,
        comments.blockIfUnresolvedComments);
  }

  private static LabelType copyLabelType(LabelType label) {
    // TODO(hiesel) Move this to core
    LabelType copy = new LabelType(label.getName(), ImmutableList.copyOf(label.getValues()));
    if (label.getRefPatterns() != null) {
      copy.setRefPatterns(ImmutableList.copyOf(label.getRefPatterns()));
    }
    copy.setAllowPostSubmit(label.allowPostSubmit());
    copy.setCanOverride(label.canOverride());
    copy.setCopyAllScoresIfNoChange(label.isCopyAllScoresIfNoChange());
    copy.setCopyAllScoresIfNoCodeChange(label.isCopyAllScoresIfNoCodeChange());
    copy.setCopyAllScoresOnMergeFirstParentUpdate(label.isCopyAllScoresOnMergeFirstParentUpdate());
    copy.setCopyAllScoresOnTrivialRebase(label.isCopyAllScoresOnTrivialRebase());
    copy.setIgnoreSelfApproval(label.ignoreSelfApproval());
    copy.setCopyMaxScore(label.isCopyMaxScore());
    copy.setCopyMinScore(label.isCopyMinScore());
    copy.setFunction(label.getFunction());
    return copy;
  }
}
