// Copyright (c) 2019, 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.

/// This library defines how `modular_test` converts the contents of a folder
/// into a modular test. At this time, the logic in this library assumes this is
/// only used within the Dart SDK repo.
///
/// A modular test folder contains:
///   * individual .dart files, each file is considered a module. A
///   `main.dart` file is required as the entry point of the test.
///   * subfolders: each considered a module with multiple files
///   * a modules.yaml file: a specification of dependencies between modules.
///     The format is described in `test_specification_parser.dart`.
library;

import 'dart:io';
import 'suite.dart';
import 'test_specification_parser.dart';
import 'find_sdk_root.dart';

/// Returns the [ModularTest] associated with a folder under [uri].
///
/// After scanning the contents of the folder, this method creates a
/// [ModularTest] that contains only modules that are reachable from the main
/// module.  This method runs several validations including that modules don't
/// have conflicting names, that the default packages are always visible, and
/// that modules do not contain cycles.
Future<ModularTest> loadTest(Uri uri) async {
  var folder = Directory.fromUri(uri);
  var testUri = folder.uri; // normalized in case the trailing '/' was missing.
  Uri root = await findRoot();
  final defaultTestSpecification = parseTestSpecification(_defaultPackagesSpec);
  Set<String> defaultPackages = defaultTestSpecification.packages.keys.toSet();
  Module sdkModule = await _createSdkModule(root);
  Map<String, Module> modules = {'sdk': sdkModule};
  String? specString;
  Module? mainModule;
  var entries = folder.listSync(recursive: false).toList()
    // Sort to avoid dependency on file system order.
    ..sort(_compareFileSystemEntity);
  for (var entry in entries) {
    var entryUri = entry.uri;
    if (entry is File) {
      var fileName = entryUri.path.substring(testUri.path.length);
      if (fileName.endsWith('.dart')) {
        var moduleName = fileName.substring(0, fileName.indexOf('.dart'));
        if (moduleName == 'sdk') {
          return _invalidTest("The file '$fileName' defines a module called "
              "'$moduleName' which conflicts with the sdk module "
              "that is provided by default.");
        }
        if (defaultPackages.contains(moduleName)) {
          return _invalidTest("The file '$fileName' defines a module called "
              "'$moduleName' which conflicts with a package by the same name "
              "that is provided by default.");
        }
        if (modules.containsKey(moduleName)) {
          return _moduleConflict(fileName, modules[moduleName]!, testUri);
        }
        var relativeUri = Uri.parse(fileName);
        var isMain = moduleName == 'main';
        var module = Module(moduleName, [], testUri, [relativeUri],
            mainSource: isMain ? relativeUri : null,
            isMain: isMain,
            packageBase: Uri.parse('.'));
        if (isMain) mainModule = module;
        modules[moduleName] = module;
      } else if (fileName == 'modules.yaml') {
        specString = await entry.readAsString();
      }
    } else {
      assert(entry is Directory);
      var path = entryUri.path;
      var moduleName = path.substring(testUri.path.length, path.length - 1);
      if (moduleName == 'sdk') {
        return _invalidTest("The folder '$moduleName' defines a module "
            "which conflicts with the sdk module "
            "that is provided by default.");
      }
      if (defaultPackages.contains(moduleName)) {
        return _invalidTest("The folder '$moduleName' defines a module "
            "which conflicts with a package by the same name "
            "that is provided by default.");
      }
      if (modules.containsKey(moduleName)) {
        return _moduleConflict(moduleName, modules[moduleName]!, testUri);
      }
      var sources = await _listModuleSources(entryUri);
      modules[moduleName] = Module(moduleName, [], testUri, sources,
          packageBase: Uri.parse('$moduleName/'));
    }
  }
  if (specString == null) {
    return _invalidTest("modules.yaml file is missing");
  }
  if (mainModule == null) {
    return _invalidTest("main module is missing");
  }

  TestSpecification spec = parseTestSpecification(specString);
  for (final name in defaultPackages) {
    if (spec.packages.containsKey(name)) {
      _invalidTest(
          ".packages file defines a conflicting entry for package '$name'.");
    }
  }
  await _addModulePerPackage(defaultTestSpecification.packages, root, modules);
  await _addModulePerPackage(spec.packages, testUri, modules);
  _attachDependencies(spec.dependencies, modules);
  _attachDependencies(defaultTestSpecification.dependencies, modules);
  _addSdkDependencies(modules, sdkModule);
  _detectCyclesAndRemoveUnreachable(modules, mainModule);
  var sortedModules = modules.values.toList()
    ..sort((a, b) => a.name.compareTo(b.name));
  var sortedFlags = spec.flags.toList()..sort();
  return ModularTest(sortedModules, mainModule, sortedFlags);
}

/// Returns all source files recursively found in a folder as relative URIs.
Future<List<Uri>> _listModuleSources(Uri root) async {
  List<Uri> sources = [];
  Directory folder = Directory.fromUri(root);
  int baseUriPrefixLength = folder.parent.uri.path.length;
  await for (var file in folder.list(recursive: true)) {
    var path = file.uri.path;
    if (path.endsWith('.dart')) {
      sources.add(Uri.parse(path.substring(baseUriPrefixLength)));
    }
  }
  return sources..sort((a, b) => a.path.compareTo(b.path));
}

/// Add links between modules based on the provided dependency map.
void _attachDependencies(
    Map<String, List<String>> dependencies, Map<String, Module> modules) {
  dependencies.forEach((name, moduleDependencies) {
    final module = modules[name];
    if (module == null) {
      _invalidTest(
          "declared dependencies for a nonexistent module named '$name'");
    }
    if (module.dependencies.isNotEmpty) {
      _invalidTest("Module dependencies have already been declared on $name.");
    }
    for (var dependencyName in moduleDependencies) {
      final moduleDependency = modules[dependencyName];
      if (moduleDependency == null) {
        _invalidTest("'$name' declares a dependency on a nonexistent module "
            "named '$dependencyName'");
      }
      module.dependencies.add(moduleDependency);
    }
  });
}

/// Make every module depend on the sdk module.
void _addSdkDependencies(Map<String, Module> modules, Module sdkModule) {
  for (var module in modules.values) {
    if (module != sdkModule) {
      module.dependencies.add(sdkModule);
    }
  }
}

/// Create a module for each package dependency.
Future<void> _addModulePerPackage(Map<String, String> packages, Uri configRoot,
    Map<String, Module> modules) async {
  for (var packageName in packages.keys) {
    var module = modules[packageName];
    if (module != null) {
      module.isPackage = true;
    } else {
      var packageLibUri = configRoot.resolve(packages[packageName]!);
      var packageRootUri = Directory.fromUri(packageLibUri).parent.uri;
      var sources = await _listModuleSources(packageLibUri);
      // TODO(sigmund): validate that we don't use a different alias for a
      // module that is part of the test (package name and module name should
      // match).
      modules[packageName] = Module(packageName, [], packageRootUri, sources,
          isPackage: true, packageBase: Uri.parse('lib/'), isShared: true);
    }
  }
}

Future<Module> _createSdkModule(Uri root) async {
  List<Uri> sources = [
    Uri.parse('sdk/lib/libraries.json'),
  ];

  // Include all dart2js, ddc, vm library sources and patch files.
  // Note: we don't extract the list of files from the libraries.json because
  // it doesn't list files that are transitively imported.
  var sdkLibrariesAndPatchesRoots = [
    'sdk/lib/',
    'runtime/lib/',
    'runtime/bin/',
  ];
  for (var path in sdkLibrariesAndPatchesRoots) {
    var dir = Directory.fromUri(root.resolve(path));
    await for (var file in dir.list(recursive: true)) {
      if (file is File && file.path.endsWith(".dart")) {
        sources.add(Uri.parse(file.uri.path.substring(root.path.length)));
      }
    }
  }
  sources.sort((a, b) => a.path.compareTo(b.path));
  return Module('sdk', [], root, sources, isSdk: true, isShared: true);
}

/// Trim the set of modules, and detect cycles while we are at it.
void _detectCyclesAndRemoveUnreachable(
    Map<String, Module> modules, Module main) {
  Set<Module> visiting = {};
  Set<Module> visited = {};

  helper(Module current) {
    if (!visiting.add(current)) {
      _invalidTest("module '${current.name}' has a dependency cycle.");
    }
    if (visited.add(current)) {
      current.dependencies.forEach(helper);
    }
    visiting.remove(current);
  }

  helper(main);
  Set<String> toKeep = visited.map((m) => m.name).toSet();
  List<String> toRemove =
      modules.keys.where((name) => !toKeep.contains(name)).toList();
  toRemove.forEach(modules.remove);
}

/// Specifies the dependencies of all packages in [_defaultPackagesInput]. This
/// string needs to be updated if dependencies between those packages changes
/// (which is rare).
// TODO(sigmund): consider either computing this from the pubspec files or the
// import graph, or adding tests that validate this is always up to date.
String _defaultPackagesSpec = '''
dependencies:
  expect: [meta, smith]
  smith: []
  meta: []
  collection: []
packages:
  expect: pkg/expect/lib
  smith: pkg/smith/lib
  meta: pkg/meta/lib
  collection: third_party/pkg/core/pkgs/collection/lib
''';

/// Report an conflict error.
Never _moduleConflict(String name, Module existing, Uri root) {
  var isFile = name.endsWith('.dart');
  var entryType = isFile ? 'file' : 'folder';

  var existingIsFile =
      existing.packageBase!.path == './' && existing.sources.length == 1;
  var existingEntryType = existingIsFile ? 'file' : 'folder';

  var existingName = existingIsFile
      ? existing.sources.single.pathSegments.last
      : existing.name;

  return _invalidTest("The $entryType '$name' defines a module "
      "which conflicts with the module defined by the $existingEntryType "
      "'$existingName'.");
}

Never _invalidTest(String message) {
  throw InvalidTestError(message);
}

class InvalidTestError extends Error {
  final String message;
  InvalidTestError(this.message);
  @override
  String toString() => "Invalid test: $message";
}

/// Comparator to sort directories before files.
int _compareFileSystemEntity(FileSystemEntity a, FileSystemEntity b) {
  if (a is Directory) {
    if (b is Directory) {
      return a.path.compareTo(b.path);
    } else {
      return -1;
    }
  } else {
    if (b is Directory) {
      return 1;
    } else {
      return a.path.compareTo(b.path);
    }
  }
}
