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

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.LOOPBACK_IP_V4, 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.NOT_FOUND
                        ..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;
}
