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

import 'package:analyzer/dart/ast/ast.dart' show AstNode, SimpleIdentifier;
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
import 'package:test/test.dart';

import 'analysis_context_factory.dart';

/**
 * The class `EngineTestCase` defines utility methods for making assertions.
 */
class EngineTestCase {
  /**
   * Flag indicating whether the fasta parser is being used.
   */
  bool get usingFastaParser => Parser.useFasta;

  /**
   * Assert that the given collection has the same number of elements as the number of specified
   * names, and that for each specified name, a corresponding element can be found in the given
   * collection with that name.
   *
   * @param elements the elements
   * @param names the names
   */
  void assertNamedElements(List<Element> elements, List<String> names) {
    for (String elemName in names) {
      bool found = false;
      for (Element elem in elements) {
        if (elem.name == elemName) {
          found = true;
          break;
        }
      }
      if (!found) {
        StringBuffer buffer = new StringBuffer();
        buffer.write("Expected element named: ");
        buffer.write(elemName);
        buffer.write("\n  but found: ");
        for (Element elem in elements) {
          buffer.write(elem.name);
          buffer.write(", ");
        }
        fail(buffer.toString());
      }
    }
    expect(elements, hasLength(names.length));
  }

  AnalysisContext createAnalysisContext() {
    return AnalysisContextFactory.contextWithCore(
        resourceProvider: new MemoryResourceProvider());
  }

  /**
   * Return the getter in the given type with the given name. Inherited getters are ignored.
   *
   * @param type the type in which the getter is declared
   * @param getterName the name of the getter to be returned
   * @return the property accessor element representing the getter with the given name
   */
  PropertyAccessorElement getGetter(InterfaceType type, String getterName) {
    for (PropertyAccessorElement accessor in type.element.accessors) {
      if (accessor.isGetter && accessor.name == getterName) {
        return accessor;
      }
    }
    fail("Could not find getter named $getterName in ${type.displayName}");
  }

  /**
   * Return the method in the given type with the given name. Inherited methods are ignored.
   *
   * @param type the type in which the method is declared
   * @param methodName the name of the method to be returned
   * @return the method element representing the method with the given name
   */
  MethodElement getMethod(InterfaceType type, String methodName) {
    for (MethodElement method in type.element.methods) {
      if (method.name == methodName) {
        return method;
      }
    }
    fail("Could not find method named $methodName in ${type.displayName}");
  }

  void setUp() {
    List<Plugin> plugins = <Plugin>[];
    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
    new ExtensionManager().processPlugins(plugins);
  }

  void tearDown() {}

  /**
   * @return the [AstNode] with requested type at offset of the "prefix".
   */
  static AstNode findNode(
      AstNode root, String code, String prefix, Predicate<AstNode> predicate) {
    int offset = code.indexOf(prefix);
    if (offset == -1) {
      throw new ArgumentError("Not found '$prefix'.");
    }
    AstNode node = new NodeLocator(offset).searchWithin(root);
    return node.thisOrAncestorMatching(predicate);
  }

  /**
   * Find the [SimpleIdentifier] with at offset of the "prefix".
   */
  static SimpleIdentifier findSimpleIdentifier(
      AstNode root, String code, String prefix) {
    int offset = code.indexOf(prefix);
    if (offset == -1) {
      throw new ArgumentError("Not found '$prefix'.");
    }
    return new NodeLocator(offset).searchWithin(root);
  }
}

/**
 * A description of an error that is expected to be reported.
 */
class ExpectedError {
  /**
   * An empty array of error descriptors used when no errors are expected.
   */
  static List<ExpectedError> NO_ERRORS = <ExpectedError>[];

  /**
   * The error code associated with the error.
   */
  final ErrorCode code;

  /**
   * The offset of the beginning of the error's region.
   */
  final int offset;

  /**
   * The offset of the beginning of the error's region.
   */
  final int length;

  /**
   * Initialize a newly created error description.
   */
  ExpectedError(this.code, this.offset, this.length);
}

/**
 * An error listener that collects all of the errors passed to it for later
 * examination.
 */
class GatheringErrorListener implements AnalysisErrorListener {
  /**
   * A flag indicating whether error ranges are to be compared when comparing
   * expected and actual errors.
   */
  final bool checkRanges;

  /**
   * A list containing the errors that were collected.
   */
  List<AnalysisError> _errors = <AnalysisError>[];

  /**
   * A table mapping sources to the line information for the source.
   */
  Map<Source, LineInfo> _lineInfoMap = <Source, LineInfo>{};

  /**
   * Initialize a newly created error listener to collect errors.
   */
  GatheringErrorListener({this.checkRanges = Parser.useFasta});

  /**
   * Return the errors that were collected.
   */
  List<AnalysisError> get errors => _errors;

  /**
   * Return `true` if at least one error has been gathered.
   */
  bool get hasErrors => _errors.length > 0;

  /**
   * Add the given [errors] to this listener.
   */
  void addAll(List<AnalysisError> errors) {
    for (AnalysisError error in errors) {
      onError(error);
    }
  }

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

  /**
   * Assert that the number of errors that have been gathered matches the number
   * of [expectedErrors] and that they have the expected error codes and
   * locations. The order in which the errors were gathered is ignored.
   */
  void assertErrors(List<ExpectedError> expectedErrors) {
    if (_errors.length != expectedErrors.length) {
      _fail(expectedErrors);
    }
    List<ExpectedError> remainingErrors = expectedErrors.toList();
    for (AnalysisError error in _errors) {
      if (!_foundAndRemoved(remainingErrors, error)) {
        _fail(expectedErrors);
      }
    }
  }

  /**
   * Assert that the number of errors that have been gathered matches the number
   * of [expectedErrorCodes] and that they have the expected error codes. The
   * order in which the errors were gathered is ignored.
   */
  void assertErrorsWithCodes(
      [List<ErrorCode> expectedErrorCodes = const <ErrorCode>[]]) {
    StringBuffer buffer = new StringBuffer();
    //
    // Compute the expected number of each type of error.
    //
    Map<ErrorCode, int> expectedCounts = <ErrorCode, int>{};
    for (ErrorCode code in expectedErrorCodes) {
      int count = expectedCounts[code];
      if (count == null) {
        count = 1;
      } else {
        count = count + 1;
      }
      expectedCounts[code] = count;
    }
    //
    // Compute the actual number of each type of error.
    //
    Map<ErrorCode, List<AnalysisError>> errorsByCode =
        <ErrorCode, List<AnalysisError>>{};
    for (AnalysisError error in _errors) {
      errorsByCode
          .putIfAbsent(error.errorCode, () => <AnalysisError>[])
          .add(error);
    }
    //
    // Compare the expected and actual number of each type of error.
    //
    expectedCounts.forEach((ErrorCode code, int expectedCount) {
      int actualCount;
      List<AnalysisError> list = errorsByCode.remove(code);
      if (list == null) {
        actualCount = 0;
      } else {
        actualCount = list.length;
      }
      if (actualCount != expectedCount) {
        if (buffer.length == 0) {
          buffer.write("Expected ");
        } else {
          buffer.write("; ");
        }
        buffer.write(expectedCount);
        buffer.write(" errors of type ");
        buffer.write(code.uniqueName);
        buffer.write(", found ");
        buffer.write(actualCount);
      }
    });
    //
    // Check that there are no more errors in the actual-errors map,
    // otherwise record message.
    //
    errorsByCode.forEach((ErrorCode code, List<AnalysisError> actualErrors) {
      int actualCount = actualErrors.length;
      if (buffer.length == 0) {
        buffer.write("Expected ");
      } else {
        buffer.write("; ");
      }
      buffer.write("0 errors of type ");
      buffer.write(code.uniqueName);
      buffer.write(", found ");
      buffer.write(actualCount);
      buffer.write(" (");
      for (int i = 0; i < actualErrors.length; i++) {
        AnalysisError error = actualErrors[i];
        if (i > 0) {
          buffer.write(", ");
        }
        buffer.write(error.offset);
      }
      buffer.write(")");
    });
    if (buffer.length > 0) {
      fail(buffer.toString());
    }
  }

  /**
   * Assert that the number of errors that have been gathered matches the number
   * of [expectedSeverities] and that there are the same number of errors and
   * warnings as specified by the argument. The order in which the errors were
   * gathered is ignored.
   */
  void assertErrorsWithSeverities(List<ErrorSeverity> expectedSeverities) {
    int expectedErrorCount = 0;
    int expectedWarningCount = 0;
    for (ErrorSeverity severity in expectedSeverities) {
      if (severity == ErrorSeverity.ERROR) {
        expectedErrorCount++;
      } else {
        expectedWarningCount++;
      }
    }
    int actualErrorCount = 0;
    int actualWarningCount = 0;
    for (AnalysisError error in _errors) {
      if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) {
        actualErrorCount++;
      } else {
        actualWarningCount++;
      }
    }
    if (expectedErrorCount != actualErrorCount ||
        expectedWarningCount != actualWarningCount) {
      fail(
          "Expected $expectedErrorCount errors and $expectedWarningCount warnings, found $actualErrorCount errors and $actualWarningCount warnings");
    }
  }

  /**
   * Assert that no errors have been gathered.
   */
  void assertNoErrors() {
    assertErrors(ExpectedError.NO_ERRORS);
  }

  /**
   * Return the line information associated with the given [source], or `null`
   * if no line information has been associated with the source.
   */
  LineInfo getLineInfo(Source source) => _lineInfoMap[source];

  /**
   * Return `true` if an error with the given [errorCode] has been gathered.
   */
  bool hasError(ErrorCode errorCode) {
    for (AnalysisError error in _errors) {
      if (identical(error.errorCode, errorCode)) {
        return true;
      }
    }
    return false;
  }

  @override
  void onError(AnalysisError error) {
    _errors.add(error);
  }

  /**
   * Set the line information associated with the given [source] to the given
   * list of [lineStarts].
   */
  void setLineInfo(Source source, List<int> lineStarts) {
    _lineInfoMap[source] = new LineInfo(lineStarts);
  }

  /**
   * Return `true` if the [actualError] matches the [expectedError].
   */
  bool _equalErrors(ExpectedError expectedError, AnalysisError actualError) {
    if (!identical(expectedError.code, actualError.errorCode)) {
      return false;
    } else if (!checkRanges) {
      return true;
    }
    return expectedError.offset == actualError.offset &&
        expectedError.length == actualError.length;
  }

  /**
   * Assert that the number of errors that have been gathered matches the number
   * of [expectedErrors] and that they have the expected error codes. The order
   * in which the errors were gathered is ignored.
   */
  void _fail(List<ExpectedError> expectedErrors) {
    StringBuffer buffer = new StringBuffer();
    buffer.write("Expected ");
    buffer.write(expectedErrors.length);
    buffer.write(" errors:");
    for (ExpectedError error in expectedErrors) {
      buffer.writeln();
      int offset = error.offset;
      buffer.write('  ${error.code} ($offset..${offset + error.length})');
    }
    buffer.writeln();
    buffer.write("found ");
    buffer.write(_errors.length);
    buffer.write(" errors:");
    for (AnalysisError error in _errors) {
      buffer.writeln();
      int offset = error.offset;
      buffer.write('  ${error.errorCode} '
          '($offset..${offset + error.length}): ${error.message}');
    }
    fail(buffer.toString());
  }

  /**
   * Search through the given list of [errors] for an error that is equal to the
   * [targetError]. If one is found, remove it from the list and return `true`,
   * otherwise return `false` without modifying the list.
   */
  bool _foundAndRemoved(List<ExpectedError> errors, AnalysisError targetError) {
    for (ExpectedError error in errors) {
      if (_equalErrors(error, targetError)) {
        errors.remove(error);
        return true;
      }
    }
    return false;
  }
}

/**
 * Instances of the class [TestLogger] implement a logger that can be used by
 * tests.
 */
class TestLogger implements Logger {
  /**
   * All logged messages.
   */
  List<String> log = [];

  @override
  void logError(String message, [CaughtException exception]) {
    log.add("error: $message");
  }

  @override
  void logInformation(String message, [CaughtException exception]) {
    log.add("info: $message");
  }
}

class TestSource extends Source {
  String _name;
  String _contents;
  int _modificationStamp = 0;
  bool exists2 = true;

  /**
   * A flag indicating whether an exception should be generated when an attempt
   * is made to access the contents of this source.
   */
  bool generateExceptionOnRead = false;

  /**
   * The number of times that the contents of this source have been requested.
   */
  int readCount = 0;

  TestSource([this._name = '/test.dart', this._contents]);

  TimestampedData<String> get contents {
    readCount++;
    if (generateExceptionOnRead) {
      String msg = "I/O Exception while getting the contents of " + _name;
      throw new Exception(msg);
    }
    return new TimestampedData<String>(0, _contents);
  }

  String get encoding => _name;

  String get fullName {
    return _name;
  }

  int get hashCode => 0;

  bool get isInSystemLibrary {
    return false;
  }

  @override
  int get modificationStamp =>
      generateExceptionOnRead ? -1 : _modificationStamp;

  String get shortName {
    return _name;
  }

  Uri get uri => new Uri.file(_name);

  UriKind get uriKind {
    throw new UnsupportedError('uriKind');
  }

  bool operator ==(Object other) {
    if (other is TestSource) {
      return other._name == _name;
    }
    return false;
  }

  bool exists() => exists2;
  void getContentsToReceiver(Source_ContentReceiver receiver) {
    throw new UnsupportedError('getContentsToReceiver');
  }

  Source resolve(String uri) {
    throw new UnsupportedError('resolve');
  }

  void setContents(String value) {
    generateExceptionOnRead = false;
    _modificationStamp = new DateTime.now().millisecondsSinceEpoch;
    _contents = value;
  }

  @override
  String toString() => '$_name';
}

class TestSourceWithUri extends TestSource {
  final Uri uri;

  TestSourceWithUri(String path, this.uri, [String content])
      : super(path, content);

  String get encoding => uri.toString();

  UriKind get uriKind {
    if (uri == null) {
      return UriKind.FILE_URI;
    } else if (uri.scheme == 'dart') {
      return UriKind.DART_URI;
    } else if (uri.scheme == 'package') {
      return UriKind.PACKAGE_URI;
    }
    return UriKind.FILE_URI;
  }

  bool operator ==(Object other) {
    if (other is TestSource) {
      return other.uri == uri;
    }
    return false;
  }
}
