// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:convert';
import 'dart:io';

import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:args/args.dart';
import 'package:collection/collection.dart';
import 'package:crypto/crypto.dart' as crypto;
import 'package:dartdoc/src/io_utils.dart';
import 'package:dartdoc/src/package_meta.dart';
import 'package:path/path.dart' as path;
import 'package:sass/sass.dart' as sass;
import 'package:yaml/yaml.dart' as yaml;
import 'package:yaml/yaml.dart';

import 'src/flutter_repo.dart';
import 'src/io_utils.dart' as io_utils;
import 'src/subprocess_launcher.dart';
import 'src/warnings_collection.dart';

void main(List<String> args) async {
  var parser = ArgParser()
    ..addCommand('analyze')
    ..addCommand('buildbot')
    ..addCommand('clean')
    ..addCommand('compare')
    ..addCommand('help')
    ..addCommand('test')
    ..addCommand('try-publish')
    ..addCommand('validate');
  var buildCommand = parser.addCommand('build')
    ..addFlag('debug', help: 'build unoptimized JavaScript');
  var docCommand = parser.addCommand('doc')
    ..addOption('name', help: 'package name')
    ..addOption('version', help: 'package version')
    ..addFlag('stats', help: 'print runtime stats');
  var serveCommand = parser.addCommand('serve')
    ..addOption('name')
    ..addOption('version');

  var results = parser.parse(args);
  var commandResults = results.command;
  if (commandResults == null) {
    return;
  }

  buildUsage = buildCommand.usage;
  docUsage = docCommand.usage;
  serveUsage = serveCommand.usage;

  return await switch (commandResults.name) {
    'analyze' => runAnalyze(commandResults),
    'build' => runBuild(commandResults),
    'buildbot' => runBuildbot(),
    'clean' => runClean(),
    'compare' => runCompare(commandResults),
    'doc' => runDoc(commandResults),
    'help' => runHelp(commandResults),
    'serve' => runServe(commandResults),
    'test' => runTest(),
    'try-publish' => runTryPublish(),
    'validate' => runValidate(commandResults),
    _ => throw ArgumentError(),
  };
}

late String buildUsage;
late String docUsage;
late String serveUsage;

String _getPackageVersion() {
  var pubspec = File('pubspec.yaml');
  if (!pubspec.existsSync()) {
    throw StateError('Cannot find pubspec.yaml in ${Directory.current}');
  }
  var yamlDoc = yaml.loadYaml(pubspec.readAsStringSync()) as yaml.YamlMap;
  return yamlDoc['version'] as String;
}

Directory get testPackage =>
    Directory(path.joinAll(['testing', 'test_package']));

Directory get testPackageExperiments =>
    Directory(path.joinAll(['testing', 'test_package_experiments']));

Future<void> runAnalyze(ArgResults commandResults) async {
  for (var target in commandResults.rest) {
    await switch (target) {
      'package' => analyzePackage(),
      'test-packages' => analyzeTestPackages(),
      _ => throw UnimplementedError('Unknown analyze target: "$target"'),
    };
  }
}

Future<void> analyzePackage() async =>
    await SubprocessLauncher('analyze').runStreamedDartCommand(
      ['analyze', '--fatal-infos', '.'],
    );

Future<void> analyzeTestPackages() async {
  var testPackagePaths = [
    testPackage.path,
    if (Platform.version.contains('dev')) testPackageExperiments.path,
  ];
  for (var testPackagePath in testPackagePaths) {
    await SubprocessLauncher('pub-get').runStreamedDartCommand(
      ['pub', 'get'],
      workingDirectory: testPackagePath,
    );
    await SubprocessLauncher('analyze-test-package').runStreamedDartCommand(
      // TODO(srawlins): Analyze the whole directory by ignoring the pubspec
      // reports.
      ['analyze', 'lib'],
      workingDirectory: testPackagePath,
    );
  }
}

Future<void> _buildHelp() async {
  print('''
Usage:
dart tool/task.dart build [renderers|dartdoc-options|web]
$buildUsage
''');
}

Future<void> runBuild(ArgResults commandResults) async {
  if (commandResults.rest.isEmpty) {
    await buildAll();
  }
  var debug = (commandResults['debug'] ?? false) as bool;
  for (var target in commandResults.rest) {
    await switch (target) {
      'renderers' => buildRenderers(),
      'dartdoc-options' => buildDartdocOptions(),
      'web' => buildWeb(debug: debug),
      _ => throw UnimplementedError('Unknown build target: "$target"'),
    };
  }
}

Future<void> buildAll() async {
  if (Platform.isWindows) {
    // Built files only need to be built on Linux and MacOS, as there are path
    // issues with Windows.
    return;
  }
  await buildWeb();
  await buildRenderers();
  await buildDartdocOptions();
}

Future<void> buildRenderers() async => await SubprocessLauncher('build')
    .runStreamedDartCommand([path.join('tool', 'mustachio', 'builder.dart')]);

Future<void> buildDartdocOptions() async {
  var version = _getPackageVersion();
  var dartdocOptions = File('dartdoc_options.yaml');
  await dartdocOptions.writeAsString('''dartdoc:
  linkToSource:
    root: '.'
    uriTemplate: 'https://github.com/dart-lang/dartdoc/blob/v$version/%f%#L%l%'
''');
}

Future<void> buildWeb({bool debug = false}) async {
  await SubprocessLauncher('build').runStreamedDartCommand([
    'compile',
    'js',
    '--output=lib/resources/docs.dart.js',
    'web/docs.dart',
    if (debug) '--enable-asserts',
    debug ? '-O0' : '-O4',
  ]);
  _delete(File('lib/resources/docs.dart.js.deps'));

  final compileResult = sass.compileToResult('web/styles/styles.scss',
      style: debug ? sass.OutputStyle.expanded : sass.OutputStyle.compressed);
  if (compileResult.css.isNotEmpty) {
    File('lib/resources/styles.css')
        .writeAsStringSync('${compileResult.css}\n');
  } else {
    throw StateError('Compiled CSS was empty.');
  }

  var compileSig =
      await _calcFilesSig(Directory('web'), extensions: {'.dart', '.scss'});
  File(path.join('web', 'sig.txt')).writeAsStringSync('$compileSig\n');
}

/// Delete the given file entity reference.
void _delete(FileSystemEntity entity) {
  if (entity.existsSync()) {
    print('deleting ${entity.path}');
    entity.deleteSync(recursive: true);
  }
}

/// Yields all of the trimmed lines of all of the files in [dir] with
/// one of the specified [extensions].
Stream<String> _fileLines(Directory dir, {required Set<String> extensions}) {
  var files = dir
      .listSync(recursive: true)
      .whereType<File>()
      .where((file) => extensions.contains(path.extension(file.path)))
      .sorted((a, b) => compareAsciiLowerCase(a.path, b.path));

  return Stream.fromIterable([
    for (var file in files)
      for (var line in file.readAsLinesSync()) line.trim(),
  ]);
}

Future<void> runBuildbot() async {
  await analyzeTestPackages();
  await analyzePackage();
  await validateFormat();
  await validateBuild();
  await runTryPublish();
  await runTest();
  await validateDartdocDocs();
}

Future<void> runClean() async {
  // This involves deleting things, so be careful.
  if (!File(path.join('tool', 'task.dart')).existsSync()) {
    throw FileSystemException('Wrong CWD, run from root of dartdoc package');
  }
  const pubDataFileNames = {'.dart_tool', '.packages', 'pubspec.lock'};
  var nonRootPubData = Directory('.')
      .listSync(recursive: true)
      .where((e) => path.dirname(e.path) != '.')
      .where((e) => pubDataFileNames.contains(path.basename(e.path)));
  for (var e in nonRootPubData) {
    e.deleteSync(recursive: true);
  }
}

Future<void> runCompare(ArgResults commandResults) async {
  if (commandResults.rest.length != 1) {
    throw ArgumentError('"compare" command requires a single target.');
  }
  var target = commandResults.rest.single;
  await switch (target) {
    'flutter-warnings' => compareFlutterWarnings(),
    'sdk-warnings' => compareSdkWarnings(),
    _ => throw UnimplementedError('Unknown compare target: "$target"'),
  };
}

Future<void> compareFlutterWarnings() async {
  var originalDartdocFlutter =
      Directory.systemTemp.createTempSync('dartdoc-comparison-flutter');
  var originalDartdoc = await _createComparisonDartdoc();
  var envCurrent = createThrowawayPubCache();
  var envOriginal = createThrowawayPubCache();
  var currentDartdocFlutterBuild = _docFlutter(
    flutterPath: flutterDir.path,
    cwd: Directory.current.path,
    env: envCurrent,
    label: 'docs-current',
  );
  var originalDartdocFlutterBuild = _docFlutter(
    flutterPath: originalDartdocFlutter.path,
    cwd: originalDartdoc,
    env: envOriginal,
    label: 'docs-original',
  );
  var currentDartdocWarnings = _collectWarnings(
    messages: await currentDartdocFlutterBuild,
    tempPath: flutterDir.absolute.path,
    branch: 'HEAD',
    pubDir: envCurrent['PUB_CACHE'],
  );
  var originalDartdocWarnings = _collectWarnings(
    messages: await originalDartdocFlutterBuild,
    tempPath: originalDartdocFlutter.absolute.path,
    branch: _dartdocOriginalBranch,
    pubDir: envOriginal['PUB_CACHE'],
  );

  print(originalDartdocWarnings.warningDeltaText(
      'Flutter repo', currentDartdocWarnings));

  if (Platform.environment['SERVE_FLUTTER'] == '1') {
    var launcher = SubprocessLauncher('serve-flutter-docs');
    await launcher.runStreamed(Platform.resolvedExecutable, ['pub', 'get']);
    var original = launcher.runStreamed(Platform.resolvedExecutable, [
      'pub',
      'global',
      'run',
      'dhttpd',
      '--port',
      '9000',
      '--path',
      path.join(originalDartdocFlutter.absolute.path, 'dev', 'docs', 'doc'),
    ]);
    var current = launcher.runStreamed(Platform.resolvedExecutable, [
      'pub',
      'global',
      'run',
      'dhttpd',
      '--port',
      '9001',
      '--path',
      path.join(flutterDir.absolute.path, 'dev', 'docs', 'doc'),
    ]);
    await [original, current].wait;
  }
}

Future<void> runDoc(ArgResults commandResults) async {
  if (commandResults.rest.length != 1) {
    throw ArgumentError('"doc" command requires a single target.');
  }
  var target = commandResults.rest.single;
  var stats = commandResults['stats'] as bool;
  await switch (target) {
    'flutter' => docFlutter(withStats: stats),
    'help' => _docHelp(),
    'package' => _docPackage(commandResults, withStats: stats),
    'sdk' => docSdk(withStats: stats),
    'testing-package' => docTestingPackage(),
    _ => throw UnimplementedError('Unknown doc target: "$target"'),
  };
}

Future<void> docFlutter({bool withStats = false}) async {
  print('building flutter docs into: ${flutterDir.path}');
  var env = createThrowawayPubCache();
  await _docFlutter(
    flutterPath: flutterDir.path,
    cwd: Directory.current.path,
    env: env,
    label: 'docs',
    withStats: withStats,
  );
}

Future<Iterable<Map<String, Object?>>> _docFlutter({
  required String flutterPath,
  required String cwd,
  required Map<String, String> env,
  String? label,
  bool withStats = false,
}) async {
  var flutterRepo = await FlutterRepo.copyFromExistingFlutterRepo(
      await cleanFlutterRepo, flutterPath, env, label);
  var snippetsPath = path.join(flutterPath, 'dev', 'snippets');
  var snippetsOutPath =
      path.join(flutterPath, 'bin', 'cache', 'artifacts', 'snippets');
  print('building snippets tool executable...');
  Directory(snippetsOutPath).createSync(recursive: true);
  await flutterRepo.launcher.runStreamed(
    flutterRepo.flutterCmd,
    ['pub', 'get'],
    workingDirectory: path.join(snippetsPath),
  );
  await flutterRepo.launcher.runStreamed(
    flutterRepo.dartCmd,
    ['compile', 'exe', '-o', '$snippetsOutPath/snippets', 'bin/snippets.dart'],
    workingDirectory: path.join(snippetsPath),
  );
  // TODO(jcollins-g): flutter's dart SDK pub tries to precompile the universe
  // when using -spath.  Why?
  await flutterRepo.launcher.runStreamed(
    flutterRepo.flutterCmd,
    ['pub', 'global', 'activate', '-spath', '.', '-x', 'dartdoc'],
    workingDirectory: cwd,
  );
  await flutterRepo.launcher.runStreamed(
    flutterRepo.flutterCmd,
    ['pub', 'get'],
    workingDirectory: path.join(flutterPath, 'dev', 'tools'),
  );
  return await flutterRepo.launcher.runStreamed(
    flutterRepo.dartCmd,
    [
      '--disable-dart-dev',
      '--enable-asserts',
      path.join(
        'dev',
        'tools',
        'create_api_docs.dart',
      ),
      '--json',
    ],
    workingDirectory: flutterPath,
    withStats: withStats,
  );
}

final Directory flutterDir =
    Directory.systemTemp.createTempSync('flutter').absolute;

Future<void> _docHelp() async {
  print('''
Usage:
dart tool/task.dart doc [flutter|package|sdk|testing-package]
$docUsage
''');
}

Future<void> _docPackage(
  ArgResults commandResults, {
  bool withStats = false,
}) async {
  var name = commandResults['name'] as String;
  var version = commandResults['version'] as String?;
  await docPackage(name: name, version: version, withStats: withStats);
}

Future<String> docPackage({
  required String name,
  required String? version,
  bool withStats = false,
}) async {
  var env = createThrowawayPubCache();
  var versionContext = version == null ? '' : '-$version';
  var launcher = SubprocessLauncher('build-$name$versionContext', env);
  await launcher.runStreamedDartCommand([
    'pub',
    'cache',
    'add',
    if (version != null) ...['-v', version],
    name,
  ]);
  var cache = Directory(path.join(env['PUB_CACHE']!, 'hosted', 'pub.dev'));
  // The pub package should be predictably in a location like this.
  var pubPackageDirOrig =
      cache.listSync().firstWhere((e) => e.path.contains('/$name-'));
  var pubPackageDir = Directory.systemTemp.createTempSync(name);
  io_utils.copy(pubPackageDirOrig, pubPackageDir);

  var executable = Platform.executable;
  var arguments = [
    '--enable-asserts',
    path.join(Directory.current.absolute.path, 'bin', 'dartdoc.dart'),
    '--link-to-remote',
    '--show-progress',
    '--show-stats',
    '--no-validate-links',
  ];
  Map<String, String>? environment;

  if (pubPackageMetaProvider
      .fromDir(PhysicalResourceProvider.INSTANCE.getFolder(pubPackageDir.path))!
      .requiresFlutter) {
    var flutterRepo =
        await FlutterRepo.fromExistingFlutterRepo(await cleanFlutterRepo);
    executable = flutterRepo.cacheDart;
    environment = flutterRepo.env;
  }
  await launcher.runStreamed(
    executable,
    ['pub', 'get'],
    environment: environment,
    workingDirectory: pubPackageDir.absolute.path,
  );
  await launcher.runStreamed(
    executable,
    // Add the `--json` flag for the support in `runStreamed` to tease out
    // data and messages. This flag allows the [runCompare] tasks to interpret
    // data from stdout as structured data, in order to compare the dartdoc
    // outputs of two commands. We add it here, but exclude it from the
    // "Quickly re-run" text below, as that command is for human consumption.
    [...arguments, '--json'],
    workingDirectory: pubPackageDir.absolute.path,
    environment: environment,
    withStats: withStats,
  );
  if (withStats) {
    (executable, arguments) =
        SubprocessLauncher.wrapWithTime(executable, arguments);
  }
  print('Quickly re-run doc generation with:');
  print(
    '    pushd ${pubPackageDir.absolute.path} ;'
    ' "$executable" ${arguments.map((a) => '"$a"').join(' ')} ;'
    ' popd',
  );
  return path.join(pubPackageDir.absolute.path, 'doc', 'api');
}

Future<void> docSdk({bool withStats = false}) async => _docSdk(
      sdkDocsPath: _sdkDocsDir.path,
      dartdocPath: Directory.current.path,
      withStats: withStats,
    );

/// Creates a throwaway pub cache and returns the environment variables
/// necessary to use it.
Map<String, String> createThrowawayPubCache() {
  var pubCache = Directory.systemTemp.createTempSync('pubcache');
  var pubCacheBin = Directory(path.join(pubCache.path, 'bin'));
  var defaultCache = Directory(_defaultPubCache);
  if (defaultCache.existsSync()) {
    io_utils.copy(defaultCache, pubCache);
  } else {
    pubCacheBin.createSync();
  }
  return Map.fromIterables([
    'PUB_CACHE',
    'PATH',
  ], [
    pubCache.path,
    [pubCacheBin.path, Platform.environment['PATH']].join(':'),
  ]);
}

final String _defaultPubCache = Platform.environment['PUB_CACHE'] ??
    path.context.resolveTildePath('~/.pub-cache');

Future<String> docTestingPackage() async {
  var testPackagePath = testPackage.absolute.path;
  var launcher = SubprocessLauncher('doc-test-package');
  await launcher.runStreamedDartCommand(['pub', 'get'],
      workingDirectory: testPackagePath);
  var outputPath = _testingPackageDocsDir.absolute.path;
  await launcher.runStreamedDartCommand(
    [
      '--enable-asserts',
      path.join(Directory.current.absolute.path, 'bin', 'dartdoc.dart'),
      '--output',
      outputPath,
      '--include-source',
      '--json',
      '--link-to-remote',
      '--pretty-index-json',
    ],
    workingDirectory: testPackagePath,
  );
  return outputPath;
}

final Directory _testingPackageDocsDir =
    Directory.systemTemp.createTempSync('testing_package');

Future<void> compareSdkWarnings() async {
  var originalDartdocSdkDocs =
      Directory.systemTemp.createTempSync('dartdoc-comparison-sdkdocs');
  var originalDartdoc = await _createComparisonDartdoc();
  var sdkDocsPath =
      Directory.systemTemp.createTempSync('sdkdocs').absolute.path;
  var currentDartdocSdkBuild = _docSdk(
    sdkDocsPath: sdkDocsPath,
    dartdocPath: Directory.current.path,
  );
  var originalDartdocSdkBuild = _docSdk(
    sdkDocsPath: originalDartdocSdkDocs.path,
    dartdocPath: originalDartdoc,
  );
  var currentDartdocWarnings = _collectWarnings(
    messages: await currentDartdocSdkBuild,
    tempPath: sdkDocsPath,
    branch: 'HEAD',
  );
  var originalDartdocWarnings = _collectWarnings(
    messages: await originalDartdocSdkBuild,
    tempPath: originalDartdocSdkDocs.absolute.path,
    branch: _dartdocOriginalBranch,
  );

  print(originalDartdocWarnings.warningDeltaText(
      'SDK docs', currentDartdocWarnings));
}

Future<Iterable<Map<String, Object?>>> _docSdk({
  required String sdkDocsPath,
  required String dartdocPath,
  bool withStats = false,
}) async {
  var launcher = SubprocessLauncher('build-sdk-docs');
  await launcher
      .runStreamedDartCommand(['pub', 'get'], workingDirectory: dartdocPath);
  var output = await launcher.runStreamedDartCommand(
    [
      '--enable-asserts',
      path.join('bin', 'dartdoc.dart'),
      '--output',
      sdkDocsPath,
      '--sdk-docs',
      '--json',
      '--show-progress',
      // Use some local assets for the header and footers, to override the SDK
      // values, from an options file, which includes not-shipped files.
      '--header',
      'lib/resources/blank.txt',
      '--footer',
      'lib/resources/blank.txt',
      '--footer-text',
      'lib/resources/blank.txt',
    ],
    workingDirectory: dartdocPath,
    withStats: withStats,
  );
  if (withStats && (Platform.isLinux || Platform.isMacOS)) {
    var diskUsageResult = Process.runSync('du', ['-sh', sdkDocsPath]);
    // Output looks like
    // 146M    /var/folders/72/ltck4q353hsg3bn8kpkg7f84005w15/T/sdkdocsHcquiB
    var diskUsageNumber =
        (diskUsageResult.stdout as String).trim().split(RegExp('\\s+')).first;

    // Prints all files in `sdkDocsPath`, newline-separated.
    var findResult = Process.runSync('find', [sdkDocsPath, '-type', 'f']);
    var fileCount = (findResult.stdout as String).split('\n').length;
    print('Generated $fileCount files amounting to $diskUsageNumber.');
  }
  return output;
}

/// Creates a clean version of dartdoc (based on the current directory, assumed
/// to be a git repository).
///
/// Uses [_dartdocOriginalBranch] to checkout a branch or tag.
Future<String> _createComparisonDartdoc() async {
  var launcher = SubprocessLauncher('create-comparison-dartdoc');
  var dartdocClean = Directory.systemTemp.createTempSync('dartdoc-comparison');
  await launcher
      .runStreamed('git', ['clone', Directory.current.path, dartdocClean.path]);
  await launcher.runStreamed('git', ['checkout', _dartdocOriginalBranch],
      workingDirectory: dartdocClean.path);
  await launcher.runStreamed(Platform.resolvedExecutable, ['pub', 'get'],
      workingDirectory: dartdocClean.path);
  return dartdocClean.path;
}

/// Version of dartdoc we should use when making comparisons.
String get _dartdocOriginalBranch {
  var branch = Platform.environment['DARTDOC_ORIGINAL'] ?? 'main';
  print('using branch/tag: $branch for comparison from \$DARTDOC_ORIGINAL');
  return branch;
}

Future<void> runHelp(ArgResults commandResults) async {
  if (commandResults.rest.isEmpty) {
    // TODO(srawlins): Add more help for more individual commands.
    print('''
Usage:
    dart tool/task.dart [analyze|build|buildbot|clean|compare|doc|help|serve|test|tryp-publish|validate] options...

Help usage:
    dart tool/task.dart help [doc|serve]
''');
    return;
  }
  if (commandResults.rest.length != 1) {
    throw ArgumentError('"help" command requires a single command name.');
  }
  var command = commandResults.rest.single;
  return switch (command) {
    'build' => _buildHelp(),
    'doc' => _docHelp(),
    'serve' => _serveHelp(),
    _ => throw UnimplementedError(
        'Unknown command: "$command", or no specific help text'),
  };
}

Future<void> runServe(ArgResults commandResults) async {
  if (commandResults.rest.length != 1) {
    throw ArgumentError('"serve" command requires a single target.');
  }
  var target = commandResults.rest.single;
  await switch (target) {
    'flutter' => serveFlutterDocs(),
    'help' => _serveHelp(),
    'package' => _servePackageDocs(commandResults),
    'sdk' => serveSdkDocs(),
    'testing-package' => serveTestingPackageDocs(),
    _ => throw UnimplementedError('Unknown serve target: "$target"'),
  };
}

Future<void> serveFlutterDocs() async {
  await docFlutter();
  print('launching dhttpd on port 8001 for Flutter');
  var launcher = SubprocessLauncher('serve-flutter-docs');
  await launcher.runStreamedDartCommand(['pub', 'get']);
  await launcher.runStreamedDartCommand([
    'pub',
    'global',
    'run',
    'dhttpd',
    '--port',
    '8001',
    '--path',
    path.join(flutterDir.path, 'dev', 'docs', 'doc'),
  ]);
}

Future<void> _serveHelp() async {
  print('''
Usage:
dart tool/task.dart serve [flutter|package|sdk|testing-package]
$docUsage
''');
}

Future<void> _servePackageDocs(ArgResults commandResults) async {
  var name = commandResults['name'] as String;
  var version = commandResults['version'] as String?;
  await servePackageDocs(name: name, version: version);
}

Future<void> servePackageDocs(
    {required String name, required String? version}) async {
  var packageDocsPath = await docPackage(name: name, version: version);
  await _serveDocsFrom(packageDocsPath, 9000, 'serve-pub-package');
}

Future<void> serveSdkDocs() async {
  await docSdk();
  print('launching dhttpd on port 8000 for SDK');
  await SubprocessLauncher('serve-sdk-docs').runStreamedDartCommand([
    'pub',
    'global',
    'run',
    'dhttpd',
    '--port',
    '8000',
    '--path',
    _sdkDocsDir.path,
  ]);
}

bool _serveReady = false;

Future<void> _serveDocsFrom(String servePath, int port, String context) async {
  print('launching dhttpd on port $port for $context');
  var launcher = SubprocessLauncher(context);
  if (!_serveReady) {
    await launcher.runStreamedDartCommand(['pub', 'get']);
    await launcher
        .runStreamedDartCommand(['pub', 'global', 'activate', 'dhttpd']);
    _serveReady = true;
  }
  await launcher.runStreamedDartCommand([
    'pub',
    'global',
    'run',
    'dhttpd',
    '--port',
    '$port',
    '--path',
    servePath
  ]);
}

Future<void> serveTestingPackageDocs() async {
  var outputPath = await docTestingPackage();
  print('launching dhttpd on port 8002 for SDK');
  var launcher = SubprocessLauncher('serve-test-package-docs');
  await launcher.runStreamed(Platform.resolvedExecutable, [
    'pub',
    'global',
    'run',
    'dhttpd',
    '--port',
    '8002',
    '--path',
    outputPath,
  ]);
}

Future<void> runTest() async {
  await analyzeTestPackages();
  await SubprocessLauncher('dart run test')
      .runStreamedDartCommand(['--enable-asserts', 'run', 'test']);
}

Future<void> runTryPublish() async {
  await SubprocessLauncher('try-publish')
      .runStreamed(Platform.resolvedExecutable, ['pub', 'publish', '-n']);
}

Future<void> runValidate(ArgResults commandResults) async {
  for (var target in commandResults.rest) {
    await switch (target) {
      'build' => validateBuild(),
      'dartdoc-docs' => validateDartdocDocs(),
      'format' => validateFormat(),
      'sdk-docs' => validateSdkDocs(),
      _ => throw UnimplementedError('Unknown validation target: "$target"'),
    };
  }
}

Future<void> validateBuild() async {
  var originalFileContents = <String, String>{};
  var differentFiles = <String>[];

  // Load original file contents into memory before running the builder; it
  // modifies them in place.
  for (var relPath in _generatedFilesList) {
    var origPath = path.joinAll(['lib', relPath]);
    var oldVersion = File(origPath);
    if (oldVersion.existsSync()) {
      originalFileContents[relPath] = oldVersion.readAsStringSync();
    }
  }

  await buildAll();

  for (var relPath in _generatedFilesList) {
    if (relPath.contains('runtime_renderers') && !_analyzerInUseIsTarget) {
      // The content of these files is very specific to the version of the
      // analyzer package in use. So we only validate if we are working on that
      // exact version.
      continue;
    }
    var newVersion = File(path.join('lib', relPath));
    if (!newVersion.existsSync()) {
      print('${newVersion.path} does not exist\n');
      differentFiles.add(relPath);
    } else {
      var newVersionText = await newVersion.readAsString();
      if (originalFileContents[relPath] != newVersionText) {
        print('${newVersion.path} has changed to: \n$newVersionText)');
        differentFiles.add(relPath);
      }
    }
  }

  if (differentFiles.isNotEmpty) {
    throw StateError('''
The following generated files needed to be rebuilt:
  ${differentFiles.map((f) => path.join('lib', f)).join("\n  ")}
Rebuild them with "dart tool/task.dart build" and check the results in.
''');
  }

  // Verify that the web frontend has been compiled.
  final currentSig =
      await _calcFilesSig(Directory('web'), extensions: {'.dart', '.scss'});
  final lastCompileSig =
      File(path.join('web', 'sig.txt')).readAsStringSync().trim();
  if (currentSig != lastCompileSig) {
    print('current files: $currentSig');
    print('cached sig   : $lastCompileSig');
    throw StateError(
        'The web frontend (web/docs.dart) needs to be recompiled; rebuild it '
        'with "dart tool/task.dart build web".');
  }

  // Reset some files for `try-publish` step. This check looks for changes in
  // the current git checkout: https://github.com/dart-lang/pub/pull/4373.
  Process.runSync('git', [
    'checkout',
    '--',
    'lib/resources/docs.dart.js',
    'lib/resources/docs.dart.js.map',
  ]);
}

/// Whether the analyzer in use (as found in `pubspec.lock`) is the target
/// version of analyzer, against which we verify the runtime renderer files.
bool get _analyzerInUseIsTarget {
  // TODO(srawlins): Add validation that this number falls within the
  // constraints of the analyzer package which are set in `pubspec.yaml`.
  const analyzerTarget = '7.2.0';

  var lockfilePath = path.join(Directory.current.path, 'pubspec.lock');
  var lockfile = loadYaml(File(lockfilePath).readAsStringSync()) as YamlMap;
  var packages = lockfile['packages'] as YamlMap;
  var analyzer = packages['analyzer'] as YamlMap;
  var analyzerInUse = analyzer['version'] as String;
  return analyzerInUse == analyzerTarget;
}

/// Paths in this list are relative to lib/.
final _generatedFilesList = [
  '../dartdoc_options.yaml',
  'src/generator/html_resources.g.dart',
  'src/generator/templates.aot_renderers_for_html.dart',
  'src/generator/templates.runtime_renderers.dart',
  'src/version.dart',
  '../test/mustachio/foo.dart',
].map((s) => path.joinAll(path.posix.split(s)));

Future<void> validateDartdocDocs() async {
  var launcher = SubprocessLauncher('test-dartdoc');
  await launcher.runStreamedDartCommand([
    '--enable-asserts',
    path.join('bin', 'dartdoc.dart'),
    '--output',
    _dartdocDocsPath,
    '--no-link-to-remote',
  ]);
  _expectFileContains(path.join(_dartdocDocsPath, 'index.html'),
      '<title>dartdoc - Dart API docs</title>');
  var objectText = RegExp('<li>Object</li>', multiLine: true);
  _expectFileContains(
    path.join(_dartdocDocsPath, 'dartdoc', 'PubPackageMeta-class.html'),
    objectText,
  );
}

/// Kind of an inefficient grepper for now.
void _expectFileContains(String filePath, Pattern text) {
  var source = File(filePath);
  if (!source.existsSync()) {
    throw StateError('file not found: $filePath');
  }
  if (!File(filePath).readAsStringSync().contains(text)) {
    throw StateError('"$text" not found in $filePath');
  }
}

final String _dartdocDocsPath =
    Directory.systemTemp.createTempSync('dartdoc').path;

Future<void> validateFormat() async {
  var processResult = Process.runSync(Platform.resolvedExecutable, [
    'format',
    '-o',
    'none',
    'bin',
    'lib',
    'test',
    'tool',
    'web',
  ]);
  if (processResult.exitCode != 0) {
    throw StateError('''
Not all files are formatted:

    ${processResult.stderr}
''');
  }
}

Future<void> validateSdkDocs() async {
  await docSdk();
  const expectedLibCount = 0;
  const expectedSubLibCount = 20;
  const expectedTotalCount = 20;
  var indexHtml = File(path.join(_sdkDocsDir.path, 'index.html'));
  if (!indexHtml.existsSync()) {
    throw StateError("No 'index.html' found for the SDK docs");
  }
  print("Found 'index.html'");
  var indexContents = indexHtml.readAsStringSync();
  var foundLibCount = _findCount(indexContents, '  <li><a href="dart-');
  if (expectedLibCount != foundLibCount) {
    throw StateError(
        "Expected $expectedLibCount 'dart:' entries in 'index.html', but "
        'found $foundLibCount');
  }
  print("Found $foundLibCount 'dart:' entries in 'index.html'");

  var libLinkPattern =
      RegExp('<li class="section-subitem"><a [^>]*href="dart-');
  var foundSubLibCount = _findCount(indexContents, libLinkPattern);
  if (expectedSubLibCount != foundSubLibCount) {
    throw StateError("Expected $expectedSubLibCount 'dart:' entries in "
        "'index.html' to be in categories, but found $foundSubLibCount");
  }
  print('$foundSubLibCount index.html dart: entries in categories found');

  // Check for the existence of certain files and directories.
  var libraries =
      _sdkDocsDir.listSync().where((fs) => fs.path.contains('dart-'));
  var libraryCount = libraries.length;
  if (expectedTotalCount != libraryCount) {
    var libraryNames =
        libraries.map((l) => "'${path.basename(l.path)}'").join(', ');
    throw StateError('Unexpected docs generated for SDK libraries; expected '
        '$expectedTotalCount directories, but $libraryCount directories were '
        'generated: $libraryNames');
  }
  print("Found $libraryCount 'dart:' libraries");

  var futureConstructorFile =
      File(path.join(_sdkDocsDir.path, 'dart-async', 'Future', 'Future.html'));
  if (!futureConstructorFile.existsSync()) {
    throw StateError('No Future.html found for dart:async Future constructor');
  }
  print('Found Future.async constructor');
}

/// A temporary directory into which the SDK can be documented.
final Directory _sdkDocsDir =
    Directory.systemTemp.createTempSync('sdkdocs').absolute;

/// Returns the number of (perhaps overlapping) occurrences of [str] in [match].
int _findCount(String str, Pattern match) {
  var count = 0;
  var index = str.indexOf(match);
  while (index != -1) {
    count++;
    index = str.indexOf(match, index + 1);
  }
  return count;
}

Future<String> _calcFilesSig(Directory dir,
    {required Set<String> extensions}) async {
  final digest = await _fileLines(dir, extensions: extensions)
      .transform(utf8.encoder)
      .transform(crypto.md5)
      .single;

  return digest.bytes
      .map((byte) => byte.toRadixString(16).padLeft(2, '0').toUpperCase())
      .join();
}

/// Returns a map of warning texts to the number of times each has been seen.
WarningsCollection _collectWarnings({
  required Iterable<Map<Object, Object?>> messages,
  required String tempPath,
  required String branch,
  String? pubDir,
}) {
  var warningTexts = WarningsCollection(tempPath, pubDir, branch);
  for (final message in messages) {
    if (message.containsKey('level') &&
        message['level'] == 'WARNING' &&
        message.containsKey('data')) {
      var data = message['data'] as Map;
      warningTexts.add(data['text'] as String);
    }
  }
  return warningTexts;
}
