// Copyright (c) 2020, 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/analysis/results.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:nnbd_migration/src/front_end/dartfix_listener.dart';
import 'package:nnbd_migration/src/front_end/driver_provider_impl.dart';
import 'package:nnbd_migration/src/front_end/info_builder.dart';
import 'package:nnbd_migration/src/front_end/instrumentation_listener.dart';
import 'package:nnbd_migration/src/front_end/migration_info.dart';
import 'package:nnbd_migration/src/front_end/non_nullable_fix.dart';
import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
import 'package:nnbd_migration/src/hint_action.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../utilities/test_logger.dart';
import 'analysis_abstract.dart';

class ListenerClient implements DartFixListenerClient {
  @override
  void onException(String detail) {
    fail('Unexpected call to onException($detail)');
  }

  @override
  void onFatalError(String detail) {
    fail('Unexpected call to onFatalError($detail)');
  }

  @override
  void onMessage(String detail) {
    fail('Unexpected call to onMessage($detail)');
  }
}

@reflectiveTest
class NnbdMigrationTestBase extends AbstractAnalysisTest {
  /// The information produced by the InfoBuilder, or `null` if [buildInfo] has
  /// not yet completed.
  Set<UnitInfo>? infos;
  NodeMapper? nodeMapper;

  /// Assert that some target in [targets] has various properties.
  void assertInTargets(
      {required Iterable<NavigationTarget> targets,
      int? offset,
      int? length,
      OffsetMapper? offsetMapper}) {
    var failureReasons = [
      if (offset != null) 'offset: $offset',
      if (length != null) 'length: $length',
      if (offsetMapper != null) 'match a custom offset mapper',
    ].join(' and ');
    offsetMapper ??= OffsetMapper.identity;
    expect(targets.any((t) {
      return (offset == null || offset == offsetMapper!.map(t.offset)) &&
          (length == null || length == t.length);
    }), isTrue, reason: 'Expected one of $targets to contain $failureReasons');
  }

  /// Assert various properties of the given [region]. If an [offset] is
  /// provided but no [length] is provided, a default length of `1` will be
  /// used.
  void assertRegion(
      {required RegionInfo region,
      int? offset,
      int? length,
      Object explanation = anything,
      Object edits = anything,
      Object traces = anything,
      Object kind = NullabilityFixKind.makeTypeNullable}) {
    if (offset != null) {
      expect(region.offset, offset);
      expect(region.length, length ?? 1);
    } else if (length != null) {
      expect(region.length, length);
    }
    expect(region.kind, kind);
    expect(region.edits, edits);
    expect(region.explanation, explanation);
    expect(region.traces, traces);
  }

  /// Asserts various properties of the pair of [regions], `regions[index]` and
  /// `regions[index + 1]`.  The expected offsets and lengths are specified
  /// separately; everything else is asserted using the same matcher.
  void assertRegionPair(List<RegionInfo> regions, int index,
      {int? offset1,
      int? length1,
      int? offset2,
      int? length2,
      Object explanation = anything,
      Object edits = anything,
      Object traces = anything,
      Object kind = anything}) {
    assertRegion(
        region: regions[index],
        offset: offset1,
        length: length1,
        explanation: explanation,
        edits: edits,
        traces: traces,
        kind: kind);
    assertRegion(
        region: regions[index + 1],
        offset: offset2,
        length: length2,
        explanation: explanation,
        edits: edits,
        traces: traces,
        kind: kind);
  }

  void assertTraceEntry(UnitInfo unit, TraceEntryInfo entryInfo,
      String function, int offset, Object descriptionMatcher,
      {Set<HintActionKind>? hintActions}) {
    assert(offset >= 0);
    var lineInfo = LineInfo.fromContent(unit.content!);
    var expectedLocation = lineInfo.getLocation(offset);
    expect(entryInfo.target!.filePath, unit.path);
    expect(entryInfo.target!.line, expectedLocation.lineNumber);
    expect(unit.offsetMapper.map(entryInfo.target!.offset), offset);
    expect(entryInfo.function, function);
    expect(entryInfo.description, descriptionMatcher);
    if (hintActions != null) {
      assertTraceHintActions(unit, entryInfo, hintActions, offset);
    }
  }

  void assertTraceHintActions(UnitInfo unit, TraceEntryInfo traceEntry,
      Set<HintActionKind> expectedHints, int nodeOffset) {
    final actionsByKind = Map<HintActionKind, HintAction>.fromIterables(
        traceEntry.hintActions.map((action) => action.kind),
        traceEntry.hintActions);
    expect(actionsByKind, hasLength(expectedHints.length));
    for (final expectedHint in expectedHints) {
      final action = actionsByKind[expectedHint]!;
      expect(action, isNotNull);
      final node = nodeMapper!.nodeForId(action.nodeId)!;
      expect(node, isNotNull);
      expect(unit.offsetMapper.map(node.codeReference!.offset), nodeOffset);
    }
  }

  /// Uses the InfoBuilder to build information for [testFile].
  ///
  /// The information is stored in [infos].
  Future<void> buildInfo(
      {bool removeViaComments = true, bool warnOnWeakCode = false}) async {
    var includedRoot = resourceProvider.pathContext.dirname(testFile!);
    await _buildMigrationInfo([testFile],
        includedRoot: includedRoot,
        shouldBeMigratedFunction: (String? path) => true,
        pathsToProcess: [testFile],
        removeViaComments: removeViaComments,
        warnOnWeakCode: warnOnWeakCode);
  }

  /// Uses the InfoBuilder to build information for a single test file.
  ///
  /// Asserts that [originalContent] is migrated to [migratedContent]. Returns
  /// the singular UnitInfo which was built.
  Future<UnitInfo> buildInfoForSingleTestFile(String originalContent,
      {required String migratedContent,
      bool removeViaComments = true,
      bool warnOnWeakCode = false}) async {
    addTestFile(originalContent);
    await buildInfo(
        removeViaComments: removeViaComments, warnOnWeakCode: warnOnWeakCode);
    // Ignore info for dart:core.
    var filteredInfos = [
      for (var info in infos!)
        if (!info.path!.contains('core.dart')) info
    ];
    expect(filteredInfos, hasLength(1));
    var unit = filteredInfos[0];
    expect(unit.path, testFile);
    expect(unit.content, migratedContent);
    return unit;
  }

  /// Uses the [InfoBuilder] to build information for test files.
  ///
  /// Returns the singular [UnitInfo] which was built.
  Future<List<UnitInfo>> buildInfoForTestFiles(Map<String, String> files,
      {required String? includedRoot,
      bool Function(String?)? shouldBeMigratedFunction,
      Iterable<String>? pathsToProcess}) async {
    shouldBeMigratedFunction ??= (String? path) => true;
    var testPaths = <String>[];
    files.forEach((String path, String content) {
      newFile(path, content: content);
      testPaths.add(path);
    });
    pathsToProcess ??= testPaths;
    await _buildMigrationInfo(testPaths,
        includedRoot: includedRoot,
        shouldBeMigratedFunction: shouldBeMigratedFunction,
        pathsToProcess: pathsToProcess);
    // Ignore info for dart:core.
    var filteredInfos = [
      for (var info in infos!)
        if (!info.path!.contains('core.dart')) info
    ];
    return filteredInfos;
  }

  void setUp() {
    super.setUp();
    nodeMapper = SimpleNodeMapper();
  }

  /// Uses the InfoBuilder to build information for files at [testPaths], which
  /// should all share a common parent directory, [includedRoot].
  Future<void> _buildMigrationInfo(Iterable<String?> testPaths,
      {required String? includedRoot,
      required bool Function(String?) shouldBeMigratedFunction,
      required Iterable<String?> pathsToProcess,
      bool removeViaComments = true,
      bool warnOnWeakCode = false}) async {
    // Compute the analysis results.
    var server = DriverProviderImpl(resourceProvider, driver!.analysisContext);
    // Run the migration engine.
    var listener = DartFixListener(server, ListenerClient());
    var instrumentationListener = InstrumentationListener();
    var adapter = NullabilityMigrationAdapter(listener);
    var migration = NullabilityMigration(adapter,
        permissive: false,
        instrumentation: instrumentationListener,
        removeViaComments: removeViaComments,
        warnOnWeakCode: warnOnWeakCode);
    Future<void> _forEachPath(
        void Function(ResolvedUnitResult) callback) async {
      for (var testPath in testPaths) {
        var result = await driver!.currentSession.getResolvedUnit(testPath!)
            as ResolvedUnitResult;
        callback(result);
      }
    }

    await _forEachPath(migration.prepareInput);
    expect(migration.unmigratedDependencies, isEmpty);
    await _forEachPath(migration.processInput);
    await _forEachPath(migration.finalizeInput);
    migration.finish();
    // Build the migration info.
    var info = instrumentationListener.data;
    var logger = TestLogger(false);
    var builder = InfoBuilder(
        resourceProvider,
        includedRoot,
        info,
        listener,
        migration,
        nodeMapper,
        logger,
        shouldBeMigratedFunction,
        pathsToProcess);
    infos = await builder.explainMigration();
  }
}
