// 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 basename of [testFile], used in traces.
  String get _testFileBasename =>
      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 ($_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_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;
    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));
  }

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

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