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

import 'dart:convert';
import 'dart:core';
import 'dart:io' hide BytesBuilder;
import 'dart:isolate';
import 'dart:math';
import 'dart:typed_data';

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/source/hosted.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:tar/tar.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(Object? 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';

d.DirectoryDescriptor configDir(Iterable<d.Descriptor> contents) =>
    d.dir(configPath, [d.dir('dart', contents)]);

/// 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 path of the ".dart_tool/package_graph.json" file in the mock app used
/// for tests, relative to the sandbox directory.
String packageGraphFilePath = p.join(
  appPath,
  '.dart_tool',
  'package_graph.json',
);

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

/// 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)!)($|
\d+ packages? (has|have) newer versions incompatible with dependency constraints.
Try `dart pub outdated` for more information.$)'''),
  );
  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,
  bool includeParentHomeAndPath = true,
}) async {
  if (error != null && warning != null) {
    throw ArgumentError("Cannot pass both 'error' and 'warning'.");
  }

  final 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,
  Object? silent,
  int? exitCode,
  Map<String, String>? environment,
  String? workingDirectory,
}) async => await pubCommand(
  RunCommand.upgrade,
  args: args,
  output: output,
  error: error,
  warning: warning,
  silent: silent,
  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 {
  final pubArgs = global ? ['global', 'run'] : ['run'];
  pubArgs.addAll(args);
  final 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,
  bool includeParentHomeAndPath = true,
}) async {
  exitCode ??= exit_codes.SUCCESS;
  // Cannot pass both output and outputJson.
  assert(output == null || outputJson == null);

  final 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);

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

  final 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 = '',
  String? workingDirectory,
}) async {
  final 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,
    },
    workingDirectory: workingDirectory,
  );
}

/// 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 = '3.1.2+3';

/// This constraint is compatible with [testVersion].
const String defaultSdkConstraint = '^3.0.2';

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

  final 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) {
    final 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.join(' ')}',
    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<(log.Level level, String message)> _logSplitter =
      createLogSplitter();

  StreamSplitter<(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 {
    final process = await Process.start(
      executable,
      arguments.toList(),
      workingDirectory: workingDirectory,
      environment: environment,
      includeParentEnvironment: includeParentEnvironment,
      runInShell: runInShell,
    );

    if (description == null) {
      final 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(
    super.process,
    super.description, {
    super.encoding,
    super.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<(log.Level, String message)> _outputToLog(
    Stream<String> stream,
    log.Level defaultLevel,
  ) {
    late log.Level lastLevel;
    return stream.map((line) {
      final match = _logLineRegExp.firstMatch(line);
      if (match == null) return (defaultLevel, line);

      final level = _logLevels[match[1]] ?? lastLevel;
      lastLevel = level;
      return (level, match[2]!);
    });
  }

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

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

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

/// 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 {
  final cache = SystemCache(rootDir: _pathInSandbox(cachePath));

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

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

/// Creates a lock file 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,
}) {
  final dependencies = <String, dynamic>{};

  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) => PackageId(
          entry.key,
          Version.parse(entry.value),
          ResolvedHostedDescription(
            HostedDescription(entry.key, 'https://pub.dev'),
            sha256: null,
          ),
        ),
      ),
  ];

  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) {
  final 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,
]) {
  final package = <String, Object>{
    'name': name,
    'version': version,
    'homepage': 'https://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 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,
  Object? 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,
) {
  final actualLines = actual.split('\n');
  final 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();
  }

  final results = <String>[];
  var failed = false;

  // Compare them line by line to see which ones match.
  final 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 {
      final expectedLine = expectedLines[i].trim();
      final 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,
  Object? expected,
  String actualText,
) {
  late Map actual;
  try {
    actual = jsonDecode(actualText) as Map;
  } on FormatException {
    failures.add('Expected $pipe JSON:');
    failures.add(expected.toString());
    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'] as List?)?.removeWhere(
    (dynamic entry) =>
        (entry as Map)['level'] == 'Fine' &&
        (entry['message'] as String).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 {
  final cache = SystemCache(rootDir: _pathInSandbox(cachePath));
  final entrypoint = Entrypoint(_pathInSandbox(appPath), cache);
  final validator = fn();
  validator.context = ValidationContext(
    entrypoint,
    await Future.value(size ?? 100),
    _globalServer == null
        ? Uri.parse('https://pub.dev')
        : Uri.parse(globalServer.url),
    entrypoint.workspaceRoot.listFiles(),
  );
  await validator.validate();
  return validator;
}

/// 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) {
  final 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 across runs or platforms.
String filterUnstableText(String input) {
  // Any paths in output should be relative to the sandbox and with forward
  // slashes to be stable across platforms.
  input = input.replaceAll(d.sandbox, r'$SANDBOX');
  input = input
      .replaceAllMapped(RegExp(r'\\(\S|\.)'), (match) => '/${match[1]}')
      .replaceAll(
        RegExp(r'sha256: "?[0-9a-f]{64}"?', multiLine: true),
        r'sha256: $SHA256',
      );
  final port = _globalServer?.port;
  if (port != null) {
    input = input.replaceAll(port.toString(), '\$PORT');
  }
  return input;
}

/// 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)} |';
  final joinedArgs = args
      .map(filterUnstableText)
      .map(escapeShellArgument)
      .join(' ');
  buffer.writeln('\$$pipe pub $joinedArgs');
  for (final line in await process.stdout.rest.toList()) {
    buffer.writeln(filterUnstableText(line));
  }
  for (final line in await process.stderr.rest.toList()) {
    buffer.writeln('[STDERR] ${filterUnstableText(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 [d.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']}',
  };
}

const _defaultMode = 420; // 644₈
const _executableMask = 0x49; // 001 001 001

Stream<List<int>> tarFromDescriptors(Iterable<d.Descriptor> contents) {
  final entries = <TarEntry>[];
  void addDescriptor(d.Descriptor descriptor, String path) {
    if (descriptor is d.DirectoryDescriptor) {
      if (descriptor.contents.isEmpty) {
        entries.add(
          TarEntry(
            TarHeader(
              name: p.posix.join(path, descriptor.name),
              typeFlag: TypeFlag.dir,
              mode: _defaultMode | _executableMask,
            ),
            Stream.fromIterable([]),
          ),
        );
      }
      for (final e in descriptor.contents) {
        addDescriptor(e, p.posix.join(path, descriptor.name));
      }
    } else {
      entries.add(
        TarEntry(
          TarHeader(
            // Ensure paths in tar files use forward slashes
            name: p.posix.join(path, descriptor.name),
            // We want to keep executable bits, but otherwise use the default
            // file mode
            mode: 420,
            // size: 100,
            modified: DateTime.fromMicrosecondsSinceEpoch(0),
            userName: 'pub',
            groupName: 'pub',
          ),
          (descriptor as d.FileDescriptor).readAsBytes(),
        ),
      );
    }
  }

  for (final e in contents) {
    addDescriptor(e, '');
  }
  return _replaceOs(
    Stream.fromIterable(entries)
        .transform(tarWriterWith(format: OutputFormat.gnuLongName))
        .transform(gzip.encoder),
  );
}

/// Replaces the entry at index 9 in [stream] with a 0. This replaces the os
/// entry of a gzip stream, giving us the same stream and this stable testing
/// on all platforms.
///
/// See https://www.rfc-editor.org/rfc/rfc1952 section 2.3 for information
/// about the OS header.
Stream<List<int>> _replaceOs(Stream<List<int>> stream) async* {
  final bytesBuilder = BytesBuilder();
  await for (final t in stream) {
    bytesBuilder.add(t);
  }
  final result = bytesBuilder.toBytes();
  result[9] = 0;
  yield result;
}

/// Utility for indexing json data structures.
///
/// Each element of [path] should be a `String`, `int` or `(String, String)`.
///
/// For each element `key` of [path], recurse into [json].
///
/// If the `key` is a String, the next json structure should be a Map, and have
/// `key` as a property. Recurse into that property.
///
/// If `key` is an `int`, the next json structure must be a List, with that
/// index. Recurse into that index.
///
/// If `key` in a `(String k, String v)` the next json structure must be a List
/// of maps, one of them having the property `k` with value `v`, recurse into
/// that map.
///
/// Cast the result as a [T].
T dig<T>(dynamic json, List<dynamic> path) {
  for (var i = 0; i < path.length; i++) {
    switch (path[i]) {
      case final String key:
        json = (json as Map)[key];
      case final int key:
        json = (json as List)[key];
      case (final String key, final String value):
        json = (json as List).firstWhere(
          (element) => (element as Map)[key] == value,
        );
      case final key:
        throw ArgumentError('Bad key $key in', 'path');
    }
  }
  return json as T;
}
