// 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.

/// Model for a modular test.

/// A modular test declares the structure of the test code: what files are
/// grouped as a module and how modules depend on one another.
class ModularTest {
  /// Modules that will be compiled by for modular test
  final List<Module> modules;

  /// The module containing the main entry method.
  final Module mainModule;

  /// Flags provided to tools that compile and execute the test.
  final List<String> flags;

  ModularTest(this.modules, this.mainModule, this.flags) {
    if (modules.isEmpty) throw ArgumentError("modules cannot be empty");
    for (var module in modules) {
      module._validate();
    }
  }

  String debugString() => modules.map((m) => m.debugString()).join('\n');
}

/// A single module in a modular test.
class Module {
  /// A short name to identify this module.
  final String name;

  /// Other modules that need to be compiled first and whose result may be
  /// necessary in order to compile this module.
  final List<Module> dependencies;

  /// Root under which all sources in the module can be found.
  final Uri rootUri;

  /// Source files that are part of this module only. Stored as a relative [Uri]
  /// from [rootUri].
  final List<Uri> sources;

  /// The file containing the main entry method, if any. Stored as a relative
  /// [Uri] from [rootUri].
  final Uri? mainSource;

  /// Whether this module is also available as a package import, where the
  /// package name matches the module name.
  bool isPackage;

  /// Whether this module represents part of the sdk.
  bool isSdk;

  /// When [isPackage], the base where all package URIs are resolved against.
  /// Stored as a relative [Uri] from [rootUri].
  final Uri? packageBase;

  /// Whether this is the main entry module of a test.
  bool isMain;

  /// Whether this module is test specific or shared across tests. Usually this
  /// will be true only for the SDK and shared packages like `package:expect`.
  bool isShared;

  Module(this.name, this.dependencies, this.rootUri, this.sources,
      {this.mainSource,
      this.isPackage = false,
      this.isMain = false,
      this.packageBase,
      this.isShared = false,
      this.isSdk = false}) {
    if (!_validModuleName.hasMatch(name)) {
      throw ArgumentError("invalid module name: $name");
    }
  }

  void _validate() {
    if (!isPackage && !isShared && !isSdk) return;

    // Note: we validate this now and not in the constructor because loader.dart
    // may update `isPackage` after the module is created.
    if (isSdk && isPackage) {
      throw InvalidModularTestError("invalid module: $name is an sdk "
          "module but was also marked as a package module.");
    }

    for (var dependency in dependencies) {
      if (isPackage && !dependency.isPackage && !dependency.isSdk) {
        throw InvalidModularTestError("invalid dependency: $name is a package "
            "but it depends on ${dependency.name}, which is not.");
      }
      if (isShared && !dependency.isShared) {
        throw InvalidModularTestError(
            "invalid dependency: $name is a shared module "
            "but it depends on ${dependency.name}, which is not.");
      }
      if (isSdk) {
        // TODO(sigmund): we should allow to split sdk modules in smaller
        // pieces. This requires a bit of work:
        // - allow to compile subsets of the sdk (see #30957 regarding
        //   extraRequiredLibraries in CFE)
        // - add logic to specify sdk dependencies.
        throw InvalidModularTestError(
            "invalid dependency: $name is an sdk module that depends on  "
            "${dependency.name}, but sdk modules are not expected to "
            "have dependencies.");
      }
    }
  }

  @override
  String toString() => '[module $name]';

  String debugString() {
    var buffer = StringBuffer();
    buffer.write('   ');
    buffer.write(name);
    buffer.write(': ');
    buffer.write(isPackage ? 'package' : '(not package)');
    buffer.write(', deps: {${dependencies.map((d) => d.name).join(", ")}}');
    if (isSdk) {
      buffer.write(', sources: {...omitted ${sources.length} sources...}');
    } else {
      buffer.write(', sources: {${sources.map((u) => "$u").join(', ')}}');
    }
    return '$buffer';
  }
}

final RegExp _validModuleName = RegExp(r'^[a-zA-Z_][a-zA-Z0-9_]*$');

/// Helper to compute transitive dependencies from [module].
Set<Module> computeTransitiveDependencies(Module module) {
  Set<Module> deps = {};
  helper(Module m) {
    if (deps.add(m)) m.dependencies.forEach(helper);
  }

  module.dependencies.forEach(helper);
  return deps;
}

/// A registry that can map a test configuration to a simple id.
///
/// This is used to help determine whether two tests are run with the same set
/// of flags (the same configuration), and thus pipelines could reuse the
/// results of shared modules from the first test when running the second test.
class ConfigurationRegistry {
  Map<String, int> _configurationId = {};

  /// Compute an id to identify the configuration of a modular test.
  ///
  /// A configuration is defined in terms of the set of flags provided to a
  /// test. If two test provided to this registry share the same set of flags,
  /// the resulting ids are the same. Similarly, if the flags are different,
  /// their ids will be different as well.
  int computeConfigurationId(ModularTest test) {
    return _configurationId[test.flags.join(' ')] ??= _configurationId.length;
  }
}

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