// 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.
import 'dart:convert';
import 'dart:core';
import 'dart:io';
import 'dart:isolate';
import 'dart:math';

import 'package:async/async.dart';
import 'package:http/testing.dart';
import 'package:path/path.dart' as p;
import 'package:pub/src/entrypoint.dart';
import 'package:pub/src/exit_codes.dart' as exit_codes;
import 'package:pub/src/git.dart' as git;
import 'package:pub/src/http.dart';
import 'package:pub/src/io.dart';
import 'package:pub/src/lock_file.dart';
import 'package:pub/src/log.dart' as log;
import 'package:pub/src/package_name.dart';
import 'package:pub/src/system_cache.dart';
import 'package:pub/src/utils.dart';
import 'package:pub/src/validator.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:test/test.dart' hide fail;
import 'package:test/test.dart' as test show fail;
import 'package:test_process/test_process.dart';

import 'descriptor.dart' as d;
import 'package_server.dart';

export 'package_server.dart' show PackageServer;

/// 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');

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

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

/// The path of the config directory used for tests, relative to the
/// sandbox directory.
const String configPath = '.config';

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

/// The path of the ".dart_tool/package_config.json" file in the mock app used
/// for tests, relative to the sandbox directory.
String packageConfigFilePath =
    p.join(appPath, '.dart_tool', 'package_config.json');

/// The entry from the `.dart_tool/package_config.json` file for [packageName].
Map<String, dynamic> packageSpec(String packageName) => json
    .decode(File(d.path(packageConfigFilePath)).readAsStringSync())['packages']
    .firstWhere((e) => e['name'] == packageName,
        orElse: () => null) as Map<String, dynamic>;

/// The suffix appended to a built snapshot.
const versionSuffix = testVersion;

/// Enum identifying a pub command that can be run with a well-defined success
/// output.
class RunCommand {
  static final add = RunCommand(
      'add', RegExp(r'Got dependencies!|Changed \d+ dependenc(y|ies)!'));
  static final get = RunCommand(
      'get', RegExp(r'Got dependencies!|Changed \d+ dependenc(y|ies)!'));
  static final upgrade = RunCommand('upgrade', RegExp(r'''
(No dependencies changed\.|Changed \d+ dependenc(y|ies)!)($|
\d+ packages? (has|have) newer versions incompatible with dependency constraints.
Try `dart pub outdated` for more information.$)'''));
  static final downgrade = RunCommand('downgrade',
      RegExp(r'(No dependencies changed\.|Changed \d+ dependenc(y|ies)!)$'));
  static final remove = RunCommand(
      'remove', RegExp(r'Got dependencies!|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 Function(RunCommand) callback) {
  group(RunCommand.get.name, () => callback(RunCommand.get));
  group(RunCommand.upgrade.name, () => callback(RunCommand.upgrade));
}

/// Invokes the 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], [silent], 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.
Future<void> pubCommand(
  RunCommand command, {
  Iterable<String>? args,
  Object? output,
  Object? error,
  Object? silent,
  Object? warning,
  int? exitCode,
  Map<String, String?>? environment,
  String? workingDirectory,
  includeParentHomeAndPath = true,
}) async {
  if (error != null && warning != null) {
    throw ArgumentError("Cannot pass both 'error' and 'warning'.");
  }

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

  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;

  await runPub(
      args: allArgs,
      output: output,
      error: error,
      silent: silent,
      exitCode: exitCode,
      environment: environment,
      workingDirectory: workingDirectory,
      includeParentHomeAndPath: includeParentHomeAndPath);
}

Future<void> pubAdd({
  Iterable<String>? args,
  Object? output,
  Object? error,
  Object? warning,
  int? exitCode,
  Map<String, String>? environment,
  String? workingDirectory,
}) async =>
    await pubCommand(
      RunCommand.add,
      args: args,
      output: output,
      error: error,
      warning: warning,
      exitCode: exitCode,
      environment: environment,
      workingDirectory: workingDirectory,
    );

Future<void> pubGet({
  Iterable<String>? args,
  Object? output,
  Object? error,
  Object? silent,
  Object? warning,
  int? exitCode,
  Map<String, String?>? environment,
  String? workingDirectory,
  bool includeParentHomeAndPath = true,
}) async =>
    await pubCommand(
      RunCommand.get,
      args: args,
      output: output,
      error: error,
      silent: silent,
      warning: warning,
      exitCode: exitCode,
      environment: environment,
      workingDirectory: workingDirectory,
      includeParentHomeAndPath: includeParentHomeAndPath,
    );

Future<void> pubUpgrade(
        {Iterable<String>? args,
        Object? output,
        Object? error,
        Object? warning,
        int? exitCode,
        Map<String, String>? environment,
        String? workingDirectory}) async =>
    await pubCommand(
      RunCommand.upgrade,
      args: args,
      output: output,
      error: error,
      warning: warning,
      exitCode: exitCode,
      environment: environment,
      workingDirectory: workingDirectory,
    );

Future<void> pubDowngrade({
  Iterable<String>? args,
  Object? output,
  Object? error,
  Object? warning,
  int? exitCode,
  Map<String, String>? environment,
  String? workingDirectory,
}) async =>
    await pubCommand(
      RunCommand.downgrade,
      args: args,
      output: output,
      error: error,
      warning: warning,
      exitCode: exitCode,
      environment: environment,
      workingDirectory: workingDirectory,
    );

Future<void> pubRemove({
  Iterable<String>? args,
  Object? output,
  Object? error,
  Object? warning,
  int? exitCode,
  Map<String, String>? environment,
  String? workingDirectory,
}) async =>
    await pubCommand(
      RunCommand.remove,
      args: args,
      output: output,
      error: error,
      warning: warning,
      exitCode: exitCode,
      environment: environment,
      workingDirectory: workingDirectory,
    );

/// 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.
Future<PubProcess> pubRun(
    {bool global = false,
    required Iterable<String> args,
    Map<String, String>? environment,
    bool verbose = true}) async {
  var pubArgs = global ? ['global', 'run'] : ['run'];
  pubArgs.addAll(args);
  var pub = await startPub(
    args: pubArgs,
    environment: environment,
    verbose: verbose,
  );

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

  return pub;
}

/// Schedules renaming (moving) the directory at [from] to [to], both of which
/// are assumed to be relative to [d.sandbox].
void renameInSandbox(String from, String to) {
  renameDir(_pathInSandbox(from), _pathInSandbox(to));
}

/// Schedules creating a symlink at path [symlink] that points to [target],
/// both of which are assumed to be relative to [d.sandbox].
void symlinkInSandbox(String target, String symlink) {
  createSymlink(_pathInSandbox(target), _pathInSandbox(symlink));
}

/// Runs Pub with [args] and validates that its results match [output] (or
/// [outputJson]), [error], [silent] (for logs that are silent by default), and
/// [exitCode].
///
/// [output], [error], and [silent] can be [String]s, [RegExp]s, or [Matcher]s.
///
/// If [input] is given, writes given lines into process stdin stream.
///
/// If [outputJson] is given, validates that pub outputs stringified JSON
/// matching that object, which can be a literal JSON object or any other
/// [Matcher].
///
/// If [environment] is given, any keys in it will override the environment
/// variables passed to the spawned process.
Future<void> runPub(
    {List<String>? args,
    Object? output,
    Object? error,
    Object? outputJson,
    Object? silent,
    int? exitCode,
    String? workingDirectory,
    Map<String, String?>? environment,
    List<String>? input,
    includeParentHomeAndPath = true}) async {
  exitCode ??= exit_codes.SUCCESS;
  // Cannot pass both output and outputJson.
  assert(output == null || outputJson == null);

  var pub = await startPub(
    args: args,
    workingDirectory: workingDirectory,
    environment: environment,
    includeParentHomeAndPath: includeParentHomeAndPath,
  );

  if (input != null) {
    input.forEach(pub.stdin.writeln);
    await pub.stdin.flush();
  }

  await pub.shouldExit(exitCode);

  var actualOutput = (await pub.stdoutStream().toList()).join('\n');
  var actualError = (await pub.stderrStream().toList()).join('\n');
  var actualSilent = (await pub.silentStream().toList()).join('\n');

  var failures = <String>[];
  if (outputJson == null) {
    _validateOutput(failures, 'stdout', output, actualOutput);
  } else {
    _validateOutputJson(failures, 'stdout', outputJson, actualOutput);
  }

  _validateOutput(failures, 'stderr', error, actualError);
  _validateOutput(failures, 'silent', silent, actualSilent);

  if (failures.isNotEmpty) {
    test.fail(failures.join('\n'));
  }
}

/// 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.
Future<PubProcess> startPublish(
  PackageServer server, {
  List<String>? args,
  bool overrideDefaultHostedServer = true,
  Map<String, String>? environment,
  String path = '',
}) async {
  var tokenEndpoint = Uri.parse(server.url).resolve('/token').toString();
  args = ['lish', ...?args];
  return await startPub(args: args, tokenEndpoint: tokenEndpoint, environment: {
    if (overrideDefaultHostedServer)
      '_PUB_TEST_DEFAULT_HOSTED_URL': server.url + path
    else
      'PUB_HOSTED_URL': server.url + path,
    if (environment != null) ...environment,
  });
}

/// Handles the beginning confirmation process for uploading a packages.
///
/// Ensures that the right output is shown and then enters "y" to confirm the
/// upload.
Future<void> confirmPublish(TestProcess pub) async {
  // TODO(rnystrom): This is overly specific and inflexible regarding different
  // test packages. Should validate this a little more loosely.
  await expectLater(
      pub.stdout, emitsThrough(startsWith('Publishing test_pkg 1.0.0 to ')));
  await expectLater(
      pub.stdout,
      emitsThrough(matches(
        r'^Do you want to publish [^ ]+ [^ ]+ (y/N)?',
      )));
  pub.stdin.writeln('y');
}

/// Resolves [path] relative to the package cache in the sandbox.
String pathInCache(String path) => p.join(d.sandbox, cachePath, path);

/// Gets the absolute path to [relPath], which is a relative path in the test
/// sandbox.
String _pathInSandbox(String relPath) => p.join(d.sandbox, relPath);

const String testVersion = '0.1.2+3';

/// Gets the environment variables used to run pub in a test context.
Map<String, String> getPubTestEnvironment([String? tokenEndpoint]) => {
      'CI': 'false', // unless explicitly given tests don't run pub in CI mode
      '_PUB_TESTING': 'true',
      '_PUB_TEST_CONFIG_DIR': _pathInSandbox(configPath),
      'PUB_CACHE': _pathInSandbox(cachePath),
      'PUB_ENVIRONMENT': 'test-environment',

      // Ensure a known SDK version is set for the tests that rely on that.
      '_PUB_TEST_SDK_VERSION': testVersion,
      if (tokenEndpoint != null) '_PUB_TEST_TOKEN_ENDPOINT': tokenEndpoint,
      if (_globalServer?.port != null)
        'PUB_HOSTED_URL': 'http://localhost:${_globalServer?.port}'
    };

/// The path to the root of pub's sources in the pub repo.
final String _pubRoot = (() {
  if (!fileExists(p.join('bin', 'pub.dart'))) {
    throw StateError(
        "Current working directory (${p.current} is not pub's root. Run tests from pub's root.");
  }
  return p.current;
})();

/// Starts a Pub process and returns a [PubProcess] that supports interaction
/// with that process.
///
/// Any futures in [args] will be resolved before the process is started.
///
/// If [environment] is given, any keys in it will override the environment
/// variables passed to the spawned process.
Future<PubProcess> startPub(
    {Iterable<String>? args,
    String? tokenEndpoint,
    String? workingDirectory,
    Map<String, String?>? environment,
    bool verbose = true,
    includeParentHomeAndPath = true}) async {
  args ??= [];

  ensureDir(_pathInSandbox(appPath));

  // If there's a snapshot for "pub" available we use it. If the snapshot is
  // out-of-date local source the tests will be useless, therefore it is
  // recommended to use a temporary file with a unique name for each test run.
  // Note: running tests without a snapshot is significantly slower, use
  // tool/test.dart to generate the snapshot.
  var pubPath = Platform.environment['_PUB_TEST_SNAPSHOT'] ?? '';
  if (pubPath.isEmpty || !fileExists(pubPath)) {
    pubPath = p.absolute(p.join(_pubRoot, 'bin/pub.dart'));
  }

  final dotPackagesPath = (await Isolate.packageConfig).toString();

  var dartArgs = ['--packages=$dotPackagesPath', '--enable-asserts'];
  dartArgs
    ..addAll([pubPath, if (!verbose) '--verbosity=normal'])
    ..addAll(args);

  final systemRoot = Platform.environment['SYSTEMROOT'];
  final tmp = Platform.environment['TMP'];

  final mergedEnvironment = {
    if (includeParentHomeAndPath) ...{
      'HOME': Platform.environment['HOME'] ?? '',
      'PATH': Platform.environment['PATH'] ?? '',
    },
    // These seem to be needed for networking to work.
    if (Platform.isWindows) ...{
      if (systemRoot != null) 'SYSTEMROOT': systemRoot,
      if (tmp != null) 'TMP': tmp,
    },
    ...getPubTestEnvironment(tokenEndpoint)
  };
  for (final e in (environment ?? {}).entries) {
    var value = e.value;
    if (value == null) {
      mergedEnvironment.remove(e.key);
    } else {
      mergedEnvironment[e.key] = value;
    }
  }

  return await PubProcess.start(Platform.resolvedExecutable, dartArgs,
      environment: mergedEnvironment,
      workingDirectory: workingDirectory ?? _pathInSandbox(appPath),
      description: args.isEmpty ? 'pub' : 'pub ${args.first}',
      includeParentEnvironment: false);
}

/// A subclass of [TestProcess] 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 TestProcess {
  late final StreamSplitter<Pair<log.Level, String>> _logSplitter =
      createLogSplitter();

  StreamSplitter<Pair<log.Level, String>> createLogSplitter() {
    return StreamSplitter(StreamGroup.merge([
      _outputToLog(super.stdoutStream(), log.Level.message),
      _outputToLog(super.stderrStream(), log.Level.error)
    ]));
  }

  static Future<PubProcess> start(String executable, Iterable<String> arguments,
      {String? workingDirectory,
      Map<String, String>? environment,
      bool includeParentEnvironment = true,
      bool runInShell = false,
      String? description,
      Encoding encoding = utf8,
      bool forwardStdio = false}) async {
    var process = await Process.start(executable, arguments.toList(),
        workingDirectory: workingDirectory,
        environment: environment,
        includeParentEnvironment: includeParentEnvironment,
        runInShell: runInShell);

    if (description == null) {
      var humanExecutable = p.isWithin(p.current, executable)
          ? p.relative(executable)
          : executable;
      description = '$humanExecutable ${arguments.join(' ')}';
    }

    return PubProcess(process, description,
        encoding: encoding, forwardStdio: forwardStdio);
  }

  /// This is protected.
  PubProcess(process, description,
      {Encoding encoding = utf8, bool forwardStdio = false})
      : super(process, description,
            encoding: encoding, forwardStdio: forwardStdio);

  final _logLineRegExp = RegExp(r'^([A-Z ]{4})[:|] (.*)$');
  final Map<String, log.Level> _logLevels = [
    log.Level.error,
    log.Level.warning,
    log.Level.message,
    log.Level.io,
    log.Level.solver,
    log.Level.fine
  ].fold({}, (levels, level) {
    levels[level.name] = level;
    return levels;
  });

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

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

  @override
  Stream<String> stdoutStream() {
    return _logSplitter.split().expand((entry) {
      if (entry.first != log.Level.message) return [];
      return [entry.last];
    });
  }

  @override
  Stream<String> stderrStream() {
    return _logSplitter.split().expand((entry) {
      if (entry.first != log.Level.error && entry.first != log.Level.warning) {
        return [];
      }
      return [entry.last];
    });
  }

  /// A stream of log messages that are silent by default.
  Stream<String> silentStream() {
    return _logSplitter.split().expand((entry) {
      if (entry.first == log.Level.message) return [];
      if (entry.first == log.Level.error) return [];
      if (entry.first == log.Level.warning) return [];
      return [entry.last];
    });
  }
}

/// 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.
void ensureGit() {
  if (!git.isInstalled) fail('Git must be installed to run this test.');
}

/// Creates a lock file for [package] without running `pub get`.
///
/// [dependenciesInSandBox] is a list of path dependencies to be found in the sandbox
/// directory.
///
/// [hosted] is a list of package names to version strings for dependencies on
/// hosted packages.
Future<void> createLockFile(String package,
    {Iterable<String>? dependenciesInSandBox,
    Map<String, String>? hosted}) async {
  var cache = SystemCache(rootDir: _pathInSandbox(cachePath));

  var lockFile =
      _createLockFile(cache, sandbox: dependenciesInSandBox, hosted: hosted);

  await d.dir(package, [
    d.file('pubspec.lock', lockFile.serialize(p.join(d.sandbox, package)))
  ]).create();
}

/// Creates a lock file for [sources] without running `pub get`.
///
/// [sandbox] is a list of path dependencies to be found in the sandbox
/// directory.
///
/// [hosted] is a list of package names to version strings for dependencies on
/// hosted packages.
LockFile _createLockFile(SystemCache cache,
    {Iterable<String>? sandbox, Map<String, String>? hosted}) {
  var dependencies = {};

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

  final packages = <PackageId>[
    ...dependencies.entries.map((entry) => cache.path.parseId(
        entry.key, Version(0, 0, 0), {'path': entry.value, 'relative': true},
        containingDir: p.join(d.sandbox, appPath))),
    if (hosted != null)
      ...hosted.entries.map(
          (entry) => cache.hosted.idFor(entry.key, Version.parse(entry.value)))
  ];

  return LockFile(packages);
}

/// 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;
  addTearDown(() {
    innerHttpClient = oldInnerClient;
  });
}

/// Describes a map representing a library package with the given [name],
/// [version], and [dependencies].
Map<String, Object> packageMap(
  String name,
  String version, [
  Map? dependencies,
  Map? devDependencies,
  Map? environment,
]) {
  var package = <String, Object>{
    'name': name,
    'version': version,
    'homepage': 'http://pub.dev',
    'description': 'A package, I guess.'
  };

  if (dependencies != null) package['dependencies'] = dependencies;
  if (devDependencies != null) package['dev_dependencies'] = devDependencies;
  if (environment != null) package['environment'] = environment;
  return package;
}

/// Returns a Map in the format used by the pub.dev 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(String hostedUrl, Map pubspec,
    {bool retracted = false, bool full = false}) {
  var name = pubspec['name'];
  var version = pubspec['version'];
  var map = {
    'pubspec': pubspec,
    'version': version,
    'archive_url': '$hostedUrl/packages/$name/versions/$version.tar.gz',
  };

  if (retracted) {
    map['retracted'] = true;
  }

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

  return map;
}

/// Returns the name of the shell script for a binstub named [name].
///
/// Adds a ".bat" extension on Windows.
String binStubName(String name) => Platform.isWindows ? '$name.bat' : name;

/// 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 = <String>[];
  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) {
  late Map actual;
  try {
    actual = jsonDecode(actualText);
  } on FormatException {
    failures.add('Expected $pipe JSON:');
    failures.add(expected);
    failures.add('Got invalid JSON:');
    failures.add(actualText);
  }

  // Remove dart2js's timing logs, which would otherwise cause tests to fail
  // flakily when compilation takes a long time.
  actual['log']?.removeWhere((entry) =>
      entry['level'] == 'Fine' &&
      entry['message'].startsWith('Not yet complete after'));

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

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

/// Schedules a single [Validator] to run on the [appPath].
///
/// Returns a scheduled Future that contains the validator after validation.
Future<Validator> validatePackage(ValidatorCreator fn, int? size) async {
  var cache = SystemCache(rootDir: _pathInSandbox(cachePath));
  final entrypoint = Entrypoint(_pathInSandbox(appPath), cache);
  var validator = fn();
  validator.context = ValidationContext(
    entrypoint,
    await Future.value(size ?? 100),
    _globalServer == null
        ? Uri.parse('https://pub.dev')
        : Uri.parse(globalServer.url),
    entrypoint.root.listFiles(),
  );
  await validator.validate();
  return validator;
}

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

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

  _PairMatcher(this._firstMatcher, this._lastMatcher);

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

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

/// Returns a matcher that asserts that a string contains [times] distinct
/// occurrences of [pattern], which must be a regular expression pattern.
Matcher matchesMultiple(String pattern, int times) {
  var buffer = StringBuffer(pattern);
  for (var i = 1; i < times; i++) {
    buffer.write(r'(.|\n)*');
    buffer.write(pattern);
  }
  return matches(buffer.toString());
}

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

/// Removes output from pub known to be unstable.
Iterable<String> filterUnstableLines(List<String> input) {
  return input
      // Downloading order is not deterministic, so to avoid flakiness we filter
      // out these lines.
      .where((line) => !line.startsWith('Downloading '))
      // Any paths in output should be relative to the sandbox and with forward
      // slashes to be stable across platforms.
      .map((line) {
    line = line
        .replaceAll(d.sandbox, r'$SANDBOX')
        .replaceAll(Platform.pathSeparator, '/');
    var port = _globalServer?.port;
    if (port != null) {
      line = line.replaceAll(port.toString(), '\$PORT');
    }
    return line;
  });
}

/// Runs `pub outdated [args]` and appends the output to [buffer].
Future<void> runPubIntoBuffer(
  List<String> args,
  StringBuffer buffer, {
  Map<String, String>? environment,
  String? workingDirectory,
  String? stdin,
}) async {
  final process = await startPub(
    args: args,
    environment: environment,
    workingDirectory: workingDirectory,
  );
  if (stdin != null) {
    process.stdin.write(stdin);
    await process.stdin.flush();
    await process.stdin.close();
  }
  final exitCode = await process.exitCode;

  // TODO(jonasfj): Clean out temporary directory names from env vars...
  // if (workingDirectory != null) {
  //   buffer.writeln('\$ cd $workingDirectory');
  // }
  // if (environment != null && environment.isNotEmpty) {
  //   buffer.writeln(environment.entries
  //       .map((e) => '\$ export ${e.key}=${e.value}')
  //       .join('\n'));
  // }
  final pipe = stdin == null ? '' : ' echo ${escapeShellArgument(stdin)} |';
  buffer.writeln(filterUnstableLines([
    '\$$pipe pub ${args.map(escapeShellArgument).join(' ')}',
    ...await process.stdout.rest.toList(),
  ]).join('\n'));
  for (final line in filterUnstableLines(await process.stderr.rest.toList())) {
    buffer.writeln('[STDERR] $line');
  }
  if (exitCode != 0) {
    buffer.writeln('[EXIT CODE] $exitCode');
  }
  buffer.write('\n');
}

/// The current global [PackageServer].
PackageServer get globalServer => _globalServer!;
PackageServer? _globalServer;

/// Creates an HTTP server that replicates the structure of pub.dev and makes it
/// the current [globalServer].
Future<PackageServer> servePackages() async {
  final server = await startPackageServer();
  _globalServer = server;

  addTearDown(() {
    _globalServer = null;
  });
  return server;
}

Future<PackageServer> startPackageServer() async {
  final server = await PackageServer.start();

  addTearDown(() async {
    await server.close();
  });
  return server;
}

/// Create temporary folder 'bin/' containing a 'git' script in [sandbox]
/// By adding the bin/ folder to the search `$PATH` we can prevent `pub` from
/// detecting the installed 'git' binary and we can test that it prints
/// a useful error message.
Future<void> setUpFakeGitScript(
    {required String bash, required String batch}) async {
  await d.dir('bin', [
    if (!Platform.isWindows) d.file('git', bash),
    if (Platform.isWindows) d.file('git.bat', batch),
  ]).create();
  if (!Platform.isWindows) {
    // Make the script executable.
    await runProcess('chmod', ['+x', p.join(d.sandbox, 'bin', 'git')]);
  }
}

/// Returns an environment where PATH is extended with `$sandbox/bin`.
Map<String, String> extendedPathEnv() {
  final separator = Platform.isWindows ? ';' : ':';
  final binFolder = p.join(d.sandbox, 'bin');

  return {
    // Override 'PATH' to ensure that we can't detect a working "git" binary
    'PATH': '$binFolder$separator${Platform.environment['PATH']}',
  };
}
