// 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:nnbd_migration/src/front_end/migration_info.dart';
import 'package:nnbd_migration/src/front_end/path_mapper.dart';
import 'package:nnbd_migration/src/front_end/region_renderer.dart';
import 'package:nnbd_migration/src/front_end/web/edit_details.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'nnbd_migration_test_base.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(RegionRendererTest);
    defineReflectiveTests(RegionRendererTestDriveD);
  });
}

@reflectiveTest
class RegionRendererTest extends RegionRendererTestBase {
  /// Returns the basename of [testFile], used in traces.
  String get _testFileBasename =>
      resourceProvider.pathContext.basename(testFile!);

  Future<void> test_informationalRegion_containsTrace() async {
    await buildInfoForSingleTestFile('f(int a) => a.isEven;',
        migratedContent: 'f(int  a) => a.isEven;');
    var response = renderRegion(5);
    expect(response.traces, hasLength(1));
    var trace = response.traces![0];
    expect(trace.description, equals('Non-nullability reason'));
  }

  Future<void> test_informationalRegion_containsTraceEntryDescriptions() async {
    await buildInfoForSingleTestFile('f(int a) => a.isEven;',
        migratedContent: 'f(int  a) => a.isEven;');
    var response = renderRegion(5);
    expect(response.traces, hasLength(1));
    var trace = response.traces![0];
    expect(trace.entries, hasLength(2));
    expect(trace.entries[0].description,
        equals('parameter 0 of f ($_testFileBasename:1:3)'));
    expect(trace.entries[1].description, equals('data flow'));
  }

  Future<void> test_informationalRegion_containsTraceLinks() async {
    await buildInfoForSingleTestFile('f(int a) => a.isEven;',
        migratedContent: 'f(int  a) => a.isEven;');
    var response = renderRegion(5);
    expect(response.traces, hasLength(1));
    var trace = response.traces![0];
    var entry = trace.entries[0];
    expect(entry.link, isNotNull);
    var testFileUriPath = resourceProvider.pathContext.toUri(testFile!).path;
    expect(entry.link!.href,
        equals('$testFileUriPath?offset=2&line=1&authToken=AUTH_TOKEN'));
    expect(entry.link!.path,
        equals(resourceProvider.pathContext.toUri(_testFileBasename).path));
  }

  Future<void> test_modifiedOutput_containsExplanation() async {
    await buildInfoForSingleTestFile('int a = null;',
        migratedContent: 'int? a = null;');
    var response = renderRegion(3);
    expect(response.explanation, equals("Changed type 'int' to be nullable"));
  }

  Future<void> test_modifiedOutput_containsPath() async {
    await buildInfoForSingleTestFile('int a = null;',
        migratedContent: 'int? a = null;');
    var response = renderRegion(3);
    expect(response.displayPath, equals(testFile));
    expect(response.uriPath, equals(pathMapper!.map(testFile!)));
    expect(response.line, equals(1));
  }

  Future<void> test_modifiedOutput_containsTraceForNullabilityReason() async {
    await buildInfoForSingleTestFile('int a = null;',
        migratedContent: 'int? a = null;');
    var response = renderRegion(3);
    expect(response.traces, hasLength(1));
    var trace = response.traces![0];
    expect(trace.description, equals('Nullability reason'));
    expect(trace.entries, hasLength(4));
    expect(trace.entries[0].description, equals('a ($_testFileBasename:1:1)'));
    expect(trace.entries[1].description, equals('data flow'));
    expect(trace.entries[2].description,
        equals('null literal ($_testFileBasename:1:9)'));
    expect(trace.entries[3].description, equals('literal expression'));
  }

  Future<void> test_unmodifiedOutput_containsExplanation() async {
    await buildInfoForSingleTestFile('f(int a) => a.isEven;',
        migratedContent: 'f(int  a) => a.isEven;');
    var response = renderRegion(5);
    expect(response.explanation, equals("Type 'int' was not made nullable"));
  }

  Future<void> test_unmodifiedOutput_containsPath() async {
    await buildInfoForSingleTestFile('f(int a) => a.isEven;',
        migratedContent: 'f(int  a) => a.isEven;');
    var response = renderRegion(5);
    expect(response.displayPath, equals(testFile));
    expect(response.uriPath, equals(pathMapper!.map(testFile!)));
    expect(response.line, equals(1));
  }
}

class RegionRendererTestBase extends NnbdMigrationTestBase {
  PathMapper? pathMapper;

  /// Render the region at [offset], using a [MigrationInfo] which knows only
  /// about the library at `infos.single`.
  EditDetails renderRegion(int offset) {
    var migrationInfo =
        MigrationInfo(infos, {}, resourceProvider.pathContext, projectPath);
    var unitInfo = infos!.single;
    var region = unitInfo.regionAt(offset);
    pathMapper = PathMapper(resourceProvider);
    return RegionRenderer(
            region, unitInfo, migrationInfo, pathMapper, 'AUTH_TOKEN')
        .render();
  }
}

@reflectiveTest
class RegionRendererTestDriveD extends RegionRendererTestBase {
  @override
  String get homePath => _switchToDriveD(super.homePath);

  Future<void>
      test_informationalRegion_containsTraceLinks_separateDrive() async {
    // See https://github.com/dart-lang/sdk/issues/43178. Linking from a file on
    // one drive to a file on another drive can cause problems.
    await buildInfoForSingleTestFile(r'''
f(List<int> a) {
  if (1 == 2) List.from(a);
}
g() {
  f(null);
}
''', migratedContent: r'''
f(List<int >? a) {
  if (1 == 2) List.from(a!);
}
g() {
  f(null);
}
''');
    var response = renderRegion(44); // The inserted null-check.
    expect(response.displayPath,
        equals(_switchToDriveD(convertPath('/home/tests/bin/test.dart'))));
    expect(response.traces, hasLength(2));
    var trace = response.traces![1];
    expect(trace.description, equals('Non-nullability reason'));
    expect(trace.entries, hasLength(1));
    var entry = trace.entries[0];
    expect(entry.link, isNotNull);
    var sdkCoreLib = convertPath('/sdk/lib/core/core.dart');
    var sdkCoreLibUriPath = resourceProvider.pathContext.toUri(sdkCoreLib).path;
    var coreLibText = resourceProvider.getFile(sdkCoreLib).readAsStringSync();
    var expectedOffset =
        'List.from'.allMatches(coreLibText).single.start + 'List.'.length;
    var expectedLine =
        '\n'.allMatches(coreLibText.substring(0, expectedOffset)).length + 1;
    expect(
        entry.link!.href,
        equals('$sdkCoreLibUriPath?'
            'offset=$expectedOffset&'
            'line=$expectedLine&'
            'authToken=AUTH_TOKEN'));
    // On Windows, the path will simply be the absolute path to the core
    // library, because there is no relative route from C:\ to D:\. On Posix,
    // the path is relative.
    var expectedLinkPath = resourceProvider.pathContext.style == p.Style.windows
        ? sdkCoreLibUriPath
        : '../../..$sdkCoreLibUriPath';
    expect(entry.link!.path, equals(expectedLinkPath));
  }

  /// On Windows, replace the C:\ relative root in [path] with the D:\ relative
  /// root.
  ///
  /// On Posix, nothing is be replaced.
  String _switchToDriveD(String path) {
    assert(resourceProvider.pathContext.isAbsolute(path));
    return resourceProvider
        .convertPath(path)
        .replaceFirst(RegExp('^C:\\\\'), 'D:\\');
  }
}
