// 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/navigation_tree_renderer.dart';
import 'package:nnbd_migration/src/front_end/path_mapper.dart';
import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'nnbd_migration_test_base.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(NavigationTreeRendererTest);
  });
}

const isNavigationTreeDirectoryNode =
    TypeMatcher<NavigationTreeDirectoryNode>();

const isNavigationTreeFileNode = TypeMatcher<NavigationTreeFileNode>();

@reflectiveTest
class NavigationTreeRendererTest extends NnbdMigrationTestBase {
  PathMapper? pathMapper;

  /// Render the navigation tree view for [files].
  Future<List<NavigationTreeNode>> renderNavigationTree(
      Map<String, String> files) async {
    await buildInfoForTestFiles(files, includedRoot: projectPath);
    var migrationInfo =
        MigrationInfo(infos, {}, resourceProvider.pathContext, projectPath);
    pathMapper = PathMapper(resourceProvider);
    return NavigationTreeRenderer(migrationInfo, pathMapper).render();
  }

  Future<void> test_containsEditCounts() async {
    var response = await renderNavigationTree({
      convertPath('$projectPath/lib/a.dart'): 'int a = 1;',
      convertPath('$projectPath/lib/b.dart'): 'int b = null;',
      convertPath('$projectPath/lib/c.dart'): 'int c = null;\nint d = null;',
    });

    var libNode = response[0] as NavigationTreeDirectoryNode;
    expect(
        libNode,
        isNavigationTreeDirectoryNode.havingSubtree([
          isNavigationTreeFileNode.havingEditCount(0),
          isNavigationTreeFileNode.havingEditCount(1),
          isNavigationTreeFileNode.havingEditCount(2)
        ]));
  }

  Future<void> test_containsHrefs() async {
    var response = await renderNavigationTree({
      convertPath('$projectPath/lib/a.dart'): 'int a = null;',
      convertPath('$projectPath/lib/src/b.dart'): 'int b = null;',
      convertPath('$projectPath/tool.dart'): 'int c = null;',
    });

    var libNode = response[0];
    expect(
        libNode,
        isNavigationTreeDirectoryNode.named('lib').havingSubtree([
          isNavigationTreeDirectoryNode.named('src').havingSubtree([
            isNavigationTreeFileNode.havingHref(
                '$projectPath/lib/src/b.dart', pathMapper!)
          ]),
          isNavigationTreeFileNode.havingHref(
              '$projectPath/lib/a.dart', pathMapper!)
        ]));

    var toolNode = response[1] as NavigationTreeFileNode;
    expect(
        toolNode.href, pathMapper!.map(convertPath('$projectPath/tool.dart')));
  }

  Future<void> test_containsMultipleLinks_multipleDepths() async {
    var response = await renderNavigationTree({
      convertPath('$projectPath/lib/a.dart'): 'int a = null;',
      convertPath('$projectPath/lib/src/b.dart'): 'int b = null;',
      convertPath('$projectPath/tool.dart'): 'int c = null;',
    });
    expect(response, hasLength(2));

    var libNode = response[0];
    expect(
        libNode,
        isNavigationTreeDirectoryNode.named('lib').havingSubtree([
          isNavigationTreeDirectoryNode
              .named('src')
              .havingSubtree([isNavigationTreeFileNode.named('b.dart')]),
          isNavigationTreeFileNode.named('a.dart')
        ]));

    var toolNode = response[1];
    expect(toolNode.name, 'tool.dart');
  }

  Future<void> test_containsMultipleLinks_multipleRoots() async {
    var response = await renderNavigationTree({
      convertPath('$projectPath/bin/bin.dart'): 'int c = null;',
      convertPath('$projectPath/lib/a.dart'): 'int a = null;',
    });
    expect(response, hasLength(2));

    var binNode = response[0] as NavigationTreeDirectoryNode;
    expect(binNode.type, equals(NavigationTreeNodeType.directory));
    expect(binNode.name, equals('bin'));
    expect(binNode.subtree, hasLength(1));

    var libNode = response[1] as NavigationTreeDirectoryNode;
    expect(libNode.type, equals(NavigationTreeNodeType.directory));
    expect(libNode.name, equals('lib'));
    expect(libNode.subtree, hasLength(1));
  }

  Future<void> test_containsMultipleLinks_sameDepth() async {
    var response = await renderNavigationTree({
      convertPath('$projectPath/lib/a.dart'): 'int a = null;',
      convertPath('$projectPath/lib/b.dart'): 'int b = null;',
    });
    expect(response, hasLength(1));

    var libNode = response[0];
    expect(
        libNode,
        isNavigationTreeDirectoryNode.named('lib').havingSubtree([
          isNavigationTreeFileNode
              .named('a.dart')
              .havingPath(convertPath('lib/a.dart'))
              .havingHref('$projectPath/lib/a.dart', pathMapper!),
          isNavigationTreeFileNode
              .named('b.dart')
              .havingPath(convertPath('lib/b.dart'))
              .havingHref('$projectPath/lib/b.dart', pathMapper!)
        ]));
  }

  Future<void> test_containsPaths() async {
    var response = await renderNavigationTree({
      convertPath('$projectPath/lib/a.dart'): 'int a = null;',
      convertPath('$projectPath/lib/src/b.dart'): 'int b = null;',
      convertPath('$projectPath/tool.dart'): 'int c = null;',
    });

    var libNode = response[0];
    expect(
        libNode,
        isNavigationTreeDirectoryNode.named('lib').havingSubtree([
          isNavigationTreeDirectoryNode.named('src').havingSubtree([
            isNavigationTreeFileNode.havingPath(convertPath('lib/src/b.dart'))
          ]),
          isNavigationTreeFileNode.havingPath(convertPath('lib/a.dart'))
        ]));

    var toolNode = response[1];
    expect(toolNode.path, 'tool.dart');
  }

  Future<void> test_containsSingleLink_deep() async {
    var response = await renderNavigationTree({
      convertPath('$projectPath/lib/src/a.dart'): 'int a = null;',
    });
    expect(response, hasLength(1));

    var libNode = response[0];
    expect(
        libNode,
        isNavigationTreeDirectoryNode.named('lib').havingSubtree([
          isNavigationTreeDirectoryNode.named('src').havingSubtree([
            isNavigationTreeFileNode
                .named('a.dart')
                .havingPath(convertPath('lib/src/a.dart'))
                .havingHref('$projectPath/lib/src/a.dart', pathMapper!)
          ])
        ]));
  }

  Future<void> test_containsSingleLink_shallow() async {
    var response = await renderNavigationTree({
      convertPath('$projectPath/a.dart'): 'int a = null;',
    });
    expect(response, hasLength(1));

    var aNode = response[0] as NavigationTreeFileNode;
    expect(aNode.name, 'a.dart');
    expect(aNode.path, 'a.dart');
    expect(aNode.href, pathMapper!.map(convertPath('$projectPath/a.dart')));
  }

  Future<void> test_migrationStatus_directory_allMigrated() async {
    var response = await renderNavigationTree({
      convertPath('$projectPath/lib/a.dart'): 'int a = null;',
      convertPath('$projectPath/lib/src/b.dart'): 'int b = null;',
    });

    var libNode = response[0] as NavigationTreeDirectoryNode;
    ((libNode.subtree![0] as NavigationTreeDirectoryNode).subtree![0]
            as NavigationTreeFileNode)
        .migrationStatus = UnitMigrationStatus.alreadyMigrated;
    (libNode.subtree![1] as NavigationTreeFileNode).migrationStatus =
        UnitMigrationStatus.alreadyMigrated;
    expect(
        libNode,
        isNavigationTreeDirectoryNode
            .named('lib')
            .havingMigrationStatus(UnitMigrationStatus.alreadyMigrated)
            .havingSubtree([
          isNavigationTreeDirectoryNode
              .named('src')
              .havingMigrationStatus(UnitMigrationStatus.alreadyMigrated),
          isNavigationTreeFileNode
        ]));
  }

  Future<void> test_migrationStatus_directory_allMigrating() async {
    var response = await renderNavigationTree({
      convertPath('$projectPath/lib/a.dart'): 'int a = null;',
      convertPath('$projectPath/lib/src/b.dart'): 'int b = null;',
    });

    var libNode = response[0];
    expect(
        libNode,
        isNavigationTreeDirectoryNode
            .named('lib')
            .havingMigrationStatus(UnitMigrationStatus.migrating)
            .havingSubtree([
          isNavigationTreeDirectoryNode
              .named('src')
              .havingMigrationStatus(UnitMigrationStatus.migrating),
          isNavigationTreeFileNode
        ]));
  }

  Future<void> test_migrationStatus_directory_allOptingOut() async {
    var response = await renderNavigationTree({
      convertPath('$projectPath/lib/a.dart'): 'int a = null;',
      convertPath('$projectPath/lib/src/b.dart'): 'int b = null;',
    });

    var libNode = response[0] as NavigationTreeDirectoryNode;
    ((libNode.subtree![0] as NavigationTreeDirectoryNode).subtree![0]
            as NavigationTreeFileNode)
        .migrationStatus = UnitMigrationStatus.optingOut;
    (libNode.subtree![1] as NavigationTreeFileNode).migrationStatus =
        UnitMigrationStatus.optingOut;
    expect(
        libNode,
        isNavigationTreeDirectoryNode
            .named('lib')
            .havingMigrationStatus(UnitMigrationStatus.optingOut)
            .havingSubtree([
          isNavigationTreeDirectoryNode
              .named('src')
              .havingMigrationStatus(UnitMigrationStatus.optingOut),
          isNavigationTreeFileNode
        ]));
  }

  Future<void> test_migrationStatus_directory_mixedInAndOut() async {
    var response = await renderNavigationTree({
      convertPath('$projectPath/lib/a.dart'): 'int a = null;',
      convertPath('$projectPath/lib/src/b.dart'): 'int b = null;',
      convertPath('$projectPath/lib/src/c.dart'): 'int b = null;',
    });

    var libNode = response[0] as NavigationTreeDirectoryNode;
    var libSrcNode = libNode.subtree![0] as NavigationTreeDirectoryNode;
    (libSrcNode.subtree![0] as NavigationTreeFileNode).migrationStatus =
        UnitMigrationStatus.optingOut;
    expect(
        libNode,
        isNavigationTreeDirectoryNode
            .named('lib')
            .havingMigrationStatus(UnitMigrationStatus.indeterminate)
            .havingSubtree([
          isNavigationTreeDirectoryNode
              .named('src')
              .havingMigrationStatus(UnitMigrationStatus.indeterminate),
          isNavigationTreeFileNode
        ]));
  }

  Future<void> test_migrationStatus_directory_mixedInAndOutAndMigrated() async {
    var response = await renderNavigationTree({
      convertPath('$projectPath/lib/a.dart'): 'int a = null;',
      convertPath('$projectPath/lib/src/b.dart'): 'int b = null;',
      convertPath('$projectPath/lib/src/c.dart'): 'int b = null;',
    });

    var libNode = response[0] as NavigationTreeDirectoryNode;
    var libSrcNode = libNode.subtree![0] as NavigationTreeDirectoryNode;
    (libSrcNode.subtree![0] as NavigationTreeFileNode).migrationStatus =
        UnitMigrationStatus.optingOut;
    (libSrcNode.subtree![1] as NavigationTreeFileNode).migrationStatus =
        UnitMigrationStatus.alreadyMigrated;
    expect(
        libNode,
        isNavigationTreeDirectoryNode
            .named('lib')
            .havingMigrationStatus(UnitMigrationStatus.indeterminate)
            .havingSubtree([
          isNavigationTreeDirectoryNode
              .named('src')
              .havingMigrationStatus(UnitMigrationStatus.optingOut),
          isNavigationTreeFileNode
        ]));
  }

  Future<void> test_migrationStatus_file() async {
    var response = await renderNavigationTree({
      convertPath('$projectPath/lib/a.dart'): 'int a = 1;',
      convertPath('$projectPath/lib/b.dart'): '// @dart=2.9\nint b = null;',
    });

    var libNode = response[0] as NavigationTreeDirectoryNode;
    expect(
        libNode,
        isNavigationTreeDirectoryNode.havingSubtree([
          isNavigationTreeFileNode
              .havingMigrationStatus(UnitMigrationStatus.migrating),
          isNavigationTreeFileNode
              .havingMigrationStatus(UnitMigrationStatus.migrating),
        ]));
  }
}

extension<T extends NavigationTreeNode> on TypeMatcher<T> {
  TypeMatcher<T> named(dynamic matcher) =>
      having((node) => node.name, 'name', matcher);

  TypeMatcher<T> havingMigrationStatus(dynamic matcher) =>
      having((node) => node.migrationStatus, 'migrationStatus', matcher);
}

extension on TypeMatcher<NavigationTreeDirectoryNode> {
  TypeMatcher<NavigationTreeDirectoryNode> havingSubtree(dynamic matcher) =>
      having((node) => node.subtree, 'subtree', matcher);
}

extension on TypeMatcher<NavigationTreeFileNode> {
  TypeMatcher<NavigationTreeFileNode> havingEditCount(dynamic matcher) =>
      having((node) => node.editCount, 'editCount', matcher);

  //TypeMatcher<NavigationTreeFileNode> named(dynamic matcher) =>
  //    having((node) => node.name, 'name', matcher);

  TypeMatcher<NavigationTreeFileNode> havingHref(
          String path, PathMapper pathMapper) =>
      having((node) => node.href, 'href', pathMapper.map(path));

  TypeMatcher<NavigationTreeFileNode> havingPath(dynamic matcher) =>
      having((node) => node.path, 'path', matcher);
}
