// 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;
// 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 'package:pub/src/git.dart' as gitlib;
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.
final 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,
  includeParentEnvironment = 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,
      includeParentEnvironment: includeParentEnvironment);
}

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? warning,
  int? exitCode,
  Map<String, String?>? environment,
  String? workingDirectory,
  bool includeParentEnvironment = true,
}) async =>
    await pubCommand(
      RunCommand.get,
      args: args,
      output: output,
      error: error,
      warning: warning,
      exitCode: exitCode,
      environment: environment,
      workingDirectory: workingDirectory,
      includeParentEnvironment: includeParentEnvironment,
    );

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,
    includeParentEnvironment = 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,
    includeParentEnvironment: includeParentEnvironment,
  );

  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, emits(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);

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,
    includeParentEnvironment = 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 mergedEnvironment = 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: includeParentEnvironment);
}

/// 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 (!gitlib.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))),
    d.file(
      '.packages',
      lockFile.packagesFile(
        cache,
        entrypoint: package,
        relativeFrom: p.join(d.sandbox, package),
      ),
    )
  ]).create();
}

/// Like [createLockFile], but creates only a `.packages` file without a
/// lockfile.
Future<void> createPackagesFile(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(
      '.packages',
      lockFile.packagesFile(
        cache,
        entrypoint: package,
        relativeFrom: d.sandbox,
      ),
    )
  ]).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.dartlang.org',
    '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.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(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.dartlang.org 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']}',
  };
}
