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

// @dart = 2.9

import "dart:async";
import "dart:io";
import "dart:convert" show json;
import "package:path/path.dart" as p;
import "package:async_helper/async_helper.dart";

/// Root directory of generated files.
/// Path contains trailing slash.
/// Each configuration gets its own sub-directory.
Directory fileRoot;

/// Shared HTTP server serving the files in [httpFiles].
/// Each configuration gets its own "sub-dir" entry in `httpFiles`.
HttpServer httpServer;

/// Directory structure served by HTTP server.
Map<String, dynamic> httpFiles = {};

/// List of configurations.
List<Configuration> configurations = [];

/// Collection of failing tests and their failure messages.
///
/// Each test may fail in more than one way.
var failingTests = <String, List<String>>{};

main() async {
  asyncStart();
  await setUp();

  await runTests(); //                         //# 01: ok
  await runTests([spawn]); //                  //# 02: ok
  await runTests([spawn, spawn]); //           //# 03: ok
  await runTests([spawnUriInherit]); //        //# 04: ok
  await runTests([spawnUriInherit, spawn]); // //# 05: ok
  await runTests([spawn, spawnUriInherit]); // //# 06: ok

  // Test that spawning a new VM with file paths instead of URIs as arguments
  // gives the same URIs in the internal values.
  await runTests([asPath]); //                 //# 07: ok

  // Test that spawnUri can reproduce the behavior of VM command line parameters
  // exactly.
  // (Don't run all configuration combinations in the same test, so
  // unroll the configurations into multiple groups and run each group
  // as its own multitest.
  {
    var groupCount = 8;
    var groups = new List.generate(8, (_) => []);
    for (int i = 0; i < configurations.length; i++) {
      groups[i % groupCount].add(configurations[i]);
    }
    var group = -1;
    group = 0; //                              //# 10: ok
    group = 1; //                              //# 11: ok
    group = 2; //                              //# 12: ok
    group = 3; //                              //# 13: ok
    group = 4; //                              //# 14: ok
    group = 5; //                              //# 15: ok
    group = 6; //                              //# 16: ok
    group = 7; //                              //# 17: ok
    if (group >= 0) {
      for (var other in groups[group]) {
        await runTests([spawnUriOther(other)]);
      }
    }
  }

  await tearDown();

  if (failingTests.isNotEmpty) {
    print("Errors found in tests:");
    failingTests.forEach((test, actual) {
      print("$test:\n  ${actual.join("\n  ")}");
    });
    exit(255);
  }

  asyncEnd();
}

/// Test running the test of the configuration through [Isolate.spawn].
///
/// This should not change the expected results compared to running it
/// directly.
Configuration spawn(Configuration conf) {
  return conf.update(
      description: conf.description + "/spawn",
      main: "spawnMain",
      newArgs: [conf.mainType],
      expect: null);
}

/// Tests running a spawnUri on top of the configuration before testing.
///
/// The `spawnUri` call has no explicit root or config parameter, and
/// shouldn't search for one, so it implicitly inherits the current isolate's
/// actual root or configuration.
Configuration spawnUriInherit(Configuration conf) {
  if (conf.expect["iroot"] == null &&
      conf.expect["iconf"] == null &&
      conf.expect["pconf"] != null) {
    // This means that the specified configuration file didn't exist.
    // spawning a new URI to "inherit" that will actually do an automatic
    // package resolution search with results that are unpredictable.
    // That behavior will be tested in a setting where we have more control over
    // the files around the spawned URI.
    return null;
  }
  return conf.update(
      description: conf.description + "/spawnUri-inherit",
      main: "spawnUriMain",
      // encode null parameters as "-". Windows fails if using empty string.
      newArgs: [
        conf.mainFile,
        "-",
        "-",
        "false"
      ],
      expect: {
        "proot": conf.expect["iroot"],
        "pconf": conf.expect["iconf"],
      });
}

/// Tests running a spawnUri with an explicit configuration different
/// from the original configuration.
///
/// Duplicates the explicit parameters as arguments to the spawned isolate.
ConfigurationTransformer spawnUriOther(Configuration other) {
  return (Configuration conf) {
    bool search = (other.config == null) && (other.root == null);
    return conf.update(
        description: "${conf.description} -spawnUri-> ${other.description}",
        main: "spawnUriMain",
        newArgs: [
          other.mainFile,
          other.config ?? "-",
          other.root ?? "-",
          "$search"
        ],
        expect: other.expect);
  };
}

/// Convert command line parameters to file paths.
///
/// This only works on the command line, not with `spawnUri`.
Configuration asPath(Configuration conf) {
  bool change = false;

  String toPath(String string) {
    if (string == null) return null;
    if (string.startsWith("file:")) {
      change = true;
      return new File.fromUri(Uri.parse(string)).path;
    }
    return string;
  }

  var mainFile = toPath(conf.mainFile);
  var root = toPath(conf.root);
  var config = toPath(conf.config);
  if (!change) return null;
  return conf.update(
      description: conf.description + "/as path",
      mainFile: mainFile,
      root: root,
      config: config);
}

/// --------------------------------------------------------------

Future setUp() async {
  fileRoot = createTempDir();
  // print("FILES: $fileRoot");
  httpServer = await startServer(httpFiles);
  // print("HTTPS: ${httpServer.address.address}:${httpServer.port}");
  createConfigurations();
}

Future tearDown() async {
  fileRoot.deleteSync(recursive: true);
  await httpServer.close();
}

typedef Configuration ConfigurationTransformer(Configuration conf);

Future runTests([List<ConfigurationTransformer> transformations]) async {
  outer:
  for (var config in configurations) {
    if (transformations != null) {
      for (int i = transformations.length - 1; i >= 0; i--) {
        config = transformations[i](config);
        if (config == null) {
          continue outer; // Can be used to skip some tests.
        }
      }
    }
    await testConfiguration(config);
  }
}

// Creates a combination of configurations for running the Dart VM.
//
// The combinations covers most configurations of implicit and explicit
// package configurations over both file: and http: file sources.
// It also specifies the expected values of the following for a VM
// run in that configuration.
//
// * `Process.packageRoot`
// * `Process.packageConfig`
// * `Isolate.packageRoot`
// * `Isolate.packageRoot`
// * `Isolate.resolvePackageUri` of various inputs.
// * A variable defined in a library loaded using a `package:` URI.
//
// The configurations all have URIs as `root`, `config` and `mainFile` strings,
// have empty argument lists and `mainFile` points to the `main.dart` file.
void createConfigurations() {
  add(String description, String mainDir,
      {String root, String config, Map file, Map http, Map expect}) {
    var id = freshName("conf");

    file ??= {};
    http ??= {};

    // Fix-up paths.
    String fileUri = fileRoot.uri.resolve("$id/").toString();
    String httpUri =
        "http://${httpServer.address.address}:${httpServer.port}/$id/";

    String fixPath(String path) {
      return path?.replaceAllMapped(fileHttpRegexp, (match) {
        if (path.startsWith("%file/", match.start)) return fileUri;
        return httpUri;
      });
    }

    void fixPaths(Map dirs) {
      for (var name in dirs.keys) {
        var value = dirs[name];
        if (value is Map) {
          Map subDir = value;
          fixPaths(subDir);
        } else {
          var newValue = fixPath(value);
          if (newValue != value) dirs[name] = newValue;
        }
      }
    }

    if (!mainDir.endsWith("/")) mainDir += "/";
    // Insert main files into the main-dir map.
    Map mainDirMap;
    {
      if (mainDir.startsWith("%file/")) {
        mainDirMap = file;
      } else {
        mainDirMap = http;
      }
      var parts = mainDir.split('/');
      for (int i = 1; i < parts.length - 1; i++) {
        var dirName = parts[i];
        mainDirMap = mainDirMap[dirName] ?? (mainDirMap[dirName] = {});
      }
    }

    mainDirMap["main"] = testMain;
    mainDirMap["spawnMain"] = spawnMain.replaceAll("%mainDir/", mainDir);
    mainDirMap["spawnUriMain"] = spawnUriMain;

    mainDir = fixPath(mainDir);
    root = fixPath(root);
    config = fixPath(config);
    fixPaths(file);
    fixPaths(http);
    // These expectations are default. If not overridden the value will be
    // expected to be null. That is, you can't avoid testing the actual
    // value of these, you can only change what value to expect.
    // For values not included here (commented out), the result is not tested
    // unless a value (maybe null) is provided.
    fixPaths(expect);

    expect = {
      "pconf": null,
      "proot": null,
      "iconf": null,
      "iroot": null,
      "foo": null,
      "foo/": null,
      "foo/bar": null,
      "foo.x": "qux",
      "bar/bar": null,
      "relative": "relative/path",
      "nonpkg": "http://example.org/file"
    }..addAll(expect ?? const {});

    // Add http files to the http server.
    if (http.isNotEmpty) {
      httpFiles[id] = http;
    }
    // Add file files to the file system.
    if (file.isNotEmpty) {
      createFiles(fileRoot, id, file);
    }

    configurations.add(new Configuration(
        description: description,
        root: root,
        config: config,
        mainFile: mainDir + "main.dart",
        args: const [],
        expect: expect));
  }

  // The `test` function can generate file or http resources.
  // It replaces "%file/" with URI of the root directory of generated files and
  // "%http/" with the URI of the HTTP server's root in appropriate contexts
  // (all file contents and parameters).

  // Tests that only use one scheme to access files.
  for (var scheme in ["file", "http"]) {
    /// Run a test in the current scheme.
    ///
    /// The files are served either through HTTP or in a local directory.
    /// Use "%$scheme/" to refer to the root of the served files.
    addScheme(description, main, {expect, files, args, root, config}) {
      add("$scheme/$description", main,
          expect: expect,
          root: root,
          config: config,
          file: (scheme == "file") ? files : null,
          http: (scheme == "http") ? files : null);
    }

    {
      // No parameters, no .packages files or packages/ dir.
      // A "file:" source realizes there is no configuration and can't resolve
      // any packages, but a "http:" source assumes a "packages/" directory.
      addScheme("no resolution", "%$scheme/",
          files: {},
          expect: (scheme == "file")
              ? {"foo.x": null}
              : {
                  "iroot": "%http/packages/",
                  "foo": "%http/packages/foo",
                  "foo/": "%http/packages/foo/",
                  "foo/bar": "%http/packages/foo/bar",
                  "foo.x": null,
                  "bar/bar": "%http/packages/bar/bar",
                });
    }

    {
      // No parameters, no .packages files,
      // packages/ dir exists and is detected.
      var files = {"packages": fooPackage};
      addScheme("implicit packages dir", "%$scheme/", files: files, expect: {
        "iroot": "%$scheme/packages/",
        "foo": "%$scheme/packages/foo",
        "foo/": "%$scheme/packages/foo/",
        "foo/bar": "%$scheme/packages/foo/bar",
        "bar/bar": "%$scheme/packages/bar/bar",
      });
    }

    {
      // No parameters, no .packages files in current dir, but one in parent,
      // packages/ dir exists and is used.
      //
      // Should not detect the .packages file in parent directory.
      // That file is empty, so if it is used, the system cannot resolve "foo".
      var files = {
        "sub": {"packages": fooPackage},
        ".packages": ""
      };
      addScheme(
          "implicit packages dir overrides parent .packages", "%$scheme/sub/",
          files: files,
          expect: {
            "iroot": "%$scheme/sub/packages/",
            "foo": "%$scheme/sub/packages/foo",
            "foo/": "%$scheme/sub/packages/foo/",
            "foo/bar": "%$scheme/sub/packages/foo/bar",
            // "foo.x": "qux",  // Blocked by issue http://dartbug.com/26482
            "bar/bar": "%$scheme/sub/packages/bar/bar",
          });
    }

    {
      // No parameters, a .packages file next to entry is found and used.
      // A packages/ directory is ignored.
      var files = {
        ".packages": "foo:pkgs/foo/",
        "packages": {},
        "pkgs": fooPackage
      };
      addScheme("implicit .packages file", "%$scheme/", files: files, expect: {
        "iconf": "%$scheme/.packages",
        "foo/": "%$scheme/pkgs/foo/",
        "foo/bar": "%$scheme/pkgs/foo/bar",
      });
    }

    {
      // No parameters, a .packages file in parent dir, no packages/ dir.
      // With a file: URI, find the .packages file.
      // WIth a http: URI, assume a packages/ dir.
      var files = {"sub": {}, ".packages": "foo:pkgs/foo/", "pkgs": fooPackage};
      addScheme(".packages file in parent", "%$scheme/sub/",
          files: files,
          expect: (scheme == "file")
              ? {
                  "iconf": "%file/.packages",
                  "foo/": "%file/pkgs/foo/",
                  "foo/bar": "%file/pkgs/foo/bar",
                }
              : {
                  "iroot": "%http/sub/packages/",
                  "foo": "%http/sub/packages/foo",
                  "foo/": "%http/sub/packages/foo/",
                  "foo/bar": "%http/sub/packages/foo/bar",
                  "foo.x": null,
                  "bar/bar": "%http/sub/packages/bar/bar",
                });
    }

    {
      // Specified package root that doesn't exist.
      // Ignores existing .packages file and packages/ dir.
      addScheme("explicit root not there", "%$scheme/",
          files: {
            "packages": fooPackage,
            ".packages": "foo:%$scheme/packages/"
          },
          root: "%$scheme/notthere/",
          expect: {
            "proot": "%$scheme/notthere/",
            "iroot": "%$scheme/notthere/",
            "foo": "%$scheme/notthere/foo",
            "foo/": "%$scheme/notthere/foo/",
            "foo/bar": "%$scheme/notthere/foo/bar",
            "foo.x": null,
            "bar/bar": "%$scheme/notthere/bar/bar",
          });
    }

    {
      // Specified package config that doesn't exist.
      // Ignores existing .packages file and packages/ dir.
      addScheme("explicit config not there", "%$scheme/",
          files: {".packages": "foo:packages/foo/", "packages": fooPackage},
          config: "%$scheme/.notthere",
          expect: {
            "pconf": "%$scheme/.notthere",
            "iconf": null, //   <- Only there if actually loaded (unspecified).
            "foo/": null,
            "foo/bar": null,
            "foo.x": null,
          });
    }

    {
      // Specified package root with no trailing slash.
      // The Platform.packageRoot and Isolate.packageRoot has a trailing slash.
      var files = {
        ".packages": "foo:packages/foo/",
        "packages": {},
        "pkgs": fooPackage
      };
      addScheme("explicit package root, no slash", "%$scheme/",
          files: files,
          root: "%$scheme/pkgs",
          expect: {
            "proot": "%$scheme/pkgs/",
            "iroot": "%$scheme/pkgs/",
            "foo": "%$scheme/pkgs/foo",
            "foo/": "%$scheme/pkgs/foo/",
            "foo/bar": "%$scheme/pkgs/foo/bar",
            "bar/bar": "%$scheme/pkgs/bar/bar",
          });
    }

    {
      // Specified package root with trailing slash.
      var files = {
        ".packages": "foo:packages/foo/",
        "packages": {},
        "pkgs": fooPackage
      };
      addScheme("explicit package root, slash", "%$scheme/",
          files: files,
          root: "%$scheme/pkgs",
          expect: {
            "proot": "%$scheme/pkgs/",
            "iroot": "%$scheme/pkgs/",
            "foo": "%$scheme/pkgs/foo",
            "foo/": "%$scheme/pkgs/foo/",
            "foo/bar": "%$scheme/pkgs/foo/bar",
            "bar/bar": "%$scheme/pkgs/bar/bar",
          });
    }

    {
      // Specified package config.
      var files = {
        ".packages": "foo:packages/foo/",
        "packages": {},
        ".pkgs": "foo:pkgs/foo/",
        "pkgs": fooPackage
      };
      addScheme("explicit package config file", "%$scheme/",
          files: files,
          config: "%$scheme/.pkgs",
          expect: {
            "pconf": "%$scheme/.pkgs",
            "iconf": "%$scheme/.pkgs",
            "foo/": "%$scheme/pkgs/foo/",
            "foo/bar": "%$scheme/pkgs/foo/bar",
          });
    }

    {
      // Specified package config as data: URI.
      // The package config can be specified as a data: URI.
      // (In that case, relative URI references in the config file won't work).
      var files = {
        ".packages": "foo:packages/foo/",
        "packages": {},
        "pkgs": fooPackage
      };
      var dataUri = "data:,foo:%$scheme/pkgs/foo/\n";
      addScheme("explicit data: config file", "%$scheme/",
          files: files,
          config: dataUri,
          expect: {
            "pconf": dataUri,
            "iconf": dataUri,
            "foo/": "%$scheme/pkgs/foo/",
            "foo/bar": "%$scheme/pkgs/foo/bar",
          });
    }
  }

  // Tests where there are files on both http: and file: sources.

  for (var entryScheme in const ["file", "http"]) {
    for (var pkgScheme in const ["file", "http"]) {
      // Package root.
      if (entryScheme != pkgScheme) {
        // Package dir and entry point on different schemes.
        var files = {};
        var https = {};
        (entryScheme == "file" ? files : https)["main"] = testMain;
        (pkgScheme == "file" ? files : https)["pkgs"] = fooPackage;
        add("$pkgScheme pkg/$entryScheme main", "%$entryScheme/",
            file: files,
            http: https,
            root: "%$pkgScheme/pkgs/",
            expect: {
              "proot": "%$pkgScheme/pkgs/",
              "iroot": "%$pkgScheme/pkgs/",
              "foo": "%$pkgScheme/pkgs/foo",
              "foo/": "%$pkgScheme/pkgs/foo/",
              "foo/bar": "%$pkgScheme/pkgs/foo/bar",
              "bar/bar": "%$pkgScheme/pkgs/bar/bar",
              "foo.x": "qux",
            });
      }
      // Package config. The configuration file may also be on either source.
      for (var configScheme in const ["file", "http"]) {
        // Don't do the boring stuff!
        if (entryScheme == configScheme && entryScheme == pkgScheme) continue;
        // Package config, packages and entry point not all on same scheme.
        var files = {};
        var https = {};
        (entryScheme == "file" ? files : https)["main"] = testMain;
        (configScheme == "file" ? files : https)[".pkgs"] =
            "foo:%$pkgScheme/pkgs/foo/\n";
        (pkgScheme == "file" ? files : https)["pkgs"] = fooPackage;
        add("$pkgScheme pkg/$configScheme config/$entryScheme main",
            "%$entryScheme/",
            file: files,
            http: https,
            config: "%$configScheme/.pkgs",
            expect: {
              "pconf": "%$configScheme/.pkgs",
              "iconf": "%$configScheme/.pkgs",
              "foo/": "%$pkgScheme/pkgs/foo/",
              "foo/bar": "%$pkgScheme/pkgs/foo/bar",
              "foo.x": "qux",
            });
      }
    }
  }
}

// ---------------------------------------------------------
// Helper functionality.

var fileHttpRegexp = new RegExp(r"%(?:file|http)/");

// Executes a test in a configuration.
//
// The test must specify which main file to use
// (`main`, `spawnMain` or `spawnUriMain`)
// and any arguments which will be used by `spawnMain` and `spawnUriMain`.
//
// The [expect] map may be used to override the expectations of the
// configuration on a value-by-value basis. Passing, e.g., `{"pconf": null}`
// will override only the `pconf` (`Platform.packageConfig`) expectation.
Future testConfiguration(Configuration conf) async {
  print("-- ${conf.description}");
  var description = conf.description;
  try {
    var output = await execDart(conf.mainFile,
        root: conf.root, config: conf.config, scriptArgs: conf.args);
    match(json.decode(output), conf.expect, description, output);
  } catch (e, s) {
    // Unexpected error calling execDart or parsing the result.
    // Report it and continue.
    print("ERROR running $description: $e\n$s");
    failingTests.putIfAbsent(description, () => []).add("$e");
  }
}

/// Test that the output of running testMain matches the expectations.
///
/// The output is a string which is parse as a JSON literal.
/// The resulting map is always mapping strings to strings, or possibly `null`.
/// The expectations can have non-string values other than null,
/// they are `toString`'ed  before being compared (so the caller can use a URI
/// or a File/Directory directly as an expectation).
void match(Map actuals, Map expectations, String desc, String actualJson) {
  for (var key in expectations.keys) {
    var expectation = expectations[key]?.toString();
    var actual = actuals[key];
    if (expectation != actual) {
      print("ERROR: $desc: $key: Expected: <$expectation> Found: <$actual>");
      failingTests
          .putIfAbsent(desc, () => [])
          .add("$key: $expectation != $actual");
    }
  }
}

const String improt = "import"; // Avoid multitest import rewriting.

/// Script that prints the current state and the result of resolving
/// a few package URIs. This script will be invoked in different settings,
/// and the result will be parsed and compared to the expectations.
const String testMain = """
$improt "dart:convert" show json;
$improt "dart:io" show Platform, Directory;
$improt "dart:isolate" show Isolate;
$improt "package:foo/foo.dart" deferred as foo;
main(_) async {
  String platformRoot = await Platform.packageRoot;
  String platformConfig = await Platform.packageConfig;
  Directory cwd = Directory.current;
  Uri script = Platform.script;
  Uri isolateRoot = await Isolate.packageRoot;
  Uri isolateConfig = await Isolate.packageConfig;
  Uri base = Uri.base;
  Uri res1 = await Isolate.resolvePackageUri(Uri.parse("package:foo"));
  Uri res2 = await Isolate.resolvePackageUri(Uri.parse("package:foo/"));
  Uri res3 = await Isolate.resolvePackageUri(Uri.parse("package:foo/bar"));
  Uri res4 = await Isolate.resolvePackageUri(Uri.parse("package:bar/bar"));
  Uri res5 = await Isolate.resolvePackageUri(Uri.parse("relative/path"));
  Uri res6 = await Isolate.resolvePackageUri(
      Uri.parse("http://example.org/file"));
  String fooX = await foo
    .loadLibrary()
    .timeout(const Duration(seconds: 1))
    .then((_) => foo.x, onError: (_) => null);
  print(json.encode({
    "cwd": cwd.path,
    "base": base?.toString(),
    "script": script?.toString(),
    "proot": platformRoot,
    "pconf": platformConfig,
    "iroot" : isolateRoot?.toString(),
    "iconf" : isolateConfig?.toString(),
    "foo": res1?.toString(),
    "foo/": res2?.toString(),
    "foo/bar": res3?.toString(),
    "foo.x": fooX?.toString(),
    "bar/bar": res4?.toString(),
    "relative": res5?.toString(),
    "nonpkg": res6?.toString(),
  }));
}
""";

/// Script that spawns a new Isolate using Isolate.spawnUri.
///
/// Takes URI of target isolate, package config, package root and
/// automatic package resolution-flag parameters as command line arguments.
/// Any further arguments are forwarded to the spawned isolate.
const String spawnUriMain = """
$improt "dart:isolate";
$improt "dart:async";
main(args) async {
  Uri target = Uri.parse(args[0]);
  Uri config = (args[1] == "-") ? null : Uri.parse(args[1]);
  Uri root = (args[2] == "-") ? null : Uri.parse(args[2]);
  bool search = args[3] == "true";
  var restArgs = args.skip(4).toList();
  // Port keeps isolate alive until spawned isolate terminates.
  var port = new RawReceivePort();
  port.handler = (res) async {
    port.close();  // Close on exit or first error.
    if (res != null) {
      await new Future.error(res[0], new StackTrace.fromString(res[1]));
    }
  };
  Isolate.spawnUri(target, restArgs, null,
                   packageRoot: root, packageConfig: config,
                   automaticPackageResolution: search,
                   onError: port.sendPort, onExit: port.sendPort);
}
""";

/// Script that spawns a new Isolate using Isolate.spawn.
///
/// Uses the first argument to select which target to spawn.
/// Should be either "test", "uri" or "spawn".
const String spawnMain = """
$improt "dart:async";
$improt "dart:isolate";
$improt "%mainDir/main.dart" as test;
$improt "%mainDir/spawnUriMain.dart" as spawnUri;
main(List<String> args) async {
  // Port keeps isolate alive until spawned isolate terminates.
  var port = new RawReceivePort();
  port.handler = (res) async {
    port.close();  // Close on exit or first error.
    if (res != null) {
      await new Future.error(res[0], new StackTrace.fromString(res[1]));
    }
  };
  var arg = args.first;
  var rest = args.skip(1).toList();
  var target;
  if (arg == "main") {
    target = test.main;
  } else if (arg == "spawnUriMain") {
    target = spawnUri.main;
  } else {
    target = main;
  }
  Isolate.spawn(target, rest, onError: port.sendPort, onExit: port.sendPort);
}
""";

/// A package directory containing only one package, "foo", with one file.
const Map fooPackage = const {
  "foo": const {"foo": "var x = 'qux';"}
};

/// Runs the Dart executable with the provided parameters.
///
/// Captures and returns the output.
Future<String> execDart(String script,
    {String root, String config, Iterable<String> scriptArgs}) async {
  var checked = false;
  assert((checked = true));
  // TODO: Find a way to change CWD before running script.
  var executable = Platform.executable;
  var args = [];
  if (checked) args.add("--checked");
  if (root != null) args.add("--package-root=$root");
  if (config != null) args.add("--packages=$config");
  args.add(script);
  if (scriptArgs != null) {
    args.addAll(scriptArgs);
  }
  return Process.run(executable, args).then((results) {
    if (results.exitCode != 0 || results.stderr.isNotEmpty) {
      throw results.stderr;
    }
    return results.stdout;
  });
}

/// Creates a number of files and subdirectories.
///
/// The [content] is the content of the directory itself. The map keys are
/// names and the values are either strings that represent Dart file contents
/// or maps that represent subdirectories.
void createFiles(Directory tempDir, String subDir, Map content) {
  Directory createDir(Directory base, String name) {
    Directory newDir = new Directory(p.join(base.path, name));
    newDir.createSync();
    return newDir;
  }

  void createTextFile(Directory base, String name, String content) {
    File newFile = new File(p.join(base.path, name));
    newFile.writeAsStringSync(content);
  }

  void createRecursive(Directory dir, Map map) {
    for (var name in map.keys) {
      var content = map[name];
      if (content is String) {
        // If the name starts with "." it's a .packages file, otherwise it's
        // a dart file. Those are the only files we care about in this test.
        createTextFile(
            dir, name.startsWith(".") ? name : name + ".dart", content);
      } else {
        assert(content is Map);
        var subdir = createDir(dir, name);
        createRecursive(subdir, content);
      }
    }
  }

  createRecursive(createDir(tempDir, subDir), content);
}

/// Start an HTTP server which serves a directory/file structure.
///
/// The directories and files are described by [files].
///
/// Each map key is an entry in a directory. A `Map` value is a sub-directory
/// and a `String` value is a text file.
/// The file contents are run through [fixPaths] to allow them to be self-
/// referential.
Future<HttpServer> startServer(Map files) async {
  return (await HttpServer.bind(InternetAddress.loopbackIPv4, 0))
    ..forEach((request) {
      var result = files;
      onFailure:
      {
        for (var part in request.uri.pathSegments) {
          if (part.endsWith(".dart")) {
            part = part.substring(0, part.length - 5);
          }
          if (result is Map) {
            result = result[part];
          } else {
            break onFailure;
          }
        }
        if (result is String) {
          request.response
            ..write(result)
            ..close();
          return;
        }
      }
      request.response
        ..statusCode = HttpStatus.notFound
        ..close();
    });
}

// Counter used to avoid reusing temporary file or directory names.
//
// Used when adding extra files to an existing directory structure,
// and when creating temporary directories.
//
// Some platform temporary-directory implementations are timer based,
// and creating two temp-dirs withing a short duration may cause a collision.
int tmpNameCounter = 0;

// Fresh file name.
String freshName([String base = "tmp"]) => "$base${tmpNameCounter++}";

Directory createTempDir() {
  return Directory.systemTemp.createTempSync(freshName("pftest-"));
}

typedef void ConfigUpdate(Configuration configuration);

/// The configuration for a single test.
class Configuration {
  /// The "description" of the test - a description of the set-up.
  final String description;

  /// The package root parameter passed to the Dart isolate.
  ///
  /// At most one of [root] and [config] should be supplied. If both are
  /// omitted, a VM will search for a packages file or dir.
  final String root;

  /// The package configuration file location passed to the Dart isolate.
  final String config;

  /// Path to the main file to run.
  final String mainFile;

  /// List of arguments to pass to the main function.
  final List<String> args;

  /// The expected values for `Platform.package{Root,Config}`,
  /// `Isolate.package{Root,Config}` and resolution of package URIs
  /// in a `foo` package.
  ///
  /// The results are found by running the `main.dart` file inside [mainDir].
  /// The tests can run this file after doing other `spawn` or `spawnUri` calls.
  final Map expect;

  Configuration(
      {this.description,
      this.root,
      this.config,
      this.mainFile,
      this.args,
      this.expect});

  // Gets the type of main file, one of `main`, `spawnMain` or `spawnUriMain`.
  String get mainType {
    var lastSlash = mainFile.lastIndexOf("/");
    if (lastSlash < 0) {
      // Assume it's a Windows path.
      lastSlash = mainFile.lastIndexOf(r"\");
    }
    var name = mainFile.substring(lastSlash + 1, mainFile.length - 5);
    assert(name == "main" || name == "spawnMain" || name == "spawnUriMain");
    return name;
  }

  String get mainPath {
    var lastSlash = mainFile.lastIndexOf("/");
    if (lastSlash < 0) {
      // Assume it's a Windows path.
      lastSlash = mainFile.lastIndexOf(r"\");
    }
    return mainFile.substring(0, lastSlash + 1);
  }

  /// Create a new configuration from the old one.
  ///
  /// [description] is new description.
  ///
  /// [main] is one of `main`, `spawnMain` or `spawnUriMain`, and changes
  /// the [Configuration.mainFile] to a different file in the same directory.
  ///
  /// [mainFile] overrides [Configuration.mainFile] completely, and ignores
  /// [main].
  ///
  /// [newArgs] are prepended to the existing [Configuration.args].
  ///
  /// [args] overrides [Configuration.args] completely and ignores [newArgs].
  ///
  /// [expect] overrides individual expectations.
  ///
  /// [root] and [config] overrides the existing values.
  Configuration update(
      {String description,
      String main,
      String mainFile,
      String root,
      String config,
      List<String> args,
      List<String> newArgs,
      Map expect}) {
    return new Configuration(
        description: description ?? this.description,
        root: root ?? this.root,
        config: config ?? this.config,
        mainFile: mainFile ??
            ((main == null) ? this.mainFile : "${this.mainPath}$main.dart"),
        args: args ??
            (<String>[]
              ..addAll(newArgs ?? const <String>[])
              ..addAll(this.args)),
        expect: expect == null ? this.expect : new Map.from(this.expect)
          ..addAll(expect ?? const {}));
  }

  // For debugging.
  String toString() {
    return "Configuration($description\n"
        "  root  : $root\n"
        "  config: $config\n"
        "  main  : $mainFile\n"
        "  args  : ${args.map((x) => '"$x"').join(" ")}\n"
        ") : expect {\n${expect.keys.map((k) => '  "$k"'.padRight(6) + ":${json.encode(expect[k])}\n").join()}"
        "}";
  }
}

// Inserts the file with generalized [name] at [path] with [content].
//
// The [path] is a directory where the file is created. It must start with
// either '%file/' or '%http/' to select the structure to put it into.
//
// The [name] should not have a trailing ".dart" for Dart files. Any file
// not starting with "." is assumed to be a ".dart" file.
void insertFileAt(
    Map file, Map http, String path, String name, String content) {
  var parts = path.split('/').toList();
  var dir = (parts[0] == "%file") ? file : http;
  for (var i = 1; i < parts.length - 1; i++) {
    var entry = parts[i];
    dir = dir[entry] ?? (dir[entry] = {});
  }
  dir[name] = content;
}
