// 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);
  });
}

@reflectiveTest
class RegionRendererTest extends NnbdMigrationTestBase {
  PathMapper pathMapper;

  /// Returns the path of [testFile] used in traces.
  ///
  /// On Windows, we display the absolute path of the test file.
  /// On Posix, we display the path of the target file relative to the current
  /// file.
  // TODO(srawlins): I doubt this is intentional. While I don't see a bug,
  //  the discrepancy could lead to confusion and may be an indicator of bugs.
  String get _testFilePathForTrace =>
      resourceProvider.pathContext.style == p.Style.windows
          ? testFile
          : resourceProvider.pathContext.basename(testFile);

  /// 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();
  }

  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 ($_testFilePathForTrace: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(_testFilePathForTrace).path));
  }

  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.
    projectPath = _switchToDriveD(projectPath);
    testFolder = _switchToDriveD(testFolder);
    testFile = _switchToDriveD(testFile);
    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;
    expect(entry.link.href,
        equals('$sdkCoreLibUriPath?offset=3730&line=166&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));
  }

  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 ($_testFilePathForTrace:1:1)'));
    expect(trace.entries[1].description, equals('data flow'));
    expect(trace.entries[2].description,
        equals('null literal ($_testFilePathForTrace: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));
  }

  /// 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 path.replaceFirst(RegExp('^C:\\\\'), 'D:\\');
  }
}
