// Copyright (c) 2014, 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.error.listener;

import 'dart:collection';

import 'package:analyzer/dart/ast/ast.dart' show AstNode;
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:source_span/source_span.dart';

/**
 * An object that listen for [AnalysisError]s being produced by the analysis
 * engine.
 */
abstract class AnalysisErrorListener {
  /**
   * An error listener that ignores errors that are reported to it.
   */
  static final AnalysisErrorListener NULL_LISTENER = new _NullErrorListener();

  /**
   * This method is invoked when an [error] has been found by the analysis
   * engine.
   */
  void onError(AnalysisError error);
}

/**
 * An [AnalysisErrorListener] that keeps track of whether any error has been
 * reported to it.
 */
class BooleanErrorListener implements AnalysisErrorListener {
  /**
   * A flag indicating whether an error has been reported to this listener.
   */
  bool _errorReported = false;

  /**
   * Return `true` if an error has been reported to this listener.
   */
  bool get errorReported => _errorReported;

  @override
  void onError(AnalysisError error) {
    _errorReported = true;
  }
}

/**
 * An object used to create analysis errors and report then to an error
 * listener.
 */
class ErrorReporter {
  /**
   * The error listener to which errors will be reported.
   */
  final AnalysisErrorListener _errorListener;

  /**
   * The default source to be used when reporting errors.
   */
  final Source _defaultSource;

  /**
   * The source to be used when reporting errors.
   */
  Source _source;

  /**
   * Initialize a newly created error reporter that will report errors to the
   * given [_errorListener]. Errors will be reported against the
   * [_defaultSource] unless another source is provided later.
   */
  ErrorReporter(this._errorListener, this._defaultSource) {
    if (_errorListener == null) {
      throw new ArgumentError("An error listener must be provided");
    } else if (_defaultSource == null) {
      throw new ArgumentError("A default source must be provided");
    }
    this._source = _defaultSource;
  }

  Source get source => _source;

  /**
   * Set the source to be used when reporting errors to the given [source].
   * Setting the source to `null` will cause the default source to be used.
   */
  void set source(Source source) {
    this._source = source ?? _defaultSource;
  }

  /**
   * Creates an error with properties with the given [errorCode] and
   * [arguments]. The [node] is used to compute the location of the error.
   */
  AnalysisErrorWithProperties newErrorWithProperties(
          ErrorCode errorCode, AstNode node, List<Object> arguments) =>
      new AnalysisErrorWithProperties(
          _source, node.offset, node.length, errorCode, arguments);

  /**
   * Report the given [error].
   */
  void reportError(AnalysisError error) {
    _errorListener.onError(error);
  }

  /**
   * Report an error with the given [errorCode] and [arguments]. The [element]
   * is used to compute the location of the error.
   */
  void reportErrorForElement(ErrorCode errorCode, Element element,
      [List<Object> arguments]) {
    int length = 0;
    if (element is ImportElement) {
      length = 6; // 'import'.length
    } else if (element is ExportElement) {
      length = 6; // 'export'.length
    } else {
      length = element.nameLength;
    }
    reportErrorForOffset(errorCode, element.nameOffset, length, arguments);
  }

  /**
   * Report an error with the given [errorCode] and [arguments].
   * The [node] is used to compute the location of the error.
   *
   * If the arguments contain the names of two or more types, the method
   * [reportTypeErrorForNode] should be used and the types
   * themselves (rather than their names) should be passed as arguments.
   */
  void reportErrorForNode(ErrorCode errorCode, AstNode node,
      [List<Object> arguments]) {
    reportErrorForOffset(errorCode, node.offset, node.length, arguments);
  }

  /**
   * Report an error with the given [errorCode] and [arguments]. The location of
   * the error is specified by the given [offset] and [length].
   */
  void reportErrorForOffset(ErrorCode errorCode, int offset, int length,
      [List<Object> arguments]) {
    _errorListener.onError(
        new AnalysisError(_source, offset, length, errorCode, arguments));
  }

  /**
   * Report an error with the given [errorCode] and [arguments]. The location of
   * the error is specified by the given [span].
   */
  void reportErrorForSpan(ErrorCode errorCode, SourceSpan span,
      [List<Object> arguments]) {
    reportErrorForOffset(errorCode, span.start.offset, span.length, arguments);
  }

  /**
   * Report an error with the given [errorCode] and [arguments]. The [token] is
   * used to compute the location of the error.
   */
  void reportErrorForToken(ErrorCode errorCode, Token token,
      [List<Object> arguments]) {
    reportErrorForOffset(errorCode, token.offset, token.length, arguments);
  }

  /**
   * Report an error with the given [errorCode] and [arguments]. The [node] is
   * used to compute the location of the error. The arguments are expected to
   * contain two or more types. Convert the types into strings by using the
   * display names of the types, unless there are two or more types with the
   * same names, in which case the extended display names of the types will be
   * used in order to clarify the message.
   *
   * If there are not two or more types in the argument list, the method
   * [reportErrorForNode] should be used instead.
   */
  void reportTypeErrorForNode(
      ErrorCode errorCode, AstNode node, List<Object> arguments) {
    _convertTypeNames(arguments);
    reportErrorForOffset(errorCode, node.offset, node.length, arguments);
  }

  /**
   * Given an array of [arguments] that is expected to contain two or more
   * types, convert the types into strings by using the display names of the
   * types, unless there are two or more types with the same names, in which
   * case the extended display names of the types will be used in order to
   * clarify the message.
   */
  void _convertTypeNames(List<Object> arguments) {
    String displayName(DartType type) {
      if (type is FunctionType) {
        String name = type.name;
        if (name != null && name.length > 0) {
          StringBuffer buffer = new StringBuffer();
          buffer.write(name);
          (type as TypeImpl).appendTo(buffer);
          return buffer.toString();
        }
      }
      return type.displayName;
    }

    if (_hasEqualTypeNames(arguments)) {
      int count = arguments.length;
      for (int i = 0; i < count; i++) {
        Object argument = arguments[i];
        if (argument is DartType) {
          Element element = argument.element;
          if (element == null) {
            arguments[i] = displayName(argument);
          } else {
            arguments[i] =
                element.getExtendedDisplayName(displayName(argument));
          }
        }
      }
    } else {
      int count = arguments.length;
      for (int i = 0; i < count; i++) {
        Object argument = arguments[i];
        if (argument is DartType) {
          arguments[i] = displayName(argument);
        }
      }
    }
  }

  /**
   * Return `true` if the given array of [arguments] contains two or more types
   * with the same display name.
   */
  bool _hasEqualTypeNames(List<Object> arguments) {
    int count = arguments.length;
    HashSet<String> typeNames = new HashSet<String>();
    for (int i = 0; i < count; i++) {
      Object argument = arguments[i];
      if (argument is DartType && !typeNames.add(argument.displayName)) {
        return true;
      }
    }
    return false;
  }
}

/**
 * An error listener that will record the errors that are reported to it in a
 * way that is appropriate for caching those errors within an analysis context.
 */
class RecordingErrorListener implements AnalysisErrorListener {
  /**
   * A map of sets containing the errors that were collected, keyed by each
   * source.
   */
  Map<Source, HashSet<AnalysisError>> _errors =
      new HashMap<Source, HashSet<AnalysisError>>();

  /**
   * Return the errors collected by the listener.
   */
  List<AnalysisError> get errors {
    int numEntries = _errors.length;
    if (numEntries == 0) {
      return AnalysisError.NO_ERRORS;
    }
    List<AnalysisError> resultList = new List<AnalysisError>();
    for (HashSet<AnalysisError> errors in _errors.values) {
      resultList.addAll(errors);
    }
    return resultList;
  }

  /**
   * Add all of the errors recorded by the given [listener] to this listener.
   */
  void addAll(RecordingErrorListener listener) {
    for (AnalysisError error in listener.errors) {
      onError(error);
    }
  }

  /**
   * Return the errors collected by the listener for the given [source].
   */
  List<AnalysisError> getErrorsForSource(Source source) {
    HashSet<AnalysisError> errorsForSource = _errors[source];
    if (errorsForSource == null) {
      return AnalysisError.NO_ERRORS;
    } else {
      return new List.from(errorsForSource);
    }
  }

  @override
  void onError(AnalysisError error) {
    Source source = error.source;
    HashSet<AnalysisError> errorsForSource = _errors[source];
    if (_errors[source] == null) {
      errorsForSource = new HashSet<AnalysisError>();
      _errors[source] = errorsForSource;
    }
    errorsForSource.add(error);
  }
}

/**
 * An [AnalysisErrorListener] that ignores error.
 */
class _NullErrorListener implements AnalysisErrorListener {
  @override
  void onError(AnalysisError event) {
    // Ignore errors
  }
}
