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

// TODO(jmesserly): this file needs to be refactored, it's a port from
// package:dev_compiler's tests
import 'dart:async';
import 'dart:collection';

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_resolution_map.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:source_span/source_span.dart';
import 'package:test/test.dart';

import '../../context/mock_sdk.dart';

SourceSpanWithContext _createSpanHelper(
    LineInfo lineInfo, int start, Source source, String content,
    {int end}) {
  var startLoc = _locationForOffset(lineInfo, source.uri, start);
  var endLoc = _locationForOffset(lineInfo, source.uri, end ?? start);

  var lineStart = startLoc.offset - startLoc.column;
  // Find the end of the line. This is not exposed directly on LineInfo, but
  // we can find it pretty easily.
  // TODO(jmesserly): for now we do the simple linear scan. Ideally we can get
  // some help from the LineInfo API.
  int lineEnd = endLoc.offset;
  int lineNum = lineInfo.getLocation(lineEnd).lineNumber;
  while (lineEnd < content.length &&
      lineInfo.getLocation(++lineEnd).lineNumber == lineNum) {}

  if (end == null) {
    end = lineEnd;
    endLoc = _locationForOffset(lineInfo, source.uri, lineEnd);
  }

  var text = content.substring(start, end);
  var lineText = content.substring(lineStart, lineEnd);
  return new SourceSpanWithContext(startLoc, endLoc, text, lineText);
}

String _errorCodeName(ErrorCode errorCode) {
  var name = errorCode.name;
  final prefix = 'STRONG_MODE_';
  if (name.startsWith(prefix)) {
    return name.substring(prefix.length);
  } else {
    return name;
  }
}

ErrorSeverity _errorSeverity(
    AnalysisOptions analysisOptions, AnalysisError error) {
  // TODO(brianwilkerson) Remove the if when top-level inference is made an
  // error again.
  if (error.errorCode.name.startsWith('STRONG_MODE_TOP_LEVEL_')) {
    return ErrorSeverity.ERROR;
  }
  return ErrorProcessor.getProcessor(analysisOptions, error)?.severity ??
      error.errorCode.errorSeverity;
}

void _expectErrors(AnalysisOptions analysisOptions, CompilationUnit unit,
    List<AnalysisError> actualErrors) {
  var expectedErrors = _findExpectedErrors(unit.beginToken);

  var actualMap = new SplayTreeMap<int, List<AnalysisError>>();
  for (var e in actualErrors) {
    actualMap.putIfAbsent(e.offset, () => []).add(e);
  }
  var expectedMap = new SplayTreeMap<int, List<_ErrorExpectation>>();
  for (var e in expectedErrors) {
    expectedMap.putIfAbsent(e.offset, () => []).add(e);
  }

  // Categorize the differences, if any.
  var unreported = <_ErrorExpectation>[];
  var different = <List<_ErrorExpectation>, List<AnalysisError>>{};

  expectedMap.forEach((offset, expectedList) {
    var actualList = actualMap[offset] ?? [];

    var unmatched = <_ErrorExpectation>[];
    for (var expected in expectedList) {
      var match = actualList.firstWhere(
          (a) => expected.matches(analysisOptions, a),
          orElse: () => null);
      if (match != null) {
        actualList.remove(match);
        if (actualList.isEmpty) actualMap.remove(offset);
      } else {
        unmatched.add(expected);
      }
    }

    if (actualList.isEmpty) {
      unreported.addAll(unmatched);
    } else if (unmatched.isNotEmpty) {
      different[unmatched] = actualList;
      actualMap.remove(offset);
    }
  });

  // Whatever is left was an unexpected error.
  List<AnalysisError> unexpected = actualMap.values.expand((a) => a).toList();

  if (unreported.isNotEmpty || unexpected.isNotEmpty || different.isNotEmpty) {
    _reportFailure(analysisOptions, unit, unreported, unexpected, different);
  }
}

List<_ErrorExpectation> _findExpectedErrors(Token beginToken) {
  var expectedErrors = <_ErrorExpectation>[];

  // Collect expectations like "error:STATIC_TYPE_ERROR" from comment tokens.
  for (Token t = beginToken; t.type != TokenType.EOF; t = t.next) {
    for (CommentToken c = t.precedingComments; c != null; c = c.next) {
      if (c.type == TokenType.MULTI_LINE_COMMENT) {
        String value = c.lexeme.substring(2, c.lexeme.length - 2);
        if (value.contains(':')) {
          int offset = t.offset;
          Token previous = t.previous;
          while (previous != null && previous.offset > c.offset) {
            offset = previous.offset;
            previous = previous.previous;
          }
          for (var expectCode in value.split(',')) {
            var expected = _ErrorExpectation.parse(offset, expectCode);
            if (expected != null) {
              expectedErrors.add(expected);
            }
          }
        }
      }
    }
  }
  return expectedErrors;
}

SourceLocation _locationForOffset(LineInfo lineInfo, Uri uri, int offset) {
  var loc = lineInfo.getLocation(offset);
  return new SourceLocation(offset,
      sourceUrl: uri, line: loc.lineNumber - 1, column: loc.columnNumber - 1);
}

/// Returns all libraries transitively imported or exported from [start].
Set<LibraryElement> _reachableLibraries(LibraryElement start) {
  Set<LibraryElement> results = new Set<LibraryElement>();

  void find(LibraryElement library) {
    if (results.add(library)) {
      library.importedLibraries.forEach(find);
      library.exportedLibraries.forEach(find);
    }
  }

  find(start);
  return results;
}

void _reportFailure(
    AnalysisOptions analysisOptions,
    CompilationUnit unit,
    List<_ErrorExpectation> unreported,
    List<AnalysisError> unexpected,
    Map<List<_ErrorExpectation>, List<AnalysisError>> different) {
  // Get the source code. This reads the data again, but it's safe because
  // all tests use memory file system.
  var sourceCode =
      resolutionMap.elementDeclaredByCompilationUnit(unit).source.contents.data;

  String formatActualError(AnalysisError error) {
    int offset = error.offset;
    int length = error.length;
    var span = _createSpanHelper(unit.lineInfo, offset,
        resolutionMap.elementDeclaredByCompilationUnit(unit).source, sourceCode,
        end: offset + length);
    var levelName = _errorSeverity(analysisOptions, error).displayName;
    return '@$offset $levelName:${_errorCodeName(error.errorCode)}\n' +
        span.message(error.message);
  }

  String formatExpectedError(_ErrorExpectation error, {bool showSource: true}) {
    int offset = error.offset;
    var severity = error.severity.displayName;
    var result = '@$offset $severity:${error.typeName}';
    if (!showSource) return result;
    var span = _createSpanHelper(
        unit.lineInfo,
        offset,
        resolutionMap.elementDeclaredByCompilationUnit(unit).source,
        sourceCode);
    return '$result\n${span.message('')}';
  }

  var message = new StringBuffer();
  if (unreported.isNotEmpty) {
    message.writeln('Expected errors that were not reported:');
    unreported.map(formatExpectedError).forEach(message.writeln);
    message.writeln();
  }
  if (unexpected.isNotEmpty) {
    message.writeln('Errors that were not expected:');
    unexpected.map(formatActualError).forEach(message.writeln);
    message.writeln();
  }
  if (different.isNotEmpty) {
    message.writeln('Errors that were reported, but different than expected:');
    different.forEach((expected, actual) {
      // The source location is the same for the expected and actual, so we only
      // print it once.
      message.writeln('Expected: ' +
          expected
              .map((e) => formatExpectedError(e, showSource: false))
              .join(', '));
      message.writeln('Actual: ' + actual.map(formatActualError).join(', '));
    });
    message.writeln();
  }
  fail('Checker errors do not match expected errors:\n\n$message');
}

class AbstractStrongTest {
  MemoryResourceProvider _resourceProvider = new MemoryResourceProvider();
  bool _checkCalled = false;

  AnalysisContext _context = null;
  AnalysisDriver _driver = null;

  bool get enableNewAnalysisDriver => false;

  /// Adds a file to check. The file should contain:
  ///
  ///   * all expected failures are listed in the source code using comments
  ///     immediately in front of the AST node that should contain the error.
  ///
  ///   * errors are formatted as a token `severity:ErrorCode`, where
  ///     `severity` is the ErrorSeverity the error would be reported at, and
  ///     `ErrorCode` is the error code's name.
  ///
  /// For example to check that an assignment produces a type error, you can
  /// create a file like:
  ///
  ///     addFile('''
  ///       String x = /*error:STATIC_TYPE_ERROR*/3;
  ///     ''');
  ///     check();
  ///
  /// For a single file, you may also use [checkFile].
  void addFile(String content, {String name: '/main.dart'}) {
    name = name.replaceFirst('^package:', '/packages/');
    _resourceProvider.newFile(_resourceProvider.convertPath(name), content);
  }

  /// Run the checker on a program, staring from '/main.dart', and verifies that
  /// errors/warnings/hints match the expected value.
  ///
  /// See [addFile] for more information about how to encode expectations in
  /// the file text.
  ///
  /// Returns the main resolved library. This can be used for further checks.
  Future<CompilationUnit> check(
      {bool declarationCasts: true,
      bool implicitCasts: true,
      bool implicitDynamic: true,
      bool superMixins: false}) async {
    _checkCalled = true;

    File mainFile =
        _resourceProvider.getFile(_resourceProvider.convertPath('/main.dart'));
    expect(mainFile.exists, true, reason: '`/main.dart` is missing');

    AnalysisOptionsImpl analysisOptions = new AnalysisOptionsImpl();
    analysisOptions.strongModeHints = true;
    analysisOptions.declarationCasts = declarationCasts;
    analysisOptions.implicitCasts = implicitCasts;
    analysisOptions.implicitDynamic = implicitDynamic;
    analysisOptions.enableSuperMixins = superMixins;

    var mockSdk = new MockSdk(resourceProvider: _resourceProvider);
    mockSdk.context.analysisOptions = analysisOptions;

    SourceFactory sourceFactory;
    {
      var uriResolver = new _TestUriResolver(_resourceProvider);
      sourceFactory =
          new SourceFactory([new DartUriResolver(mockSdk), uriResolver]);
    }

    CompilationUnit mainUnit;
    if (enableNewAnalysisDriver) {
      StringBuffer logBuffer = new StringBuffer();
      FileContentOverlay fileContentOverlay = new FileContentOverlay();
      PerformanceLog log = new PerformanceLog(logBuffer);
      AnalysisDriverScheduler scheduler = new AnalysisDriverScheduler(log);
      _driver = new AnalysisDriver(
          scheduler,
          log,
          _resourceProvider,
          new MemoryByteStore(),
          fileContentOverlay,
          null,
          sourceFactory,
          analysisOptions);
      scheduler.start();

      mainUnit = (await _driver.getResult(mainFile.path)).unit;
    } else {
      _context = AnalysisEngine.instance.createAnalysisContext();
      _context.analysisOptions = analysisOptions;
      _context.sourceFactory = sourceFactory;

      // Run the checker on /main.dart.
      Source mainSource = sourceFactory.forUri2(mainFile.toUri());
      mainUnit = _context.resolveCompilationUnit2(mainSource, mainSource);
    }

    var collector = new _ErrorCollector(analysisOptions);

    // Extract expectations from the comments in the test files, and
    // check that all errors we emit are included in the expected map.
    LibraryElement mainLibrary =
        resolutionMap.elementDeclaredByCompilationUnit(mainUnit).library;
    Set<LibraryElement> allLibraries = _reachableLibraries(mainLibrary);
    for (LibraryElement library in allLibraries) {
      for (CompilationUnitElement unit in library.units) {
        var errors = <AnalysisError>[];
        collector.errors = errors;

        var source = unit.source;
        if (source.uri.scheme == 'dart') {
          continue;
        }

        var analysisResult = await _resolve(source);

        errors.addAll(analysisResult.errors.where((e) =>
            // We don't care about any of these:
            e.errorCode != HintCode.UNUSED_ELEMENT &&
            e.errorCode != HintCode.UNUSED_FIELD &&
            e.errorCode != HintCode.UNUSED_IMPORT &&
            e.errorCode != HintCode.UNUSED_LOCAL_VARIABLE &&
            e.errorCode != TodoCode.TODO));
        _expectErrors(analysisOptions, analysisResult.unit, errors);
      }
    }

    return mainUnit;
  }

  /// Adds a file using [addFile] and calls [check].
  ///
  /// Also returns the resolved compilation unit.
  Future<CompilationUnit> checkFile(String content,
      {bool declarationCasts: true,
      bool implicitCasts: true,
      bool implicitDynamic: true,
      bool superMixins: false}) async {
    addFile(content);
    return await check(
        declarationCasts: declarationCasts,
        implicitCasts: implicitCasts,
        implicitDynamic: implicitDynamic,
        superMixins: superMixins);
  }

  void setUp() {
    AnalysisEngine.instance.processRequiredPlugins();
  }

  void tearDown() {
    // This is a sanity check, in case only addFile is called.
    expect(_checkCalled, true, reason: 'must call check() method in test case');
    _context?.dispose();
    _driver?.dispose();
    AnalysisEngine.instance.clearCaches();
  }

  Future<_TestAnalysisResult> _resolve(Source source) async {
    if (enableNewAnalysisDriver) {
      var result = await _driver.getResult(source.fullName);
      return new _TestAnalysisResult(source, result.unit, result.errors);
    } else {
      List<Source> libraries = _context.getLibrariesContaining(source);
      var unit = _context.resolveCompilationUnit2(source, libraries.single);
      var errors = _context.computeErrors(source);
      return new _TestAnalysisResult(source, unit, errors);
    }
  }
}

class _ErrorCollector implements AnalysisErrorListener {
  final AnalysisOptions analysisOptions;
  List<AnalysisError> errors;
  final bool hints;

  _ErrorCollector(this.analysisOptions, {this.hints: true});

  void onError(AnalysisError error) {
    // Unless DDC hints are requested, filter them out.
    var HINT = ErrorSeverity.INFO.ordinal;
    if (hints || _errorSeverity(analysisOptions, error).ordinal > HINT) {
      errors.add(error);
    }
  }
}

/// Describes an expected message that should be produced by the checker.
class _ErrorExpectation {
  final int offset;
  final ErrorSeverity severity;
  final String typeName;

  _ErrorExpectation(this.offset, this.severity, this.typeName);

  bool matches(AnalysisOptions options, AnalysisError e) {
    return _errorSeverity(options, e) == severity &&
        _errorCodeName(e.errorCode) == typeName;
  }

  String toString() => '@$offset ${severity.displayName}: [$typeName]';

  static _ErrorExpectation parse(int offset, String descriptor) {
    descriptor = descriptor.trim();
    var tokens = descriptor.split(' ');
    if (tokens.length == 1) return _parse(offset, tokens[0]);
    expect(tokens.length, 4, reason: 'invalid error descriptor');
    expect(tokens[1], "should", reason: 'invalid error descriptor');
    expect(tokens[2], "be", reason: 'invalid error descriptor');
    if (tokens[0] == "pass") return null;
    // TODO(leafp) For now, we just use whatever the current expectation is,
    // eventually we could do more automated reporting here.
    return _parse(offset, tokens[0]);
  }

  static _ErrorExpectation _parse(offset, String descriptor) {
    var tokens = descriptor.split(':');
    expect(tokens.length, 2, reason: 'invalid error descriptor');
    var name = tokens[0].toUpperCase();
    var typeName = tokens[1];

    var level = ErrorSeverity.values
        .firstWhere((l) => l.name == name, orElse: () => null);
    expect(level, isNotNull,
        reason: 'invalid severity in error descriptor: `${tokens[0]}`');
    expect(typeName, isNotNull,
        reason: 'invalid type in error descriptor: ${tokens[1]}');
    return new _ErrorExpectation(offset, level, typeName);
  }
}

class _TestAnalysisResult {
  final Source source;
  final CompilationUnit unit;
  final List<AnalysisError> errors;
  _TestAnalysisResult(this.source, this.unit, this.errors);
}

class _TestUriResolver extends ResourceUriResolver {
  final MemoryResourceProvider provider;
  _TestUriResolver(provider)
      : provider = provider,
        super(provider);

  @override
  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
    if (uri.scheme == 'package') {
      return (provider.getResource(
              provider.convertPath('/packages/' + uri.path)) as File)
          .createSource(uri);
    }
    return super.resolveAbsolute(uri, actualUri);
  }
}
