// 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 to read a test specification from a Yaml
/// file. We expect specifications written in this format:
///
///    dependencies:
///      b: a
///      main: [b, expect]
///    flags:
///      - constant-update-2018
///    packages:
///      c: .
///      a: a
///
///
/// Where:
///   - the dependencies section describe how modules depend on one another,
///   - the flags section show what flags are needed to run that specific test,
///   - the packages section is used to create a package structure on top of the
///     declared modules.
///
/// When defining dependencies:
///   - Each name corresponds to a module.
///   - Module names correlate to either a file, a folder, or a package.
///   - A map entry contains all the dependencies of a module, if any.
///   - If a module has a single dependency, it can be written as a single
///     value.
///
/// When defining packages:
///   - The name corresponds to a package name, this doesn't need to match
///     the name of the module. That said, it's common for some modules
///     and packages to share their name (especially for the default set of
///     packages included by the framework, like package:expect).
///   - The value is a path to the folder containing the libraries of that
///     package.
///
/// The packages entry is optional.  If this is not specified, the test will
/// still have a default set of packages, like package:expect and package:meta.
/// If the packages entry is specified, it will be extended with the definitions
/// of the default set of packages as well. Thus, the list of packages provided
/// is expected to be disjoint with those in the default set. The default set is
/// defined directly in the code of `loader.dart`.
///
/// The logic in this library mostly treats these names as strings, separately
/// `loader.dart` is responsible for validating, attaching dependency
/// information to a set of module definitions, and resolving package paths.
///
/// The framework is agnostic of what the flags are, but at this time we only
/// use the name of experimental language features. These are then used to
/// decide what options to pass to the tools that compile and run the tests.
import 'package:yaml/yaml.dart';

/// Parses [contents] containing a module dependencies specification written in
/// yaml, and returns a [TestSpecification].
TestSpecification parseTestSpecification(String contents) {
  var spec = loadYaml(contents);
  if (spec is! YamlMap) {
    return _invalidSpecification("spec is not a map");
  }
  var dependencies = spec['dependencies'];
  if (dependencies == null) {
    return _invalidSpecification("no dependencies section");
  }
  if (dependencies is! YamlMap) {
    return _invalidSpecification("dependencies is not a map");
  }

  Map<String, List<String>> normalizedMap = {};
  dependencies.forEach((key, value) {
    if (key is! String) {
      _invalidSpecification("key: '$key' is not a string");
    }
    final values = normalizedMap[key] = [];
    if (value is String) {
      values.add(value);
    } else if (value is List) {
      for (var entry in value) {
        if (entry is! String) {
          _invalidSpecification("entry: '$entry' is not a string");
        }
        values.add(entry);
      }
    } else {
      _invalidSpecification(
          "entry: '$value' is not a string or a list of strings");
    }
  });

  List<String> normalizedFlags = [];
  dynamic flags = spec['flags'];
  if (flags is String) {
    normalizedFlags.add(flags);
  } else if (flags is List) {
    normalizedFlags.addAll(flags.cast<String>());
  } else if (flags != null) {
    _invalidSpecification(
        "flags: '$flags' expected to be string or list of strings");
  }

  Map<String, String> normalizedPackages = {};
  final packages = spec['packages'];
  if (packages != null) {
    if (packages is Map) {
      normalizedPackages.addAll(packages.cast<String, String>());
    } else {
      _invalidSpecification("packages is not a map");
    }
  }
  return TestSpecification(normalizedFlags, normalizedMap, normalizedPackages);
}

/// Data specifying details about a modular test including dependencies and
/// flags that are necessary in order to properly run a test.
///
class TestSpecification {
  /// Set of flags necessary to properly run a test.
  ///
  /// Usually this contains flags enabling language experiments.
  final List<String> flags;

  /// Dependencies of the modules that are expected to exist on the test.
  ///
  /// Note: some values in the map may not have a corresponding key. That may be
  /// the case for modules that have no dependencies and modules that are not
  /// specified explicitly because they are added automatically by the framework
  /// (for instance, the module of `package:expect` or the sdk itself).
  final Map<String, List<String>> dependencies;

  /// Map of package name to a relative path.
  ///
  /// The paths in this map are meant to be resolved relative to the location
  /// where this test specification was defined.
  final Map<String, String> packages;

  TestSpecification(this.flags, this.dependencies, this.packages);
}

_invalidSpecification(String message) {
  throw InvalidSpecificationError(message);
}

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