// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/analysis_options/error/option_codes.dart';
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/registry.dart';
import 'package:analyzer/src/plugin/options.dart';
import 'package:analyzer/src/util/yaml.dart';
import 'package:yaml/yaml.dart';

/// A hint code indicating reference to a deprecated lint.
///
/// Parameters:
/// 0: the rule name
const AnalysisOptionsHintCode DEPRECATED_LINT_HINT = AnalysisOptionsHintCode(
    'DEPRECATED_LINT_HINT',
    "'{0}' is a deprecated lint rule and should not be used");

/// Duplicate rules.
///
/// Parameters:
/// 0: the rule name
const AnalysisOptionsHintCode DUPLICATE_RULE_HINT = AnalysisOptionsHintCode(
    'DUPLICATE_RULE',
    "The rule {0} is already specified and doesn't need to be specified again.",
    correction: "Try removing all but one specification of the rule.");

/// An error code indicating an incompatible rule.
///
/// Parameters:
/// 0: the rule name
/// 1: the incompatible rule
const AnalysisOptionsWarningCode INCOMPATIBLE_LINT_WARNING =
    AnalysisOptionsWarningCode('INCOMPATIBLE_LINT_WARNING',
        "The rule '{0}' is incompatible with the rule '{1}'",
        correction: "Try removing one of the incompatible rules.");

/// An error code indicating an undefined lint rule.
///
/// Parameters:
/// 0: the rule name
const AnalysisOptionsWarningCode UNDEFINED_LINT_WARNING =
    AnalysisOptionsWarningCode(
        'UNDEFINED_LINT_WARNING', "'{0}' is not a recognized lint rule");

/// Rule provider.
typedef LintRuleProvider = Iterable<LintRule> Function();

/// Validates `linter` rule configurations.
class LinterRuleOptionsValidator extends OptionsValidator {
  static const linter = 'linter';
  static const rulesKey = 'rules';

  final LintRuleProvider ruleProvider;

  LinterRuleOptionsValidator({LintRuleProvider provider})
      : ruleProvider = provider ?? (() => Registry.ruleRegistry.rules);

  LintRule getRegisteredLint(Object value) => ruleProvider()
      .firstWhere((rule) => rule.name == value, orElse: () => null);

  @override
  List<AnalysisError> validate(ErrorReporter reporter, YamlMap options) {
    List<AnalysisError> errors = <AnalysisError>[];
    var node = getValue(options, linter);
    if (node is YamlMap) {
      var rules = getValue(node, rulesKey);
      validateRules(rules, reporter);
    }
    return errors;
  }

  void validateRules(YamlNode rules, ErrorReporter reporter) {
    if (rules is YamlList) {
      final seenRules = <String>{};

      String findIncompatibleRule(LintRule rule) {
        for (var incompatibleRule in rule.incompatibleRules) {
          if (seenRules.contains(incompatibleRule)) {
            return incompatibleRule;
          }
        }
        return null;
      }

      for (var ruleNode in rules.nodes) {
        final value = ruleNode.value;
        if (value != null) {
          final rule = getRegisteredLint(value);
          if (rule == null) {
            reporter.reportErrorForSpan(
                UNDEFINED_LINT_WARNING, ruleNode.span, [value]);
            continue;
          }

          final incompatibleRule = findIncompatibleRule(rule);
          if (incompatibleRule != null) {
            reporter.reportErrorForSpan(INCOMPATIBLE_LINT_WARNING,
                ruleNode.span, [value, incompatibleRule]);
          } else if (!seenRules.add(rule.name)) {
            reporter.reportErrorForSpan(
                DUPLICATE_RULE_HINT, ruleNode.span, [value]);
          } else if (rule.maturity == Maturity.deprecated) {
            reporter.reportErrorForSpan(
                DEPRECATED_LINT_HINT, ruleNode.span, [value]);
          }
        }
      }
    }
  }
}
