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

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

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

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