// Copyright (c) 2015, 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/diagnostic/diagnostic.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/analysis_options/analysis_options_file.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:collection/collection.dart';
import 'package:meta/meta.dart';
import 'package:yaml/yaml.dart';

/// String identifiers mapped to associated severities.
const Map<String, DiagnosticSeverity> severityMap = {
  'error': DiagnosticSeverity.ERROR,
  'info': DiagnosticSeverity.INFO,
  'warning': DiagnosticSeverity.WARNING,
};

/// Error processor configuration derived from analysis (or embedder) options.
class ErrorConfig {
  /// The processors in this config.
  final List<ErrorProcessor> processors = <ErrorProcessor>[];

  /// Create an error config for the given error code map.
  /// For example:
  ///     new ErrorConfig({'missing_return' : 'error'});
  /// will create a processor config that turns `missing_return` warnings into
  /// errors.
  ErrorConfig(YamlNode? codeMap) {
    if (codeMap is YamlMap) {
      _processMap(codeMap);
    }
  }

  void _processMap(YamlMap codes) {
    codes.nodes.forEach((k, v) {
      if (k is YamlScalar && v is YamlScalar) {
        var code = k.value;
        if (code is! String) return;

        code = code.toUpperCase();
        var action = v.value.toString().toLowerCase();
        if (AnalysisOptionsFile.ignoreSynonyms.contains(action)) {
          processors.add(ErrorProcessor.ignore(code));
        } else {
          var severity = severityMap[action];
          if (severity != null) {
            processors.add(ErrorProcessor(code, severity));
          }
        }
      }
    });
  }
}

/// Process errors by filtering or changing associated [DiagnosticSeverity].
class ErrorProcessor {
  /// The code name of the associated error.
  final String code;

  /// The desired severity of the processed error.
  ///
  /// If `null`, this processor will "filter" the associated error code.
  final DiagnosticSeverity? severity;

  /// Create an error processor that assigns errors with this [code] the
  /// given [severity].
  ///
  /// If [severity] is `null`, matching errors will be filtered.
  ErrorProcessor(String code, [this.severity]) : code = code.toLowerCase();

  /// Create an error processor that ignores the given error by [code].
  factory ErrorProcessor.ignore(String code) => ErrorProcessor(code);

  /// The string that unique describes the processor.
  String get description => '$code -> ${severity?.name}';

  /// Check if this processor applies to the given [diagnostic].
  @visibleForTesting
  bool appliesTo(Diagnostic diagnostic) =>
      code == diagnostic.diagnosticCode.lowerCaseName;

  @override
  String toString() => "ErrorProcessor[code='$code', severity=$severity]";

  /// Returns an error processor associated in the [analysisOptions] for the
  /// given [diagnostic], or `null` if none is found.
  static ErrorProcessor? getProcessor(
    // TODO(srawlins): Make `analysisOptions` non-nullable, in a breaking
    // change release.
    AnalysisOptions? analysisOptions,
    Diagnostic diagnostic,
  ) {
    return analysisOptions?.errorProcessors.firstWhereOrNull(
      (processor) => processor.appliesTo(diagnostic),
    );
  }
}
