// 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/file_system/memory_file_system.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
    hide NavigationTarget;
import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:nnbd_migration/src/front_end/dartfix_listener.dart';
import 'package:nnbd_migration/src/front_end/migration_info.dart';
import 'package:nnbd_migration/src/front_end/migration_state.dart';
import 'package:nnbd_migration/src/front_end/navigation_tree_renderer.dart';
import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
import 'package:nnbd_migration/src/front_end/path_mapper.dart';
import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
import 'package:nnbd_migration/src/preview/preview_site.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../front_end/nnbd_migration_test_base.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(PreviewSiteTest);
    defineReflectiveTests(PreviewSiteWithEngineTest);
  });
}

@reflectiveTest
class PreviewSiteTest with ResourceProviderMixin, PreviewSiteTestMixin {
  @override
  Future<void> performEdit(String path, int offset, String replacement) {
    final pathUri = Uri.file(path).path;
    return site
        .performEdit(Uri.parse('localhost://$pathUri?offset=$offset&end=$offset'
            '&replacement=${Uri.encodeComponent(replacement)}'));
  }

  void setUp() {
    dartfixListener = DartFixListener(null, ListenerClient());
    resourceProvider = MemoryResourceProvider();
    final migrationInfo =
        MigrationInfo({}, {}, resourceProvider.pathContext, null);
    state = MigrationState(null, null, dartfixListener, null, {});
    state.pathMapper = PathMapper(resourceProvider);
    state.migrationInfo = migrationInfo;
    site = PreviewSite(state, () async {
      return state;
    }, () {});
  }

  void test_apply_regress41391() async {
    final path = convertPath('/test.dart');
    final file = getFile(path);
    final analysisOptionsPath = convertPath('/analysis_options.yaml');
    final analysisOptions = getFile(analysisOptionsPath);
    analysisOptions.writeAsStringSync('analyzer:');
    final content = 'void main() {}';
    file.writeAsStringSync(content);
    site.unitInfoMap[path] = UnitInfo(path)..diskContent = content;
    // Add a source change for analysis_options, which has no UnitInfo.
    dartfixListener.addSourceFileEdit(
        'enable experiment',
        Location(analysisOptionsPath, 9, 0, 1, 9),
        SourceFileEdit(analysisOptionsPath, 0, edits: [
          SourceEdit(9, 0, '\n  enable-experiment:\n  - non-nullable')
        ]));
    // This should not crash.
    site.performApply([]);
    expect(analysisOptions.readAsStringSync(), '''
analyzer:
  enable-experiment:
  - non-nullable''');
    expect(state.hasBeenApplied, true);
  }

  void test_applyChangesEmpty() {
    final file = getFile('/test.dart');
    file.writeAsStringSync('void main() {}');
    site.performApply([]);
    expect(file.readAsStringSync(), 'void main() {}');
    expect(state.hasBeenApplied, true);
  }

  void test_applyChangesTwiceThrows() {
    site.performApply([]);
    expect(() => site.performApply([]), throwsA(isA<StateError>()));
  }

  void test_applyMigration_sanityCheck_dontApply() async {
    final path = convertPath('/test.dart');
    final file = getFile(path);
    site.unitInfoMap[path] = UnitInfo(path)
      ..diskContent = '// different content';
    final currentContent = 'void main() {}';
    file.writeAsStringSync(currentContent);
    dartfixListener.addSourceFileEdit(
        'test change',
        Location(path, 10, 0, 1, 10),
        SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')]));
    expect(() => site.performApply([]), throwsA(isA<StateError>()));
    expect(file.readAsStringSync(), currentContent);
    expect(state.hasBeenApplied, false);
  }

  void test_applyMultipleChanges() {
    final path = convertPath('/test.dart');
    final file = getFile(path);
    final content = 'void main() {}';
    file.writeAsStringSync(content);
    site.unitInfoMap[path] = UnitInfo(path)..diskContent = content;
    dartfixListener.addSourceFileEdit(
        'test change',
        Location(path, 10, 0, 1, 10),
        SourceFileEdit(path, 0, edits: [
          SourceEdit(10, 0, 'List args'),
          SourceEdit(13, 0, '\n  print(args);\n')
        ]));
    site.performApply([]);
    expect(file.readAsStringSync(), '''
void main(List args) {
  print(args);
}''');
    expect(state.hasBeenApplied, true);
  }

  void test_applySingleChange() {
    final path = convertPath('/test.dart');
    final file = getFile(path);
    final content = 'void main() {}';
    file.writeAsStringSync(content);
    site.unitInfoMap[path] = UnitInfo(path)..diskContent = content;
    dartfixListener.addSourceFileEdit(
        'test change',
        Location(path, 10, 0, 1, 10),
        SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')]));
    site.performApply([]);
    expect(file.readAsStringSync(), 'void main(List args) {}');
    expect(state.hasBeenApplied, true);
  }

  void test_optOutOfNullSafety_blankLines() {
    expect(IncrementalPlan.optCodeOutOfNullSafety('  \n  \n'),
        equals('// @dart=2.9\n\n  \n  \n'));
  }

  void test_optOutOfNullSafety_commentThenCode() {
    expect(
        IncrementalPlan.optCodeOutOfNullSafety('// comment\n\nvoid main() {}'),
        equals('// comment\n\n\n// @dart=2.9\n\nvoid main() {}'));
  }

  void test_optOutOfNullSafety_empty() {
    expect(IncrementalPlan.optCodeOutOfNullSafety(''), equals('// @dart=2.9'));
  }

  void test_optOutOfNullSafety_singleComment_multiLine() {
    expect(IncrementalPlan.optCodeOutOfNullSafety('// line 1\n// line 2'),
        equals('// line 1\n// line 2\n\n// @dart=2.9\n'));
  }

  void test_optOutOfNullSafety_singleComment_multiLine_indented() {
    expect(IncrementalPlan.optCodeOutOfNullSafety('  // line 1\n  // line 2'),
        equals('  // line 1\n  // line 2\n\n// @dart=2.9\n'));
  }

  void test_optOutOfNullSafety_singleComment_singleLine() {
    expect(IncrementalPlan.optCodeOutOfNullSafety('// comment'),
        equals('// comment\n\n// @dart=2.9\n'));
  }

  void test_optOutOfNullSafety_singleComment_singleLine_trailingNewline() {
    expect(IncrementalPlan.optCodeOutOfNullSafety('// comment\n'),
        equals('// comment\n\n\n// @dart=2.9\n'));
  }

  void test_optOutOfNullSafety_singleLine() {
    expect(IncrementalPlan.optCodeOutOfNullSafety('void main() {}'),
        equals('// @dart=2.9\n\nvoid main() {}'));
  }

  void test_optOutOfNullSafety_singleLine_afterBlankLines() {
    expect(IncrementalPlan.optCodeOutOfNullSafety('\n\nvoid main() {}'),
        equals('// @dart=2.9\n\n\n\nvoid main() {}'));
  }

  void test_performEdit() {
    final path = convertPath('/test.dart');
    final file = getFile(path);
    final content = 'int foo() {}';
    final unitInfo = UnitInfo(path)
      ..diskContent = content
      ..content = content
      ..diskChangesOffsetMapper = OffsetMapper.identity;
    site.unitInfoMap[path] = unitInfo;
    file.writeAsStringSync(content);
    performEdit(path, 3, '/*?*/');
    expect(file.readAsStringSync(), 'int/*?*/ foo() {}');
    expect(state.hasBeenApplied, false);
    expect(state.needsRerun, true);
    expect(unitInfo.content, 'int/*?*/ foo() {}');
  }

  void test_performEdit_sanityCheck_dontApply() {
    final path = convertPath('/test.dart');
    final file = getFile(path);
    site.unitInfoMap[path] = UnitInfo(path)
      ..diskContent = '// different content';
    final currentContent = 'void main() {}';
    file.writeAsStringSync(currentContent);
    expect(() => performEdit(path, 0, 'foo'), throwsA(isA<StateError>()));
    expect(file.readAsStringSync(), currentContent);
    expect(state.hasBeenApplied, false);
  }
}

mixin PreviewSiteTestMixin {
  PreviewSite site;
  DartFixListener dartfixListener;
  MigrationState state;

  Future<void> performEdit(String path, int offset, String replacement) {
    final pathUri = Uri.file(path).path;
    return site
        .performEdit(Uri.parse('localhost://$pathUri?offset=$offset&end=$offset'
            '&replacement=${Uri.encodeComponent(replacement)}'));
  }
}

@reflectiveTest
class PreviewSiteWithEngineTest extends NnbdMigrationTestBase
    with ResourceProviderMixin, PreviewSiteTestMixin {
  MigrationInfo migrationInfo;

  Future<void> setUpMigrationInfo(Map<String, String> files) async {
    await buildInfoForTestFiles(files, includedRoot: projectPath);
    dartfixListener = DartFixListener(null, ListenerClient());
    migrationInfo =
        MigrationInfo(infos, {}, resourceProvider.pathContext, projectPath);
    state = MigrationState(null, null, dartfixListener, null, {});
    nodeMapper = state.nodeMapper;
    state.pathMapper = PathMapper(resourceProvider);
    state.migrationInfo = migrationInfo;
    site = PreviewSite(state, () async {
      return state;
    }, () {});
  }

  void test_applyHintAction() async {
    await setUpMigrationInfo({});
    final path = convertPath('$projectPath/bin/test.dart');
    final file = getFile(path);
    final content = r'''
int x;
int y = x;
''';
    file.writeAsStringSync(content);
    final migratedContent = '''
int? x;
int? y = x;
''';
    final unitInfo = await buildInfoForSingleTestFile(content,
        migratedContent: migratedContent);
    site.unitInfoMap[path] = unitInfo;
    await site.performHintAction(
        unitInfo.regions[1].traces[0].entries[0].hintActions[0]);
    await site.performHintAction(
        unitInfo.regions[1].traces[0].entries[2].hintActions[0]);
    expect(file.readAsStringSync(), '''
int/*?*/ x;
int/*?*/ y = x;
''');
    expect(unitInfo.content, '''
int/*?*/? x;
int/*?*/? y = x;
''');
    assertRegion(
        region: unitInfo.regions[0], offset: unitInfo.content.indexOf('? x'));
    assertRegion(
        region: unitInfo.regions[1], offset: unitInfo.content.indexOf('? y'));
    final targets = List<NavigationTarget>.from(unitInfo.targets);
    assertInTargets(
        targets: targets,
        offset: unitInfo.content.indexOf('x'),
        offsetMapper: unitInfo.offsetMapper);
    assertInTargets(
        targets: targets,
        offset: unitInfo.content.indexOf('y'),
        offsetMapper: unitInfo.offsetMapper);
    var trace = unitInfo.regions[1].traces[0];
    assertTraceEntry(unitInfo, trace.entries[0], 'y',
        unitInfo.content.indexOf('int/*?*/? y'), contains('y (test.dart:2:1)'));
    assertTraceEntry(unitInfo, trace.entries[1], 'y',
        unitInfo.content.indexOf('= x;') + '= '.length, contains('data flow'));
    expect(state.hasBeenApplied, false);
    expect(state.needsRerun, true);
  }

  void test_applyHintAction_removeHint() async {
    await setUpMigrationInfo({});
    final path = convertPath('$projectPath/bin/test.dart');
    final file = getFile(path);
    final content = r'''
int/*!*/ x;
int y = x;
''';
    file.writeAsStringSync(content);
    final migratedContent = '''
int/*!*/ x;
int  y = x;
''';
    final unitInfo = await buildInfoForSingleTestFile(content,
        migratedContent: migratedContent);
    site.unitInfoMap[path] = unitInfo;
    await site.performHintAction(
        unitInfo.regions[0].traces[0].entries[0].hintActions[0]);
    expect(file.readAsStringSync(), '''
int x;
int y = x;
''');
    expect(unitInfo.content, '''
int x;
int  y = x;
''');
    expect(unitInfo.regions, hasLength(1));
    assertRegion(
        kind: NullabilityFixKind.typeNotMadeNullable,
        region: unitInfo.regions[0],
        offset: unitInfo.content.indexOf('  y'));
    final targets = List<NavigationTarget>.from(unitInfo.targets);
    assertInTargets(
        targets: targets,
        offset: unitInfo.content.indexOf('x'),
        offsetMapper: unitInfo.offsetMapper);
    expect(state.hasBeenApplied, false);
    expect(state.needsRerun, true);
  }

  void test_applyMigration_migratePreviouslyOptedOutFile() async {
    final path = convertPath('$projectPath/lib/a.dart');
    final content = '''
// @dart=2.9

void main() {}''';
    await setUpMigrationInfo({path: content});
    site.unitInfoMap[path] = UnitInfo(path)
      ..diskContent = content
      ..wasExplicitlyOptedOut = true;
    dartfixListener.addSourceFileEdit(
        'remove DLV comment',
        Location(path, 0, 14, 1, 1),
        SourceFileEdit(path, 0, edits: [SourceEdit(0, 14, '')]));
    var navigationTree =
        NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
    site.performApply(navigationTree);
    expect(getFile(path).readAsStringSync(), 'void main() {}');
  }

  void test_applyMigration_optOutEmptyFile() async {
    final path = convertPath('$projectPath/lib/a.dart');
    final content = '';
    await setUpMigrationInfo({path: content});
    site.unitInfoMap[path] = UnitInfo(path)
      ..diskContent = content
      ..wasExplicitlyOptedOut = false;
    var navigationTree =
        NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
    var libDir = navigationTree.single as NavigationTreeDirectoryNode;
    (libDir.subtree.single as NavigationTreeFileNode).migrationStatus =
        UnitMigrationStatus.optingOut;
    site.performApply(navigationTree);
    expect(getFile(path).readAsStringSync(), '// @dart=2.9');
  }

  void test_applyMigration_optOutOne_migrateAnother() async {
    final pathA = convertPath('$projectPath/lib/a.dart');
    final pathB = convertPath('$projectPath/lib/b.dart');
    final content = 'void main() {}';
    await setUpMigrationInfo({pathA: content, pathB: content});
    site.unitInfoMap[pathA] = UnitInfo(pathA)
      ..diskContent = content
      ..wasExplicitlyOptedOut = false;
    site.unitInfoMap[pathB] = UnitInfo(pathB)
      ..diskContent = content
      ..wasExplicitlyOptedOut = false;
    dartfixListener.addSourceFileEdit(
        'test change',
        Location(pathA, 10, 0, 1, 10),
        SourceFileEdit(pathA, 0, edits: [SourceEdit(10, 0, 'List args')]));
    dartfixListener.addSourceFileEdit(
        'test change',
        Location(pathB, 10, 0, 1, 10),
        SourceFileEdit(pathB, 0, edits: [SourceEdit(10, 0, 'List args')]));
    var navigationTree =
        NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
    var libDir = navigationTree.single as NavigationTreeDirectoryNode;
    (libDir.subtree[0] as NavigationTreeFileNode).migrationStatus =
        UnitMigrationStatus.optingOut;
    site.performApply(navigationTree);
    expect(getFile(pathA).readAsStringSync(), '''
// @dart=2.9

void main() {}''');
    expect(getFile(pathB).readAsStringSync(), '''
void main(List args) {}''');
  }

  void test_applyMigration_optOutFileWithEdits() async {
    final path = convertPath('$projectPath/lib/a.dart');
    final content = 'void main() {}';
    await setUpMigrationInfo({path: content});
    site.unitInfoMap[path] = UnitInfo(path)
      ..diskContent = content
      ..wasExplicitlyOptedOut = false;
    dartfixListener.addSourceFileEdit(
        'test change',
        Location(path, 10, 0, 1, 10),
        SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')]));
    var navigationTree =
        NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
    var libDir = navigationTree.single as NavigationTreeDirectoryNode;
    (libDir.subtree.single as NavigationTreeFileNode).migrationStatus =
        UnitMigrationStatus.optingOut;
    site.performApply(navigationTree);
    expect(getFile(path).readAsStringSync(), '''
// @dart=2.9

void main() {}''');
  }

  void test_applyMigration_optOutFileWithoutEdits() async {
    final path = convertPath('$projectPath/lib/a.dart');
    final content = 'void main() {}';
    await setUpMigrationInfo({path: content});
    site.unitInfoMap[path] = UnitInfo(path)
      ..diskContent = content
      ..wasExplicitlyOptedOut = false;
    var navigationTree =
        NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
    var libDir = navigationTree.single as NavigationTreeDirectoryNode;
    (libDir.subtree.single as NavigationTreeFileNode).migrationStatus =
        UnitMigrationStatus.optingOut;
    site.performApply(navigationTree);
    expect(getFile(path).readAsStringSync(), '''
// @dart=2.9

void main() {}''');
  }

  void test_applyMigration_optOutPreviouslyOptedOutFile() async {
    final path = convertPath('$projectPath/lib/a.dart');
    final content = '''
// @dart=2.9

int a;''';
    await setUpMigrationInfo({path: content});
    site.unitInfoMap[path] = UnitInfo(path)
      ..diskContent = content
      ..wasExplicitlyOptedOut = true;
    dartfixListener.addSourceFileEdit(
        'remove DLV comment',
        Location(path, 0, 14, 1, 1),
        SourceFileEdit(path, 0, edits: [SourceEdit(0, 14, '')]));
    var navigationTree =
        NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
    var libDir = navigationTree.single as NavigationTreeDirectoryNode;
    (libDir.subtree.single as NavigationTreeFileNode).migrationStatus =
        UnitMigrationStatus.optingOut;
    site.performApply(navigationTree);
    expect(getFile(path).readAsStringSync(), content);
  }

  void test_performEdit_multiple() async {
    await setUpMigrationInfo({});
    final path = convertPath('/test.dart');
    final file = getFile(path);
    final content = r'''
int x;
int y = x;
''';
    file.writeAsStringSync(content);
    final migratedContent = '''
int? x;
int? y = x;
''';
    final unitInfo = await buildInfoForSingleTestFile(content,
        migratedContent: migratedContent);
    site.unitInfoMap[path] = unitInfo;
    final firstEditOffset = unitInfo.regions[0].edits[0].offset;
    performEdit(path, firstEditOffset, '/*?*/');
    final secondEditOffset = unitInfo.regions[1].edits[0].offset;
    performEdit(path, secondEditOffset, '/*?*/');
    expect(file.readAsStringSync(), '''
int/*?*/ x;
int/*?*/ y = x;
''');
    expect(unitInfo.content, '''
int/*?*/? x;
int/*?*/? y = x;
''');
    assertRegion(
        region: unitInfo.regions[0], offset: unitInfo.content.indexOf('? x'));
    assertRegion(
        region: unitInfo.regions[1], offset: unitInfo.content.indexOf('? y'));
    final targets = List<NavigationTarget>.from(unitInfo.targets);
    assertInTargets(
        targets: targets,
        offset: unitInfo.content.indexOf('x'),
        offsetMapper: unitInfo.offsetMapper);
    assertInTargets(
        targets: targets,
        offset: unitInfo.content.indexOf('y'),
        offsetMapper: unitInfo.offsetMapper);
    var trace = unitInfo.regions[1].traces[0];
    assertTraceEntry(unitInfo, trace.entries[0], 'y',
        unitInfo.content.indexOf('int/*?*/? y'), contains('y (test.dart:2:1)'));
    assertTraceEntry(unitInfo, trace.entries[1], 'y',
        unitInfo.content.indexOf('= x;') + '= '.length, contains('data flow'));
    expect(state.hasBeenApplied, false);
    expect(state.needsRerun, true);
  }
}
