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

/// Test infrastructure for testing pub.
///
/// Unlike typical unit tests, most pub tests are integration tests that stage
/// some stuff on the file system, run pub, and then validate the results. This
/// library provides an API to build tests like that.
library test_pub;

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';

import 'package:http/testing.dart';
import 'package:path/path.dart' as p;
import 'package:scheduled_test/scheduled_process.dart';
import 'package:scheduled_test/scheduled_server.dart';
import 'package:scheduled_test/scheduled_stream.dart';
import 'package:scheduled_test/scheduled_test.dart' hide fail;
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:unittest/compact_vm_config.dart';
import 'package:yaml/yaml.dart';

import '../lib/src/entrypoint.dart';
import '../lib/src/exit_codes.dart' as exit_codes;
// TODO(rnystrom): Using "gitlib" as the prefix here is ugly, but "git" collides
// with the git descriptor method. Maybe we should try to clean up the top level
// scope a bit?
import '../lib/src/git.dart' as gitlib;
import '../lib/src/http.dart';
import '../lib/src/io.dart';
import '../lib/src/lock_file.dart';
import '../lib/src/log.dart' as log;
import '../lib/src/package.dart';
import '../lib/src/pubspec.dart';
import '../lib/src/source/hosted.dart';
import '../lib/src/source/path.dart';
import '../lib/src/source_registry.dart';
import '../lib/src/system_cache.dart';
import '../lib/src/utils.dart';
import '../lib/src/validator.dart';
import '../lib/src/version.dart';
import 'descriptor.dart' as d;
import 'serve_packages.dart';

export 'serve_packages.dart';

/// This should be called at the top of a test file to set up an appropriate
/// test configuration for the machine running the tests.
initConfig() {
  useCompactVMConfiguration();
  filterStacks = true;
  unittestConfiguration.timeout = null;
}

/// The current [HttpServer] created using [serve].
var _server;

/// The list of paths that have been requested from the server since the last
/// call to [getRequestedPaths].
final _requestedPaths = <String>[];

/// The cached value for [_portCompleter].
Completer<int> _portCompleterCache;

/// A [Matcher] that matches JavaScript generated by dart2js with minification
/// enabled.
Matcher isMinifiedDart2JSOutput =
    isNot(contains("// The code supports the following hooks"));

/// A [Matcher] that matches JavaScript generated by dart2js with minification
/// disabled.
Matcher isUnminifiedDart2JSOutput =
    contains("// The code supports the following hooks");

/// A map from package names to paths from which those packages should be loaded
/// for [createLockFile].
///
/// This allows older versions of dependencies than those that exist in the repo
/// to be used when testing pub.
Map<String, String> _packageOverrides;

/// A map from barback versions to the paths of directories in the repo
/// containing them.
///
/// This includes the latest version of barback from pkg as well as all old
/// versions of barback in third_party.
final _barbackVersions = _findBarbackVersions();

/// Some older barback versions require older versions of barback's dependencies
/// than those that are in the repo.
///
/// This is a map from barback version ranges to the dependencies for those
/// barback versions. Each dependency version listed here should be included in
/// third_party/pkg.
final _barbackDeps = {
  new VersionConstraint.parse("<0.15.0"): {
    "source_maps": "0.9.4"
  }
};

/// Populates [_barbackVersions].
Map<Version, String> _findBarbackVersions() {
  var versions = {};
  var currentBarback = p.join(repoRoot, 'pkg', 'barback');
  versions[new Pubspec.load(currentBarback, new SourceRegistry()).version] =
      currentBarback;

  for (var dir in listDir(p.join(repoRoot, 'third_party', 'pkg'))) {
    var basename = p.basename(dir);
    if (!basename.startsWith('barback')) continue;
    versions[new Version.parse(split1(basename, '-').last)] = dir;
  }

  return versions;
}

/// Runs the tests in [callback] against all versions of barback in the repo
/// that match [versionConstraint].
///
/// This is used to test that pub doesn't accidentally break older versions of
/// barback that it's committed to supporting. Only versions `0.13.0` and later
/// will be tested.
void withBarbackVersions(String versionConstraint, void callback()) {
  var constraint = new VersionConstraint.parse(versionConstraint);

  var validVersions = _barbackVersions.keys.where(constraint.allows);
  if (validVersions.isEmpty) {
    throw new ArgumentError(
        'No available barback version matches "$versionConstraint".');
  }

  for (var version in validVersions) {
    group("with barback $version", () {
      setUp(() {
        _packageOverrides = {};
        _packageOverrides['barback'] = _barbackVersions[version];
        _barbackDeps.forEach((constraint, deps) {
          if (!constraint.allows(version)) return;
          deps.forEach((packageName, version) {
            _packageOverrides[packageName] = p.join(
                repoRoot, 'third_party', 'pkg', '$packageName-$version');
          });
        });

        currentSchedule.onComplete.schedule(() {
          _packageOverrides = null;
        });
      });

      callback();
    });
  }
}

/// The completer for [port].
Completer<int> get _portCompleter {
  if (_portCompleterCache != null) return _portCompleterCache;
  _portCompleterCache = new Completer<int>();
  currentSchedule.onComplete.schedule(() {
    _portCompleterCache = null;
  }, 'clearing the port completer');
  return _portCompleterCache;
}

/// A future that will complete to the port used for the current server.
Future<int> get port => _portCompleter.future;

/// Gets the list of paths that have been requested from the server since the
/// last time this was called (or since the server was first spun up).
Future<List<String>> getRequestedPaths() {
  return schedule(() {
    var paths = _requestedPaths.toList();
    _requestedPaths.clear();
    return paths;
  }, "get previous network requests");
}

/// Creates an HTTP server to serve [contents] as static files.
///
/// This server will exist only for the duration of the pub run. Subsequent
/// calls to [serve] replace the previous server.
void serve([List<d.Descriptor> contents]) {
  var baseDir = d.dir("serve-dir", contents);

  _hasServer = true;

  schedule(() {
    return _closeServer().then((_) {
      return shelf_io.serve((request) {
        currentSchedule.heartbeat();
        var path = p.posix.fromUri(request.url.path.replaceFirst("/", ""));
        _requestedPaths.add(path);

        return validateStream(baseDir.load(path))
            .then((stream) => new shelf.Response.ok(stream))
            .catchError((error) {
          return new shelf.Response.notFound('File "$path" not found.');
        });
      }, 'localhost', 0).then((server) {
        _server = server;
        _portCompleter.complete(_server.port);
        currentSchedule.onComplete.schedule(_closeServer);
      });
    });
  }, 'starting a server serving:\n${baseDir.describe()}');
}

/// Closes [_server].
///
/// Returns a [Future] that completes after the [_server] is closed.
Future _closeServer() {
  if (_server == null) return new Future.value();
  var future = _server.close();
  _server = null;
  _hasServer = false;
  _portCompleterCache = null;
  return future;
}

/// `true` if the current test spins up an HTTP server.
bool _hasServer = false;

/// Converts [value] into a YAML string.
String yaml(value) => JSON.encode(value);

/// The full path to the created sandbox directory for an integration test.
String get sandboxDir => _sandboxDir;
String _sandboxDir;

/// The path to the Dart repo's packages.
final String pkgPath = p.absolute(p.join(
    p.dirname(Platform.executable),
    '../../../../pkg'));

/// The path of the package cache directory used for tests, relative to the
/// sandbox directory.
final String cachePath = "cache";

/// The path of the mock app directory used for tests, relative to the sandbox
/// directory.
final String appPath = "myapp";

/// The path of the packages directory in the mock app used for tests, relative
/// to the sandbox directory.
final String packagesPath = "$appPath/packages";

/// Set to true when the current batch of scheduled events should be aborted.
bool _abortScheduled = false;

/// Enum identifying a pub command that can be run with a well-defined success
/// output.
class RunCommand {
  static final get = new RunCommand('get', new RegExp(
      r'Got dependencies!|Changed \d+ dependenc(y|ies)!'));
  static final upgrade = new RunCommand('upgrade', new RegExp(
      r'(No dependencies changed\.|Changed \d+ dependenc(y|ies)!)$'));
  static final downgrade = new RunCommand('downgrade', new RegExp(
      r'(No dependencies changed\.|Changed \d+ dependenc(y|ies)!)$'));

  final String name;
  final RegExp success;
  RunCommand(this.name, this.success);
}

/// Runs the tests defined within [callback] using both pub get and pub upgrade.
///
/// Many tests validate behavior that is the same between pub get and
/// upgrade have the same behavior. Instead of duplicating those tests, this
/// takes a callback that defines get/upgrade agnostic tests and runs them
/// with both commands.
void forBothPubGetAndUpgrade(void callback(RunCommand command)) {
  group(RunCommand.get.name, () => callback(RunCommand.get));
  group(RunCommand.upgrade.name, () => callback(RunCommand.upgrade));
}

/// Schedules an invocation of pub [command] and validates that it completes
/// in an expected way.
///
/// By default, this validates that the command completes successfully and
/// understands the normal output of a successful pub command. If [warning] is
/// given, it expects the command to complete successfully *and* print
/// [warning] to stderr. If [error] is given, it expects the command to *only*
/// print [error] to stderr. [output], [error], and [warning] may be strings,
/// [RegExp]s, or [Matcher]s.
///
/// If [exitCode] is given, expects the command to exit with that code.
// TODO(rnystrom): Clean up other tests to call this when possible.
void pubCommand(RunCommand command,
    {Iterable<String> args, output, error, warning, int exitCode}) {
  if (error != null && warning != null) {
    throw new ArgumentError("Cannot pass both 'error' and 'warning'.");
  }

  var allArgs = [command.name];
  if (args != null) allArgs.addAll(args);

  if (output == null) output = command.success;

  if (error != null && exitCode == null) exitCode = 1;

  // No success output on an error.
  if (error != null) output = null;
  if (warning != null) error = warning;

  schedulePub(args: allArgs, output: output, error: error, exitCode: exitCode);
}

void pubGet({Iterable<String> args, output, error, warning, int exitCode}) {
  pubCommand(RunCommand.get, args: args, output: output, error: error,
      warning: warning, exitCode: exitCode);
}

void pubUpgrade({Iterable<String> args, output, error, warning, int exitCode}) {
  pubCommand(RunCommand.upgrade, args: args, output: output, error: error,
      warning: warning, exitCode: exitCode);
}

void pubDowngrade({Iterable<String> args, output, error, warning,
    int exitCode}) {
  pubCommand(RunCommand.downgrade, args: args, output: output, error: error,
      warning: warning, exitCode: exitCode);
}

/// Schedules starting the "pub [global] run" process and validates the
/// expected startup output.
///
/// If [global] is `true`, this invokes "pub global run", otherwise it does
/// "pub run".
///
/// Returns the `pub run` process.
ScheduledProcess pubRun({bool global: false, Iterable<String> args}) {
  var pubArgs = global ? ["global", "run"] : ["run"];
  pubArgs.addAll(args);
  var pub = startPub(args: pubArgs);

  // Loading sources and transformers isn't normally printed, but the pub test
  // infrastructure runs pub in verbose mode, which enables this.
  pub.stdout.expect(consumeWhile(startsWith("Loading")));

  return pub;
}

/// Defines an integration test.
///
/// The [body] should schedule a series of operations which will be run
/// asynchronously.
void integration(String description, void body()) =>
  _integration(description, body, test);

/// Like [integration], but causes only this test to run.
void solo_integration(String description, void body()) =>
  _integration(description, body, solo_test);

void _integration(String description, void body(), [Function testFn]) {
  testFn(description, () {
    // TODO(nweiz): remove this when issue 15362 is fixed.
    currentSchedule.timeout *= 2;

    // The windows bots are very slow, so we increase the default timeout.
    if (Platform.operatingSystem == "windows") {
      currentSchedule.timeout *= 2;
    }

    _sandboxDir = createSystemTempDir();
    d.defaultRoot = sandboxDir;
    currentSchedule.onComplete.schedule(() => deleteEntry(_sandboxDir),
        'deleting the sandbox directory');

    // Schedule the test.
    body();
  });
}

/// Get the path to the root "pub/test" directory containing the pub
/// tests.
String get testDirectory =>
  p.absolute(p.dirname(libraryPath('test_pub')));

/// Schedules renaming (moving) the directory at [from] to [to], both of which
/// are assumed to be relative to [sandboxDir].
void scheduleRename(String from, String to) {
  schedule(
      () => renameDir(
          p.join(sandboxDir, from),
          p.join(sandboxDir, to)),
      'renaming $from to $to');
}

/// Schedules creating a symlink at path [symlink] that points to [target],
/// both of which are assumed to be relative to [sandboxDir].
void scheduleSymlink(String target, String symlink) {
  schedule(
      () => createSymlink(
          p.join(sandboxDir, target),
          p.join(sandboxDir, symlink)),
      'symlinking $target to $symlink');
}

/// Schedules a call to the Pub command-line utility.
///
/// Runs Pub with [args] and validates that its results match [output] (or
/// [outputJson]), [error], and [exitCode].
///
/// [output] and [error] can be [String]s, [RegExp]s, or [Matcher]s.
///
/// If [outputJson] is given, validates that pub outputs stringified JSON
/// matching that object, which can be a literal JSON object or any other
/// [Matcher].
void schedulePub({List args, output, error, outputJson,
    Future<Uri> tokenEndpoint, int exitCode: exit_codes.SUCCESS}) {
  // Cannot pass both output and outputJson.
  assert(output == null || outputJson == null);

  var pub = startPub(args: args, tokenEndpoint: tokenEndpoint);
  pub.shouldExit(exitCode);

  var failures = [];
  var stderr;

  expect(Future.wait([
    pub.stdoutStream().toList(),
    pub.stderrStream().toList()
  ]).then((results) {
    var stdout = results[0].join("\n");
    stderr = results[1].join("\n");

    if (outputJson == null) {
      _validateOutput(failures, 'stdout', output, stdout);
      return null;
    }

    // Allow the expected JSON to contain futures.
    return awaitObject(outputJson).then((resolved) {
      _validateOutputJson(failures, 'stdout', resolved, stdout);
    });
  }).then((_) {
    _validateOutput(failures, 'stderr', error, stderr);

    if (!failures.isEmpty) throw new TestFailure(failures.join('\n'));
  }), completes);
}

/// Like [startPub], but runs `pub lish` in particular with [server] used both
/// as the OAuth2 server (with "/token" as the token endpoint) and as the
/// package server.
///
/// Any futures in [args] will be resolved before the process is started.
ScheduledProcess startPublish(ScheduledServer server, {List args}) {
  var tokenEndpoint = server.url.then((url) =>
      url.resolve('/token').toString());
  if (args == null) args = [];
  args = flatten(['lish', '--server', tokenEndpoint, args]);
  return startPub(args: args, tokenEndpoint: tokenEndpoint);
}

/// Handles the beginning confirmation process for uploading a packages.
///
/// Ensures that the right output is shown and then enters "y" to confirm the
/// upload.
void confirmPublish(ScheduledProcess pub) {
  // TODO(rnystrom): This is overly specific and inflexible regarding different
  // test packages. Should validate this a little more loosely.
  pub.stdout.expect(startsWith('Publishing test_pkg 1.0.0 to '));
  pub.stdout.expect(emitsLines(
      "|-- LICENSE\n"
      "|-- lib\n"
      "|   '-- test_pkg.dart\n"
      "'-- pubspec.yaml\n"
      "\n"
      "Looks great! Are you ready to upload your package (y/n)?"));
  pub.writeLine("y");
}

/// Whether the async/await compiler has already been run.
///
/// If a test suite runs pub more than once, we only need to run the compiler
/// the first time.
// TODO(rnystrom): Remove this when #104 is fixed.
bool _compiledAsync = false;

/// Gets the path to the pub entrypoint Dart script to run.
// TODO(rnystrom): This exists to run the async/await compiler on pub and then
// get the path to the output of that. Once #104 is fixed, remove this.
String _getPubPath(String dartBin) {
  var buildDir = p.join(p.dirname(dartBin), '../../');

  // Ensure the async/await compiler has been run once for this test suite. The
  // compiler itself will only re-compile source files that have actually
  // changed, so this is a no-op if everything is already compiled.
  if (!_compiledAsync) {
    var result = Process.runSync(dartBin, [
      '--package-root=$_packageRoot/',
      p.join(testDirectory, '..', 'bin', 'async_compile.dart'),
      buildDir,
      '--silent'
    ]);
    stdout.write(result.stdout);
    stderr.write(result.stderr);
    if (result.exitCode != 0) fail("Async/await compiler failed.");

    _compiledAsync = true;
  }

  return p.join(buildDir, 'pub_async/bin/pub.dart');
}

/// Starts a Pub process and returns a [ScheduledProcess] that supports
/// interaction with that process.
///
/// Any futures in [args] will be resolved before the process is started.
ScheduledProcess startPub({List args, Future<Uri> tokenEndpoint}) {
  String pathInSandbox(String relPath) {
    return p.join(p.absolute(sandboxDir), relPath);
  }

  ensureDir(pathInSandbox(appPath));

  // Find a Dart executable we can use to spawn. Use the same one that was
  // used to run this script itself.
  var dartBin = Platform.executable;

  // If the executable looks like a path, get its full path. That way we
  // can still find it when we spawn it with a different working directory.
  if (dartBin.contains(Platform.pathSeparator)) {
    dartBin = p.absolute(dartBin);
  }

  // Find the main pub entrypoint.
  var pubPath = _getPubPath(dartBin);
  // TODO(rnystrom): Replace the above line with the following when #104 is
  // fixed.
  //var pubPath = p.join(testDirectory, '..', 'bin', 'pub.dart');

  var dartArgs = ['--package-root=$_packageRoot/', '--checked', pubPath,
      '--verbose'];
  dartArgs.addAll(args);

  if (tokenEndpoint == null) tokenEndpoint = new Future.value();
  var environmentFuture = tokenEndpoint.then((tokenEndpoint) {
    var environment = {};
    environment['_PUB_TESTING'] = 'true';
    environment['PUB_CACHE'] = pathInSandbox(cachePath);

    // Ensure a known SDK version is set for the tests that rely on that.
    environment['_PUB_TEST_SDK_VERSION'] = "0.1.2+3";

    if (tokenEndpoint != null) {
      environment['_PUB_TEST_TOKEN_ENDPOINT'] =
        tokenEndpoint.toString();
    }

    // If there is a server running, tell pub what its URL is so hosted
    // dependencies will look there.
    if (_hasServer) {
      return port.then((p) {
        environment['PUB_HOSTED_URL'] = "http://localhost:$p";
        return environment;
      });
    }

    return environment;
  });

  return new PubProcess.start(dartBin, dartArgs, environment: environmentFuture,
      workingDirectory: pathInSandbox(appPath),
      description: args.isEmpty ? 'pub' : 'pub ${args.first}');
}

/// A subclass of [ScheduledProcess] that parses pub's verbose logging output
/// and makes [stdout] and [stderr] work as though pub weren't running in
/// verbose mode.
class PubProcess extends ScheduledProcess {
  Stream<Pair<log.Level, String>> _log;
  Stream<String> _stdout;
  Stream<String> _stderr;

  PubProcess.start(executable, arguments,
      {workingDirectory, environment, String description,
       Encoding encoding: UTF8})
    : super.start(executable, arguments,
        workingDirectory: workingDirectory,
        environment: environment,
        description: description,
        encoding: encoding);

  Stream<Pair<log.Level, String>> _logStream() {
    if (_log == null) {
      _log = mergeStreams(
        _outputToLog(super.stdoutStream(), log.Level.MESSAGE),
        _outputToLog(super.stderrStream(), log.Level.ERROR));
    }

    var pair = tee(_log);
    _log = pair.first;
    return pair.last;
  }

  final _logLineRegExp = new RegExp(r"^([A-Z ]{4})[:|] (.*)$");
  final _logLevels = [
    log.Level.ERROR, log.Level.WARNING, log.Level.MESSAGE, log.Level.IO,
    log.Level.SOLVER, log.Level.FINE
  ].fold(<String, log.Level>{}, (levels, level) {
    levels[level.name] = level;
    return levels;
  });

  Stream<Pair<log.Level, String>> _outputToLog(Stream<String> stream,
      log.Level defaultLevel) {
    var lastLevel;
    return stream.map((line) {
      var match = _logLineRegExp.firstMatch(line);
      if (match == null) return new Pair<log.Level, String>(defaultLevel, line);

      var level = _logLevels[match[1]];
      if (level == null) level = lastLevel;
      lastLevel = level;
      return new Pair<log.Level, String>(level, match[2]);
    });
  }

  Stream<String> stdoutStream() {
    if (_stdout == null) {
      _stdout = _logStream().expand((entry) {
        if (entry.first != log.Level.MESSAGE) return [];
        return [entry.last];
      });
    }

    var pair = tee(_stdout);
    _stdout = pair.first;
    return pair.last;
  }

  Stream<String> stderrStream() {
    if (_stderr == null) {
      _stderr = _logStream().expand((entry) {
        if (entry.first != log.Level.ERROR &&
            entry.first != log.Level.WARNING) {
          return [];
        }
        return [entry.last];
      });
    }

    var pair = tee(_stderr);
    _stderr = pair.first;
    return pair.last;
  }
}

/// The path to the `packages` directory from which pub loads its dependencies.
String get _packageRoot => p.absolute(Platform.packageRoot);

/// Fails the current test if Git is not installed.
///
/// We require machines running these tests to have git installed. This
/// validation gives an easier-to-understand error when that requirement isn't
/// met than just failing in the middle of a test when pub invokes git.
///
/// This also increases the [Schedule] timeout to 30 seconds on Windows,
/// where Git runs really slowly.
void ensureGit() {
  if (Platform.operatingSystem == "windows") {
    currentSchedule.timeout = new Duration(seconds: 30);
  }

  if (!gitlib.isInstalled) {
    throw new Exception("Git must be installed to run this test.");
  }
}

/// Schedules activating a global package [package] without running
/// "pub global activate".
///
/// This is useful because global packages must be hosted, but the test hosted
/// server doesn't serve barback. The other parameters here follow
/// [createLockFile].
void makeGlobalPackage(String package, String version,
    Iterable<d.Descriptor> contents, {Iterable<String> pkg,
    Map<String, String> hosted}) {
  // Start the server so we know what port to use in the cache directory name.
  serveNoPackages();

  // Create the package in the hosted cache.
  d.hostedCache([
    d.dir("$package-$version", contents)
  ]).create();

  var lockFile = _createLockFile(pkg: pkg, hosted: hosted);

  // Add the root package to the lockfile.
  var id = new PackageId(package, "hosted", new Version.parse(version),
      package);
  lockFile.packages[package] = id;

  // Write the lockfile to the global cache.
  var sources = new SourceRegistry();
  sources.register(new HostedSource());
  sources.register(new PathSource());

  d.dir(cachePath, [
    d.dir("global_packages", [
      d.file("$package.lock", lockFile.serialize(null, sources))
    ])
  ]).create();
}

/// Creates a lock file for [package] without running `pub get`.
///
/// [sandbox] is a list of path dependencies to be found in the sandbox
/// directory. [pkg] is a list of packages in the Dart repo's "pkg" directory;
/// each package listed here and all its dependencies will be linked to the
/// version in the Dart repo.
///
/// [hosted] is a list of package names to version strings for dependencies on
/// hosted packages.
void createLockFile(String package, {Iterable<String> sandbox,
    Iterable<String> pkg, Map<String, String> hosted}) {
  var lockFile = _createLockFile(sandbox: sandbox, pkg: pkg, hosted: hosted);

  var sources = new SourceRegistry();
  sources.register(new HostedSource());
  sources.register(new PathSource());

  d.file(p.join(package, 'pubspec.lock'),
      lockFile.serialize(null, sources)).create();
}

/// Creates a lock file for [package] without running `pub get`.
///
/// [sandbox] is a list of path dependencies to be found in the sandbox
/// directory. [pkg] is a list of packages in the Dart repo's "pkg" directory;
/// each package listed here and all its dependencies will be linked to the
/// version in the Dart repo.
///
/// [hosted] is a list of package names to version strings for dependencies on
/// hosted packages.
LockFile _createLockFile({Iterable<String> sandbox,
Iterable<String> pkg, Map<String, String> hosted}) {
  var dependencies = {};

  if (sandbox != null) {
    for (var package in sandbox) {
      dependencies[package] = '../$package';
    }
  }

  if (pkg != null) {
    _addPackage(String package) {
      if (dependencies.containsKey(package)) return;

      var packagePath;
      if (package == 'barback' && _packageOverrides == null) {
        throw new StateError("createLockFile() can only create a lock file "
            "with a barback dependency within a withBarbackVersions() "
            "block.");
      }

      if (_packageOverrides.containsKey(package)) {
        packagePath = _packageOverrides[package];
      } else {
        packagePath = p.join(pkgPath, package);
      }

      dependencies[package] = packagePath;
      var pubspec = loadYaml(
          readTextFile(p.join(packagePath, 'pubspec.yaml')));
      var packageDeps = pubspec['dependencies'];
      if (packageDeps == null) return;
      packageDeps.keys.forEach(_addPackage);
    }

    pkg.forEach(_addPackage);
  }

  var lockFile = new LockFile.empty();
  dependencies.forEach((name, dependencyPath) {
    var id = new PackageId(name, 'path', new Version(0, 0, 0), {
      'path': dependencyPath,
      'relative': p.isRelative(dependencyPath)
    });
    lockFile.packages[name] = id;
  });

  if (hosted != null) {
    hosted.forEach((name, version) {
      var id = new PackageId(name, 'hosted', new Version.parse(version), name);
      lockFile.packages[name] = id;
    });
  }

  return lockFile;
}

/// Uses [client] as the mock HTTP client for this test.
///
/// Note that this will only affect HTTP requests made via http.dart in the
/// parent process.
void useMockClient(MockClient client) {
  var oldInnerClient = innerHttpClient;
  innerHttpClient = client;
  currentSchedule.onComplete.schedule(() {
    innerHttpClient = oldInnerClient;
  }, 'de-activating the mock client');
}

/// Describes a map representing a library package with the given [name],
/// [version], and [dependencies].
Map packageMap(String name, String version, [Map dependencies]) {
  var package = {
    "name": name,
    "version": version,
    "author": "Natalie Weizenbaum <nweiz@google.com>",
    "homepage": "http://pub.dartlang.org",
    "description": "A package, I guess."
  };

  if (dependencies != null) package["dependencies"] = dependencies;

  return package;
}

/// Returns a Map in the format used by the pub.dartlang.org API to represent a
/// package version.
///
/// [pubspec] is the parsed pubspec of the package version. If [full] is true,
/// this returns the complete map, including metadata that's only included when
/// requesting the package version directly.
Map packageVersionApiMap(Map pubspec, {bool full: false}) {
  var name = pubspec['name'];
  var version = pubspec['version'];
  var map = {
    'pubspec': pubspec,
    'version': version,
    'url': '/api/packages/$name/versions/$version',
    'archive_url': '/packages/$name/versions/$version.tar.gz',
    'new_dartdoc_url': '/api/packages/$name/versions/$version'
        '/new_dartdoc',
    'package_url': '/api/packages/$name'
  };

  if (full) {
    map.addAll({
      'downloads': 0,
      'created': '2012-09-25T18:38:28.685260',
      'libraries': ['$name.dart'],
      'uploader': ['nweiz@google.com']
    });
  }

  return map;
}

/// Compares the [actual] output from running pub with [expected].
///
/// If [expected] is a [String], ignores leading and trailing whitespace
/// differences and tries to report the offending difference in a nice way.
///
/// If it's a [RegExp] or [Matcher], just reports whether the output matches.
void _validateOutput(List<String> failures, String pipe, expected,
                     String actual) {
  if (expected == null) return;

  if (expected is String) {
    _validateOutputString(failures, pipe, expected, actual);
  } else {
    if (expected is RegExp) expected = matches(expected);
    expect(actual, expected);
  }
}

void _validateOutputString(List<String> failures, String pipe,
                           String expected, String actual) {
  var actualLines = actual.split("\n");
  var expectedLines = expected.split("\n");

  // Strip off the last line. This lets us have expected multiline strings
  // where the closing ''' is on its own line. It also fixes '' expected output
  // to expect zero lines of output, not a single empty line.
  if (expectedLines.last.trim() == '') {
    expectedLines.removeLast();
  }

  var results = [];
  var failed = false;

  // Compare them line by line to see which ones match.
  var length = max(expectedLines.length, actualLines.length);
  for (var i = 0; i < length; i++) {
    if (i >= actualLines.length) {
      // Missing output.
      failed = true;
      results.add('? ${expectedLines[i]}');
    } else if (i >= expectedLines.length) {
      // Unexpected extra output.
      failed = true;
      results.add('X ${actualLines[i]}');
    } else {
      var expectedLine = expectedLines[i].trim();
      var actualLine = actualLines[i].trim();

      if (expectedLine != actualLine) {
        // Mismatched lines.
        failed = true;
        results.add('X ${actualLines[i]}');
      } else {
        // Output is OK, but include it in case other lines are wrong.
        results.add('| ${actualLines[i]}');
      }
    }
  }

  // If any lines mismatched, show the expected and actual.
  if (failed) {
    failures.add('Expected $pipe:');
    failures.addAll(expectedLines.map((line) => '| $line'));
    failures.add('Got:');
    failures.addAll(results);
  }
}

/// Validates that [actualText] is a string of JSON that matches [expected],
/// which may be a literal JSON object, or any other [Matcher].
void _validateOutputJson(List<String> failures, String pipe,
                         expected, String actualText) {
  var actual;
  try {
    actual = JSON.decode(actualText);
  } on FormatException catch(error) {
    failures.add('Expected $pipe JSON:');
    failures.add(expected);
    failures.add('Got invalid JSON:');
    failures.add(actualText);
  }

  // Match against the expectation.
  expect(actual, expected);
}

/// A function that creates a [Validator] subclass.
typedef Validator ValidatorCreator(Entrypoint entrypoint);

/// Schedules a single [Validator] to run on the [appPath].
///
/// Returns a scheduled Future that contains the errors and warnings produced
/// by that validator.
Future<Pair<List<String>, List<String>>> schedulePackageValidation(
    ValidatorCreator fn) {
  return schedule(() {
    var cache = new SystemCache.withSources(p.join(sandboxDir, cachePath));

    return syncFuture(() {
      var validator = fn(new Entrypoint(p.join(sandboxDir, appPath), cache));
      return validator.validate().then((_) {
        return new Pair(validator.errors, validator.warnings);
      });
    });
  }, "validating package");
}

/// A matcher that matches a Pair.
Matcher pairOf(Matcher firstMatcher, Matcher lastMatcher) =>
   new _PairMatcher(firstMatcher, lastMatcher);

class _PairMatcher extends Matcher {
  final Matcher _firstMatcher;
  final Matcher _lastMatcher;

  _PairMatcher(this._firstMatcher, this._lastMatcher);

  bool matches(item, Map matchState) {
    if (item is! Pair) return false;
    return _firstMatcher.matches(item.first, matchState) &&
        _lastMatcher.matches(item.last, matchState);
  }

  Description describe(Description description) {
    return description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]);
  }
}

/// A [StreamMatcher] that matches multiple lines of output.
StreamMatcher emitsLines(String output) => inOrder(output.split("\n"));
