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

library analyzer.source.error_processor;

import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:yaml/yaml.dart';

/// String identifiers mapped to associated severities.
const Map<String, ErrorSeverity> severityMap = const {
  'error': ErrorSeverity.ERROR,
  'info': ErrorSeverity.INFO,
  'warning': ErrorSeverity.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` hints into
  /// errors.
  ErrorConfig(Object codeMap) {
    _processMap(codeMap);
  }

  void _process(String code, Object action) {
    action = toLowerCase(action);
    code = toUpperCase(code);
    if (AnalyzerOptions.ignoreSynonyms.contains(action)) {
      processors.add(new ErrorProcessor.ignore(code));
    } else {
      ErrorSeverity severity = _toSeverity(action);
      if (severity != null) {
        processors.add(new ErrorProcessor(code, severity));
      }
    }
  }

  void _processMap(Object codes) {
    if (codes is YamlMap) {
      // TODO(pq): stop traversing nodes and unify w/ standard map handling
      codes.nodes.forEach((k, v) {
        if (k is YamlScalar && v is YamlScalar) {
          _process(k.value, v.value);
        }
      });
    } else if (codes is Map) {
      codes.forEach((k, v) {
        if (k is String) {
          _process(k, v);
        }
      });
    }
  }

  ErrorSeverity _toSeverity(String severity) => severityMap[severity];
}

/// Process errors by filtering or changing associated [ErrorSeverity].
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 ErrorSeverity severity;

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

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

  /// Check if this processor applies to the given [error].
  bool appliesTo(AnalysisError error) => code == error.errorCode.name;

  /// Return an error processor associated with this [context] for the given
  /// [error], or `null` if none is found.
  static ErrorProcessor getProcessor(
      AnalysisContext context, AnalysisError error) {
    if (context == null) {
      return null;
    }

    // Let the user configure how specific errors are processed.
    List<ErrorProcessor> processors =
        context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);

    // Give strong mode a chance to upgrade it.
    if (context.analysisOptions.strongMode) {
      processors = processors.toList();
      processors.add(_StrongModeTypeErrorProcessor.instance);
    }
    return processors.firstWhere((ErrorProcessor p) => p.appliesTo(error),
        orElse: () => null);
  }
}

/// In strong mode, this upgrades static type warnings to errors.
class _StrongModeTypeErrorProcessor implements ErrorProcessor {
  static final instance = new _StrongModeTypeErrorProcessor();

  // TODO(rnystrom): As far as I know, this is only used to implement
  // appliesTo(). Consider making it private in ErrorProcessor if possible.
  String get code => throw new UnsupportedError(
      "_StrongModeTypeErrorProcessor is not specific to an error code.");

  /// In strong mode, type warnings are upgraded to errors.
  ErrorSeverity get severity => ErrorSeverity.ERROR;

  /// Check if this processor applies to the given [error].
  bool appliesTo(AnalysisError error) =>
      error.errorCode.type == ErrorType.STATIC_TYPE_WARNING;
}
