// Copyright 2014 The Flutter Authors. 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:core' hide print;
import 'dart:io' hide exit;
import 'dart:typed_data';

import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:collection/equality.dart';
import 'package:crypto/crypto.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;

import 'allowlist.dart';
import 'custom_rules/analyze.dart';
import 'custom_rules/avoid_future_catcherror.dart';
import 'custom_rules/no_double_clamp.dart';
import 'custom_rules/no_stop_watches.dart';
import 'custom_rules/protect_public_state_subtypes.dart';
import 'custom_rules/render_box_intrinsics.dart';
import 'run_command.dart';
import 'utils.dart';

final String flutterPackages = path.join(flutterRoot, 'packages');
final String flutterExamples = path.join(flutterRoot, 'examples');

/// The path to the `dart` executable; set at the top of `main`
late final String dart;

/// The path to the `pub` executable; set at the top of `main`
late final String pub;

/// When you call this, you can pass additional arguments to pass custom
/// arguments to flutter analyze. For example, you might want to call this
/// script with the parameter --dart-sdk to use custom dart sdk.
///
/// For example:
/// bin/cache/dart-sdk/bin/dart dev/bots/analyze.dart --dart-sdk=/tmp/dart-sdk
Future<void> main(List<String> arguments) async {
  final String dartSdk = path.join(
    Directory.current.absolute.path,
    _getDartSdkFromArguments(arguments) ?? path.join(flutterRoot, 'bin', 'cache', 'dart-sdk'),
  );
  dart = path.join(dartSdk, 'bin', Platform.isWindows ? 'dart.exe' : 'dart');
  pub = path.join(dartSdk, 'bin', Platform.isWindows ? 'pub.bat' : 'pub');
  printProgress('STARTING ANALYSIS');
  await run(arguments);
  if (hasError) {
    reportErrorsAndExit('${bold}Analysis failed.$reset');
  }
  reportSuccessAndExit('${bold}Analysis successful.$reset');
}

/// Scans [arguments] for an argument of the form `--dart-sdk` or
/// `--dart-sdk=...` and returns the configured SDK, if any.
String? _getDartSdkFromArguments(List<String> arguments) {
  String? result;
  for (int i = 0; i < arguments.length; i += 1) {
    if (arguments[i] == '--dart-sdk') {
      if (result != null) {
        foundError(<String>['The --dart-sdk argument must not be used more than once.']);
        return null;
      }
      if (i + 1 < arguments.length) {
        result = arguments[i + 1];
      } else {
        foundError(<String>['--dart-sdk must be followed by a path.']);
        return null;
      }
    }
    if (arguments[i].startsWith('--dart-sdk=')) {
      if (result != null) {
        foundError(<String>['The --dart-sdk argument must not be used more than once.']);
        return null;
      }
      result = arguments[i].substring('--dart-sdk='.length);
    }
  }
  return result;
}

Future<void> run(List<String> arguments) async {
  bool assertsEnabled = false;
  assert(() {
    assertsEnabled = true;
    return true;
  }());
  if (!assertsEnabled) {
    foundError(<String>['The analyze.dart script must be run with --enable-asserts.']);
  }

  printProgress('Release branch validation');
  await verifyReleaseBranchState(flutterRoot);

  printProgress('TargetPlatform tool/framework consistency');
  await verifyTargetPlatform(flutterRoot);

  printProgress('All tool test files end in _test.dart...');
  await verifyToolTestsEndInTestDart(flutterRoot);

  printProgress('No sync*/async*');
  await verifyNoSyncAsyncStar(flutterPackages);
  await verifyNoSyncAsyncStar(flutterExamples, minimumMatches: 200);

  printProgress('No runtimeType in toString...');
  await verifyNoRuntimeTypeInToString(flutterRoot);

  printProgress('Debug mode instead of checked mode...');
  await verifyNoCheckedMode(flutterRoot);

  printProgress('Links for creating GitHub issues...');
  await verifyIssueLinks(flutterRoot);

  printProgress('Links to repositories...');
  await verifyRepositoryLinks(flutterRoot);

  printProgress('Unexpected binaries...');
  await verifyNoBinaries(flutterRoot);

  printProgress('Trailing spaces...');
  await verifyNoTrailingSpaces(
    flutterRoot,
  ); // assumes no unexpected binaries, so should be after verifyNoBinaries

  printProgress('Spaces after flow control statements...');
  await verifySpacesAfterFlowControlStatements(flutterRoot);

  printProgress('Deprecations...');
  await verifyDeprecations(flutterRoot);

  printProgress('Goldens...');
  await verifyGoldenTags(flutterPackages);

  printProgress('Skip test comments...');
  await verifySkipTestComments(flutterRoot);

  printProgress('Licenses...');
  await verifyNoMissingLicense(flutterRoot);

  printProgress('Test imports...');
  await verifyNoTestImports(flutterRoot);

  printProgress('Bad imports (framework)...');
  await verifyNoBadImportsInFlutter(flutterRoot);

  printProgress('Bad imports (tools)...');
  await verifyNoBadImportsInFlutterTools(flutterRoot);

  printProgress('Internationalization...');
  await verifyInternationalizations(flutterRoot, dart);

  printProgress('Localization files of stocks app...');
  await verifyStockAppLocalizations(flutterRoot);

  printProgress('Integration test timeouts...');
  await verifyIntegrationTestTimeouts(flutterRoot);

  printProgress('null initialized debug fields...');
  await verifyNullInitializedDebugExpensiveFields(flutterRoot);

  printProgress('Taboo words...');
  await verifyTabooDocumentation(flutterRoot);

  printProgress('Lint Kotlin files...');
  await lintKotlinFiles(flutterRoot);

  printProgress('Lint generated Kotlin files from templates...');
  await lintKotlinTemplatedFiles(flutterRoot);

  // Ensure that all package dependencies are in sync.
  printProgress('Package dependencies...');
  await runCommand(flutter, <String>['update-packages'], workingDirectory: flutterRoot);

  /// Ensure that no new dependencies have been accidentally
  /// added to core packages.
  printProgress('Package Allowlist...');
  await _checkConsumerDependencies();

  // Analyze all the Dart code in the repo.
  printProgress('Dart analysis...');
  final CommandResult dartAnalyzeResult = await _runFlutterAnalyze(
    flutterRoot,
    options: <String>['--flutter-repo', ...arguments],
  );

  printProgress('Check formatting of Dart files...');
  await runCommand(dart, <String>[
    '--enable-asserts',
    path.join(flutterRoot, 'dev', 'tools', 'bin', 'format.dart'),
  ], workingDirectory: flutterRoot);

  if (dartAnalyzeResult.exitCode == 0) {
    // Only run the private lints when the code is free of type errors. The
    // lints are easier to write when they can assume, for example, there is no
    // inheritance cycles.
    final List<AnalyzeRule> rules = <AnalyzeRule>[
      noDoubleClamp,
      noStopwatches,
      renderBoxIntrinsicCalculation,
      protectPublicStateSubtypes,
    ];
    final String ruleNames = rules.map((AnalyzeRule rule) => '\n * $rule').join();
    printProgress('Analyzing code in the framework with the following rules:$ruleNames');
    await analyzeWithRules(
      flutterRoot,
      rules,
      includePaths: const <String>['packages/flutter/lib'],
      excludePaths: const <String>['packages/flutter/lib/fix_data'],
    );
    final List<AnalyzeRule> testRules = <AnalyzeRule>[noStopwatches];
    final String testRuleNames = testRules.map((AnalyzeRule rule) => '\n * $rule').join();
    printProgress('Analyzing code in the test folder with the following rules:$testRuleNames');
    await analyzeWithRules(flutterRoot, testRules, includePaths: <String>['packages/flutter/test']);
    final List<AnalyzeRule> toolRules = <AnalyzeRule>[AvoidFutureCatchError()];
    final String toolRuleNames = toolRules.map((AnalyzeRule rule) => '\n * $rule').join();
    printProgress('Analyzing code in the tool with the following rules:$toolRuleNames');
    await analyzeWithRules(
      flutterRoot,
      toolRules,
      includePaths: const <String>['packages/flutter_tools/lib', 'packages/flutter_tools/test'],
    );
  } else {
    printProgress(
      'Skipped performing further analysis in the framework because "flutter analyze" finished with a non-zero exit code.',
    );
  }

  printProgress('Executable allowlist...');
  await _checkForNewExecutables();

  // Try with the --watch analyzer, to make sure it returns success also.
  // The --benchmark argument exits after one run.
  // We specify a failureMessage so that the actual output is muted in the case where _runFlutterAnalyze above already failed.
  printProgress('Dart analysis (with --watch)...');
  await _runFlutterAnalyze(
    flutterRoot,
    failureMessage: 'Dart analyzer failed when --watch was used.',
    options: <String>['--flutter-repo', '--watch', '--benchmark', ...arguments],
  );

  // Analyze the code in `{@tool snippet}` sections in the repo.
  printProgress('Snippet code...');
  await runCommand(dart, <String>[
    '--enable-asserts',
    path.join(flutterRoot, 'dev', 'bots', 'analyze_snippet_code.dart'),
    '--verbose',
  ], workingDirectory: flutterRoot);

  // Make sure that all of the existing samples are linked from at least one API doc comment.
  printProgress('Code sample link validation...');
  await runCommand(dart, <String>[
    '--enable-asserts',
    path.join(flutterRoot, 'dev', 'bots', 'check_code_samples.dart'),
  ], workingDirectory: flutterRoot);

  // Try analysis against a big version of the gallery; generate into a temporary directory.
  printProgress('Dart analysis (mega gallery)...');
  final Directory outDir = Directory.systemTemp.createTempSync('flutter_mega_gallery.');
  try {
    await runCommand(dart, <String>[
      path.join(flutterRoot, 'dev', 'tools', 'mega_gallery.dart'),
      '--out',
      outDir.path,
    ], workingDirectory: flutterRoot);
    await _runFlutterAnalyze(
      outDir.path,
      failureMessage: 'Dart analyzer failed on mega_gallery benchmark.',
      options: <String>['--watch', '--benchmark', ...arguments],
    );
  } finally {
    outDir.deleteSync(recursive: true);
  }

  // Ensure gen_default links the correct files
  printProgress('Correct file names in gen_defaults.dart...');
  await verifyTokenTemplatesUpdateCorrectFiles(flutterRoot);

  // Ensure material library files are up-to-date with the token template files.
  printProgress('Material library files are up-to-date with token template files...');
  await verifyMaterialFilesAreUpToDateWithTemplateFiles(flutterRoot, dart);

  // Ensure integration test files are up-to-date with the app template.
  printProgress('Up to date integration test template files...');
  await verifyIntegrationTestTemplateFiles(flutterRoot);
}

// TESTS

FeatureSet _parsingFeatureSet() => FeatureSet.latestLanguageVersion();

_Line _getLine(ParseStringResult parseResult, int offset) {
  final int lineNumber = parseResult.lineInfo.getLocation(offset).lineNumber;
  final String content = parseResult.content.substring(
    parseResult.lineInfo.getOffsetOfLine(lineNumber - 1),
    parseResult.lineInfo.getOffsetOfLine(lineNumber) - 1,
  );
  return _Line(lineNumber, content);
}

Future<void> verifyReleaseBranchState(String workringDirerctory) async {
  final ProcessResult result = await Process.run(dart, <String>[
    'bin/check_engine_version.dart',
  ], workingDirectory: path.join(workringDirerctory, 'dev', 'tools'));
  if (result.exitCode != 0) {
    foundError(<String>['${result.stderr}']);
  }
}

Future<void> verifyTargetPlatform(String workingDirectory) async {
  final File framework = File(
    '$workingDirectory/packages/flutter/lib/src/foundation/platform.dart',
  );
  final Set<String> frameworkPlatforms = <String>{};
  List<String> lines = framework.readAsLinesSync();
  int index = 0;
  while (true) {
    if (index >= lines.length) {
      foundError(<String>['${framework.path}: Can no longer find TargetPlatform enum.']);
      return;
    }
    if (lines[index].startsWith('enum TargetPlatform {')) {
      index += 1;
      break;
    }
    index += 1;
  }
  while (true) {
    if (index >= lines.length) {
      foundError(<String>['${framework.path}: Could not find end of TargetPlatform enum.']);
      return;
    }
    String line = lines[index].trim();
    final int comment = line.indexOf('//');
    if (comment >= 0) {
      line = line.substring(0, comment);
    }
    if (line == '}') {
      break;
    }
    if (line.isNotEmpty) {
      if (line.endsWith(',')) {
        frameworkPlatforms.add(line.substring(0, line.length - 1));
      } else {
        foundError(<String>[
          '${framework.path}:$index: unparseable line when looking for TargetPlatform values',
        ]);
      }
    }
    index += 1;
  }
  final File tool = File('$workingDirectory/packages/flutter_tools/lib/src/resident_runner.dart');
  final Set<String> toolPlatforms = <String>{};
  lines = tool.readAsLinesSync();
  index = 0;
  while (true) {
    if (index >= lines.length) {
      foundError(<String>['${tool.path}: Can no longer find nextPlatform logic.']);
      return;
    }
    if (lines[index].trim().startsWith('const platforms = <String>[')) {
      index += 1;
      break;
    }
    index += 1;
  }
  while (true) {
    if (index >= lines.length) {
      foundError(<String>['${tool.path}: Could not find end of nextPlatform logic.']);
      return;
    }
    final String line = lines[index].trim();
    if (line.startsWith("'") && line.endsWith("',")) {
      toolPlatforms.add(line.substring(1, line.length - 2));
    } else if (line == '];') {
      break;
    } else {
      foundError(<String>[
        '${tool.path}:$index: unparseable line when looking for nextPlatform values',
      ]);
    }
    index += 1;
  }
  final Set<String> frameworkExtra = frameworkPlatforms.difference(toolPlatforms);
  if (frameworkExtra.isNotEmpty) {
    foundError(<String>[
      'TargetPlatform has some extra values not found in the tool: ${frameworkExtra.join(", ")}',
    ]);
  }
  final Set<String> toolExtra = toolPlatforms.difference(frameworkPlatforms);
  if (toolExtra.isNotEmpty) {
    foundError(<String>[
      'The nextPlatform logic in the tool has some extra values not found in TargetPlatform: ${toolExtra.join(", ")}',
    ]);
  }
}

/// Verify Token Templates are mapped to correct file names while generating
/// M3 defaults in /dev/tools/gen_defaults/bin/gen_defaults.dart.
Future<void> verifyTokenTemplatesUpdateCorrectFiles(String workingDirectory) async {
  final List<String> errors = <String>[];

  String getMaterialDirPath(List<String> lines) {
    final String line = lines.firstWhere((String line) => line.contains('String materialLib'));
    final String relativePath = line.substring(line.indexOf("'") + 1, line.lastIndexOf("'"));
    return path.join(workingDirectory, relativePath);
  }

  String getFileName(String line) {
    const String materialLibString = r"'$materialLib/";
    final String leftClamp = line.substring(
      line.indexOf(materialLibString) + materialLibString.length,
    );
    return leftClamp.substring(0, leftClamp.indexOf("'"));
  }

  final String genDefaultsBinDir = '$workingDirectory/dev/tools/gen_defaults/bin';
  final File file = File(path.join(genDefaultsBinDir, 'gen_defaults.dart'));
  final List<String> lines = file.readAsLinesSync();
  final String materialDirPath = getMaterialDirPath(lines);
  bool atLeastOneTargetLineExists = false;

  for (final String line in lines) {
    if (line.contains('updateFile();')) {
      atLeastOneTargetLineExists = true;
      final String fileName = getFileName(line);
      final String filePath = path.join(materialDirPath, fileName);
      final File file = File(filePath);

      if (!file.existsSync()) {
        errors.add('file $filePath does not exist.');
      }
    }
  }

  assert(
    atLeastOneTargetLineExists,
    'No lines exist that this test expects to '
    'verify. Check if the target file is correct or remove this test',
  );

  // Fail if any errors
  if (errors.isNotEmpty) {
    final String s = errors.length > 1 ? 's' : '';
    final String itThem = errors.length > 1 ? 'them' : 'it';
    foundError(<String>[
      ...errors,
      '${bold}Please correct the file name$s or remove $itThem from /dev/tools/gen_defaults/bin/gen_defaults.dart$reset',
    ]);
  }
}

/// Verify Material library files are up-to-date with the token template files
/// when running /dev/tools/gen_defaults/bin/gen_defaults.dart.
Future<void> verifyMaterialFilesAreUpToDateWithTemplateFiles(
  String workingDirectory,
  String dartExecutable,
) async {
  final List<String> errors = <String>[];
  const String beginGeneratedComment = '// BEGIN GENERATED TOKEN PROPERTIES';

  String getMaterialDirPath(List<String> lines) {
    final String line = lines.firstWhere((String line) => line.contains('String materialLib'));
    final String relativePath = line.substring(line.indexOf("'") + 1, line.lastIndexOf("'"));
    return path.join(workingDirectory, relativePath);
  }

  String getFileName(String line) {
    const String materialLibString = r"'$materialLib/";
    final String leftClamp = line.substring(
      line.indexOf(materialLibString) + materialLibString.length,
    );
    return leftClamp.substring(0, leftClamp.indexOf("'"));
  }

  // Get the template generated code from the file.
  List<String> getGeneratedCode(List<String> lines) {
    return lines.skipWhile((String line) => !line.contains(beginGeneratedComment)).toList();
  }

  final String genDefaultsBinDir = '$workingDirectory/dev/tools/gen_defaults/bin';
  final File file = File(path.join(genDefaultsBinDir, 'gen_defaults.dart'));
  final List<String> lines = file.readAsLinesSync();
  final String materialDirPath = getMaterialDirPath(lines);
  final Map<String, List<String>> beforeGeneratedCode = <String, List<String>>{};
  final Map<String, List<String>> afterGeneratedCode = <String, List<String>>{};

  for (final String line in lines) {
    if (line.contains('updateFile();')) {
      final String fileName = getFileName(line);
      final String filePath = path.join(materialDirPath, fileName);
      final File file = File(filePath);
      beforeGeneratedCode[fileName] = getGeneratedCode(file.readAsLinesSync());
    }
  }

  // Run gen_defaults.dart to generate the token template files.
  await runCommand(dartExecutable, <String>[
    '--enable-asserts',
    path.join('dev', 'tools', 'gen_defaults', 'bin', 'gen_defaults.dart'),
  ], workingDirectory: workingDirectory);

  for (final String line in lines) {
    if (line.contains('updateFile();')) {
      final String fileName = getFileName(line);
      final String filePath = path.join(materialDirPath, fileName);
      final File file = File(filePath);
      afterGeneratedCode[fileName] = getGeneratedCode(file.readAsLinesSync());
    }
  }

  // Compare the generated code before and after running gen_defaults.dart.
  for (final String fileName in beforeGeneratedCode.keys) {
    final List<String> before = beforeGeneratedCode[fileName]!;
    final List<String> after = afterGeneratedCode[fileName]!;
    if (!const IterableEquality<String>().equals(before, after)) {
      errors.add('$fileName is not up-to-date with the token template file.');
    }
  }

  // Fail if any errors.
  if (errors.isNotEmpty) {
    foundError(<String>[
      ...errors,
      '${bold}See: https://github.com/flutter/flutter/blob/main/dev/tools/gen_defaults to update the token template files.$reset',
    ]);
  }
}

/// Verify tool test files end in `_test.dart`.
///
/// The test runner will only recognize files ending in `_test.dart` as tests to
/// be run: https://github.com/dart-lang/test/tree/master/pkgs/test#running-tests
Future<void> verifyToolTestsEndInTestDart(String workingDirectory) async {
  final String toolsTestPath = path.join(workingDirectory, 'packages', 'flutter_tools', 'test');
  final List<String> violations = <String>[];

  // detect files that contains calls to test(), testUsingContext(), and testWithoutContext()
  final RegExp callsTestFunctionPattern = RegExp(
    r'^ *(test\(.*\)|testUsingContext\(.*\)|testWithoutContext\(.*\))',
  );

  await for (final File file in _allFiles(toolsTestPath, 'dart', minimumMatches: 300)) {
    final bool isValidTestFile = file.path.endsWith('_test.dart');
    if (isValidTestFile) {
      continue;
    }

    final bool isTestData = file.path.contains(r'test_data');
    if (isTestData) {
      continue;
    }

    final bool isInTestShard = file.path.contains(r'.shard/');
    if (!isInTestShard) {
      continue;
    }

    final bool callsTestFunction = file.readAsStringSync().contains(callsTestFunctionPattern);
    if (!callsTestFunction) {
      continue;
    }

    violations.add(file.path);
  }
  if (violations.isNotEmpty) {
    foundError(<String>[
      '${bold}Found flutter_tools tests that do not end in `_test.dart`; these will not be run by the test runner$reset',
      ...violations,
    ]);
  }
}

Future<void> verifyNoSyncAsyncStar(String workingDirectory, {int minimumMatches = 2000}) async {
  final RegExp syncPattern = RegExp(r'\s*?a?sync\*\s*?{');
  final RegExp ignorePattern = RegExp(r'^\s*?// The following uses a?sync\* because:? ');
  final RegExp commentPattern = RegExp(r'^\s*?//');
  final List<String> errors = <String>[];
  await for (final File file in _allFiles(
    workingDirectory,
    'dart',
    minimumMatches: minimumMatches,
  )) {
    if (file.path.contains('test')) {
      continue;
    }
    final List<String> lines = file.readAsLinesSync();
    for (int index = 0; index < lines.length; index += 1) {
      final String line = lines[index];
      if (line.startsWith(commentPattern)) {
        continue;
      }
      if (line.contains(syncPattern)) {
        int lookBehindIndex = index - 1;
        bool hasExplanation = false;
        while (lookBehindIndex >= 0 && lines[lookBehindIndex].startsWith(commentPattern)) {
          if (lines[lookBehindIndex].startsWith(ignorePattern)) {
            hasExplanation = true;
            break;
          }
          lookBehindIndex -= 1;
        }
        if (!hasExplanation) {
          errors.add('${file.path}:$index: sync*/async* without an explanation.');
        }
      }
    }
  }
  if (errors.isNotEmpty) {
    foundError(<String>[
      '${bold}Do not use sync*/async* methods. See https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#avoid-syncasync for details.$reset',
      ...errors,
    ]);
  }
}

final RegExp _findGoldenTestPattern = RegExp(r'matchesGoldenFile\(');
final RegExp _findGoldenDefinitionPattern = RegExp(r'matchesGoldenFile\(Object');
final RegExp _leadingComment = RegExp(r'//');
final RegExp _goldenTagPattern1 = RegExp(r'@Tags\(');
final RegExp _goldenTagPattern2 = RegExp(r"'reduced-test-set'");

/// Only golden file tests in the flutter package are subject to reduced testing,
/// for example, invocations in flutter_test to validate comparator
/// functionality do not require tagging.
const String _ignoreGoldenTag = '// flutter_ignore: golden_tag (see analyze.dart)';
const String _ignoreGoldenTagForFile = '// flutter_ignore_for_file: golden_tag (see analyze.dart)';

Future<void> verifyGoldenTags(String workingDirectory, {int minimumMatches = 2000}) async {
  final List<String> errors = <String>[];
  await for (final File file in _allFiles(
    workingDirectory,
    'dart',
    minimumMatches: minimumMatches,
  )) {
    bool needsTag = false;
    bool hasTagNotation = false;
    bool hasReducedTag = false;
    bool ignoreForFile = false;
    final List<String> lines = file.readAsLinesSync();
    for (final String line in lines) {
      if (line.contains(_goldenTagPattern1)) {
        hasTagNotation = true;
      }
      if (line.contains(_goldenTagPattern2)) {
        hasReducedTag = true;
      }
      if (line.contains(_findGoldenTestPattern) &&
          !line.contains(_findGoldenDefinitionPattern) &&
          !line.contains(_leadingComment) &&
          !line.contains(_ignoreGoldenTag)) {
        needsTag = true;
      }
      if (line.contains(_ignoreGoldenTagForFile)) {
        ignoreForFile = true;
      }
      // If the file is being ignored or a reduced test tag is already accounted
      // for, skip parsing the rest of the lines for golden file tests.
      if (ignoreForFile || (hasTagNotation && hasReducedTag)) {
        break;
      }
    }
    // If a reduced test tag is already accounted for, move on to the next file.
    if (ignoreForFile || (hasTagNotation && hasReducedTag)) {
      continue;
    }
    // If there are golden file tests, ensure they are tagged for all reduced
    // test environments.
    if (needsTag) {
      if (!hasTagNotation) {
        errors.add(
          '${file.path}: Files containing golden tests must be tagged using '
          "@Tags(<String>['reduced-test-set']) at the top of the file before import statements.",
        );
      } else if (!hasReducedTag) {
        errors.add(
          '${file.path}: Files containing golden tests must be tagged with '
          "'reduced-test-set'.",
        );
      }
    }
  }
  if (errors.isNotEmpty) {
    foundError(<String>[
      ...errors,
      '${bold}See: https://github.com/flutter/flutter/blob/main/docs/contributing/testing/Writing-a-golden-file-test-for-package-flutter.md$reset',
    ]);
  }
}

class _DeprecationMessagesVisitor extends RecursiveAstVisitor<void> {
  _DeprecationMessagesVisitor(this.parseResult, this.filePath);

  final ParseStringResult parseResult;
  final String filePath;
  final List<String> errors = <String>[];

  /// Some deprecation notices are special, for example they're used to annotate members that
  /// will never go away and were never allowed but which we are trying to show messages for.
  /// (One example would be a library that intentionally conflicts with a member in another
  /// library to indicate that it is incompatible with that other library. Another would be
  /// the regexp just above...)
  static const Pattern ignoreDeprecration =
      '// flutter_ignore: deprecation_syntax (see analyze.dart)';

  /// Some deprecation notices are exempt for historical reasons. They must have an issue listed.
  static final RegExp legacyDeprecation = RegExp(
    r'// flutter_ignore: deprecation_syntax, https://github.com/flutter/flutter/issues/\d+',
  );

  static final RegExp deprecationVersionPattern = RegExp(
    r'This feature was deprecated after v(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)(?<build>-\d+\.\d+\.pre)?\.$',
  );

  void _addErrorWithLineInfo(AstNode node, {required String error}) {
    final int lineNumber = parseResult.lineInfo.getLocation(node.offset).lineNumber;
    errors.add('$filePath:$lineNumber: $error');
  }

  @override
  void visitAnnotation(Annotation node) {
    super.visitAnnotation(node);
    final bool shouldCheckAnnotation =
        node.name.name == 'Deprecated' &&
        !hasInlineIgnore(node, parseResult, ignoreDeprecration) &&
        !hasInlineIgnore(node, parseResult, legacyDeprecation);
    if (!shouldCheckAnnotation) {
      return;
    }
    final NodeList<Expression>? arguments = node.arguments?.arguments;
    if (arguments == null || arguments.length != 1) {
      _addErrorWithLineInfo(
        node,
        error: 'A @Deprecation annotation must have exactly one deprecation notice String.',
      );
      return;
    }
    final Expression deprecationNotice = arguments.first;
    if (deprecationNotice is! AdjacentStrings) {
      _addErrorWithLineInfo(node, error: 'Deprecation notice must be an adjacent string.');
      return;
    }
    final List<StringLiteral> strings = deprecationNotice.strings;
    final Iterator<StringLiteral> deprecationMessageIterator = strings.iterator;
    final bool isNotEmpty = deprecationMessageIterator.moveNext();
    assert(isNotEmpty); // An AdjacentString always has 2 or more string literals.

    final [...List<StringLiteral> messageLiterals, StringLiteral versionLiteral] = strings;

    // Verify the version literal has the correct pattern.
    final RegExpMatch? versionMatch = versionLiteral is SimpleStringLiteral
        ? deprecationVersionPattern.firstMatch(versionLiteral.value)
        : null;
    if (versionMatch == null) {
      _addErrorWithLineInfo(
        versionLiteral,
        error:
            'Deprecation notice must end with a line saying "This feature was deprecated after...".',
      );
      return;
    }

    final int major = int.parse(versionMatch.namedGroup('major')!);
    final int minor = int.parse(versionMatch.namedGroup('minor')!);
    final int patch = int.parse(versionMatch.namedGroup('patch')!);
    final bool hasBuild = versionMatch.namedGroup('build') != null;
    // There was a beta release that was mistakenly labeled 3.1.0 without a build.
    final bool specialBeta = major == 3 && minor == 1 && patch == 0;
    if (!specialBeta && (major > 1 || (major == 1 && minor >= 20))) {
      if (!hasBuild) {
        _addErrorWithLineInfo(
          versionLiteral,
          error:
              'Deprecation notice does not accurately indicate a beta branch version number; please see https://flutter.dev/docs/development/tools/sdk/releases to find the latest beta build version number.',
        );
        return;
      }
    }

    // Verify the version literal has the correct pattern.
    assert(messageLiterals.isNotEmpty); // An AdjacentString always has 2 or more string literals.
    for (final StringLiteral message in messageLiterals) {
      if (message is! SingleStringLiteral) {
        _addErrorWithLineInfo(
          message,
          error: 'Deprecation notice does not match required pattern.',
        );
        return;
      }
      if (!message.isSingleQuoted) {
        _addErrorWithLineInfo(
          message,
          error:
              'Deprecation notice does not match required pattern. You might have used double quotes (") for the string instead of single quotes (\').',
        );
        return;
      }
    }
    final String fullExplanation = messageLiterals
        .map((StringLiteral message) => message.stringValue ?? '')
        .join()
        .trimRight();
    if (fullExplanation.isEmpty) {
      _addErrorWithLineInfo(
        messageLiterals.last,
        error:
            'Deprecation notice should be a grammatically correct sentence and end with a period; There might not be an explanatory message.',
      );
      return;
    }
    final String firstChar = String.fromCharCode(fullExplanation.runes.first);
    if (firstChar.toUpperCase() != firstChar) {
      _addErrorWithLineInfo(
        messageLiterals.first,
        error:
            'Deprecation notice should be a grammatically correct sentence and start with a capital letter; see style guide: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md',
      );
      return;
    }
    if (!fullExplanation.endsWith('.') &&
        !fullExplanation.endsWith('?') &&
        !fullExplanation.endsWith('!')) {
      _addErrorWithLineInfo(
        messageLiterals.last,
        error:
            'Deprecation notice should be a grammatically correct sentence and end with a period; notice appears to be "$fullExplanation".',
      );
      return;
    }
  }
}

Future<void> verifyDeprecations(String workingDirectory, {int minimumMatches = 2000}) async {
  final List<String> errors = <String>[];
  await for (final File file in _allFiles(
    workingDirectory,
    'dart',
    minimumMatches: minimumMatches,
  )) {
    final ParseStringResult parseResult = parseFile(
      featureSet: _parsingFeatureSet(),
      path: file.absolute.path,
    );
    final _DeprecationMessagesVisitor visitor = _DeprecationMessagesVisitor(parseResult, file.path);
    visitor.visitCompilationUnit(parseResult.unit);
    errors.addAll(visitor.errors);
  }
  // Fail if any errors
  if (errors.isNotEmpty) {
    foundError(<String>[
      ...errors,
      '${bold}See: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes$reset',
    ]);
  }
}

String _generateLicense(String prefix) {
  return '${prefix}Copyright 2014 The Flutter Authors. All rights reserved.\n'
      '${prefix}Use of this source code is governed by a BSD-style license that can be\n'
      '${prefix}found in the LICENSE file.';
}

Future<void> verifyNoMissingLicense(String workingDirectory, {bool checkMinimums = true}) async {
  final int? overrideMinimumMatches = checkMinimums ? null : 0;
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'dart',
    overrideMinimumMatches ?? 2000,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'java',
    overrideMinimumMatches ?? 1,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'h',
    overrideMinimumMatches ?? 30,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'm',
    overrideMinimumMatches ?? 30,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'cc',
    overrideMinimumMatches ?? 10,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'cpp',
    overrideMinimumMatches ?? 0,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'swift',
    overrideMinimumMatches ?? 10,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'gradle',
    overrideMinimumMatches ?? 80,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'gn',
    overrideMinimumMatches ?? 0,
    _generateLicense('# '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'sh',
    overrideMinimumMatches ?? 1,
    _generateLicense('# '),
    header: r'#!/usr/bin/env bash\n',
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'bat',
    overrideMinimumMatches ?? 1,
    _generateLicense('REM '),
    header: r'@ECHO off\n',
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'ps1',
    overrideMinimumMatches ?? 1,
    _generateLicense('# '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'html',
    overrideMinimumMatches ?? 1,
    '<!-- ${_generateLicense('')} -->',
    trailingBlank: false,
    header: r'<!DOCTYPE HTML>\n',
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'xml',
    overrideMinimumMatches ?? 1,
    '<!-- ${_generateLicense('')} -->',
    header: r'(<\?xml version="1.0" encoding="utf-8"\?>\n)?',
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'frag',
    overrideMinimumMatches ?? 1,
    _generateLicense('// '),
    header: r'#version 320 es(\n)+',
  );
}

Future<void> _verifyNoMissingLicenseForExtension(
  String workingDirectory,
  String extension,
  int minimumMatches,
  String license, {
  bool trailingBlank = true,
  // The "header" is a regular expression matching the header that comes before
  // the license in some files.
  String header = '',
}) async {
  assert(!license.endsWith('\n'));
  final String licensePattern = RegExp.escape('$license\n${trailingBlank ? '\n' : ''}');
  final List<String> errors = <String>[];
  await for (final File file in _allFiles(
    workingDirectory,
    extension,
    minimumMatches: minimumMatches,
  )) {
    final String contents = file.readAsStringSync().replaceAll('\r\n', '\n');
    if (contents.isEmpty) {
      continue; // let's not go down the /bin/true rabbit hole
    }
    if (path.basename(file.path) == 'Package.swift') {
      continue;
    }
    if (!contents.startsWith(RegExp(header + licensePattern))) {
      errors.add(file.path);
    }
  }
  // Fail if any errors
  if (errors.isNotEmpty) {
    final String fileDoes = errors.length == 1 ? 'file does' : '${errors.length} files do';
    foundError(<String>[
      '${bold}The following $fileDoes not have the right license header for $extension files:$reset',
      ...errors.map<String>((String error) => '  $error'),
      'The expected license header is:',
      if (header.isNotEmpty) 'A header matching the regular expression "$header",',
      if (header.isNotEmpty) 'followed by the following license text:',
      license,
      if (trailingBlank) '...followed by a blank line.',
    ]);
  }
}

class _Line {
  _Line(this.line, this.content);

  final int line;
  final String content;
}

Iterable<_Line> _getTestSkips(File file) {
  final ParseStringResult parseResult = parseFile(
    featureSet: _parsingFeatureSet(),
    path: file.absolute.path,
  );
  final _TestSkipLinesVisitor<CompilationUnit> visitor = _TestSkipLinesVisitor<CompilationUnit>(
    parseResult,
  );
  visitor.visitCompilationUnit(parseResult.unit);
  return visitor.skips;
}

class _TestSkipLinesVisitor<T> extends RecursiveAstVisitor<T> {
  _TestSkipLinesVisitor(this.parseResult) : skips = <_Line>{};

  final ParseStringResult parseResult;
  final Set<_Line> skips;

  static bool isTestMethod(String name) {
    return name.startsWith('test') || name == 'group' || name == 'expect';
  }

  static final Pattern _skipTestIntentionalPattern = RegExp(r'// .*[intended]');
  static final Pattern _skipTestTrackingBugPattern = RegExp(
    r'// .*https+?://github.com/.*/issues/\d+',
  );
  bool _hasValidJustificationComment(Label skipLabel) {
    return hasInlineIgnore(skipLabel, parseResult, _skipTestIntentionalPattern) ||
        hasInlineIgnore(skipLabel, parseResult, _skipTestTrackingBugPattern);
  }

  @override
  T? visitMethodInvocation(MethodInvocation node) {
    if (isTestMethod(node.methodName.toString())) {
      for (final Expression argument in node.argumentList.arguments) {
        if (argument is NamedExpression &&
            argument.name.label.name == 'skip' &&
            !_hasValidJustificationComment(argument.name)) {
          skips.add(_getLine(parseResult, argument.beginToken.charOffset));
        }
      }
    }
    return super.visitMethodInvocation(node);
  }
}

Future<void> verifySkipTestComments(String workingDirectory) async {
  final List<String> errors = <String>[];
  final Stream<File> testFiles = _allFiles(
    workingDirectory,
    'dart',
    minimumMatches: 1500,
  ).where((File f) => f.path.endsWith('_test.dart'));

  await for (final File file in testFiles) {
    for (final _Line skip in _getTestSkips(file)) {
      errors.add('${file.path}:${skip.line}: skip test without a justification comment.');
    }
  }

  // Fail if any errors
  if (errors.isNotEmpty) {
    foundError(<String>[
      ...errors,
      '\n${bold}See: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#skipped-tests$reset',
    ]);
  }
}

final RegExp _testImportPattern = RegExp(r'''import (['"])([^'"]+_test\.dart)\1''');
const Set<String> _exemptTestImports = <String>{
  'package:flutter_test/flutter_test.dart',
  'hit_test.dart',
  'package:test_api/src/backend/live_test.dart',
  'package:integration_test/integration_test.dart',
};

Future<void> verifyNoTestImports(String workingDirectory) async {
  final List<String> errors = <String>[];
  assert("// foo\nimport 'binding_test.dart' as binding;\n'".contains(_testImportPattern));
  final List<File> dartFiles = await _allFiles(
    path.join(workingDirectory, 'packages'),
    'dart',
    minimumMatches: 1500,
  ).toList();
  for (final File file in dartFiles) {
    for (final String line in file.readAsLinesSync()) {
      final Match? match = _testImportPattern.firstMatch(line);
      if (match != null && !_exemptTestImports.contains(match.group(2))) {
        errors.add(file.path);
      }
    }
  }
  // Fail if any errors
  if (errors.isNotEmpty) {
    foundError(<String>[
      '${bold}The following file(s) import a test directly. Test utilities should be in their own file.$reset',
      ...errors,
    ]);
  }
}

Future<void> verifyNoBadImportsInFlutter(String workingDirectory) async {
  final List<String> errors = <String>[];
  final String libPath = path.join(workingDirectory, 'packages', 'flutter', 'lib');
  final String srcPath = path.join(workingDirectory, 'packages', 'flutter', 'lib', 'src');
  // Verify there's one libPath/*.dart for each srcPath/*/.
  final List<String> packages =
      Directory(libPath)
          .listSync()
          .where(
            (FileSystemEntity entity) => entity is File && path.extension(entity.path) == '.dart',
          )
          .map<String>((FileSystemEntity entity) => path.basenameWithoutExtension(entity.path))
          .toList()
        ..sort();
  final List<String> directories =
      Directory(srcPath)
          .listSync()
          .whereType<Directory>()
          .map<String>((Directory entity) => path.basename(entity.path))
          .toList()
        ..sort();
  if (!_listEquals<String>(packages, directories)) {
    errors.add(
      <String>[
        'flutter/lib/*.dart does not match flutter/lib/src/*/:',
        'These are the exported packages:',
        ...packages.map<String>((String path) => '  lib/$path.dart'),
        'These are the directories:',
        ...directories.map<String>((String path) => '  lib/src/$path/'),
      ].join('\n'),
    );
  }
  // Verify that the imports are well-ordered.
  final Map<String, Set<String>> dependencyMap = <String, Set<String>>{};
  for (final String directory in directories) {
    dependencyMap[directory] = await _findFlutterDependencies(
      path.join(srcPath, directory),
      errors,
      checkForMeta: directory != 'foundation',
    );
  }
  assert(
    dependencyMap['material']!.contains('widgets') &&
        dependencyMap['widgets']!.contains('rendering') &&
        dependencyMap['rendering']!.contains('painting'),
  ); // to make sure we're convinced _findFlutterDependencies is finding some
  for (final String package in dependencyMap.keys) {
    if (dependencyMap[package]!.contains(package)) {
      errors.add(
        'One of the files in the $yellow$package$reset package imports that package recursively.',
      );
    }
  }

  for (final String key in dependencyMap.keys) {
    for (final String dependency in dependencyMap[key]!) {
      if (dependencyMap[dependency] != null) {
        continue;
      }
      // Sanity check before performing _deepSearch, to ensure there's no rogue
      // dependencies.
      final String validFilenames = dependencyMap.keys
          .map((String name) => '$name.dart')
          .join(', ');
      errors.add(
        '$key imported package:flutter/$dependency.dart '
        'which is not one of the valid exports { $validFilenames }.\n'
        'Consider changing $dependency.dart to one of them.',
      );
    }
  }

  for (final String package in dependencyMap.keys) {
    final List<String>? loop = _deepSearch<String>(dependencyMap, package);
    if (loop != null) {
      errors.add('${yellow}Dependency loop:$reset ${loop.join(' depends on ')}');
    }
  }
  // Fail if any errors
  if (errors.isNotEmpty) {
    foundError(<String>[
      if (errors.length == 1)
        '${bold}An error was detected when looking at import dependencies within the Flutter package:$reset'
      else
        '${bold}Multiple errors were detected when looking at import dependencies within the Flutter package:$reset',
      ...errors,
    ]);
  }
}

Future<void> verifyNoBadImportsInFlutterTools(String workingDirectory) async {
  final List<String> errors = <String>[];
  final List<File> files = await _allFiles(
    path.join(workingDirectory, 'packages', 'flutter_tools', 'lib'),
    'dart',
    minimumMatches: 200,
  ).toList();
  for (final File file in files) {
    if (file.readAsStringSync().contains('package:flutter_tools/')) {
      errors.add('$yellow${file.path}$reset imports flutter_tools.');
    }
  }
  // Fail if any errors
  if (errors.isNotEmpty) {
    foundError(<String>[
      if (errors.length == 1)
        '${bold}An error was detected when looking at import dependencies within the flutter_tools package:$reset'
      else
        '${bold}Multiple errors were detected when looking at import dependencies within the flutter_tools package:$reset',
      ...errors.map((String paragraph) => '$paragraph\n'),
    ]);
  }
}

Future<void> verifyIntegrationTestTimeouts(String workingDirectory) async {
  final List<String> errors = <String>[];
  final String dev = path.join(workingDirectory, 'dev');
  final List<File> files = await _allFiles(dev, 'dart', minimumMatches: 1)
      .where(
        (File file) =>
            file.path.contains('test_driver') &&
            (file.path.endsWith('_test.dart') || file.path.endsWith('util.dart')),
      )
      .toList();
  for (final File file in files) {
    final String contents = file.readAsStringSync();
    final int testCount = ' test('.allMatches(contents).length;
    final int timeoutNoneCount = 'timeout: Timeout.none'.allMatches(contents).length;
    if (testCount != timeoutNoneCount) {
      errors.add(
        '$yellow${file.path}$reset has at least $testCount test(s) but only $timeoutNoneCount `Timeout.none`(s).',
      );
    }
  }
  if (errors.isNotEmpty) {
    foundError(<String>[
      if (errors.length == 1)
        '${bold}An error was detected when looking at integration test timeouts:$reset'
      else
        '${bold}Multiple errors were detected when looking at integration test timeouts:$reset',
      ...errors.map((String paragraph) => '$paragraph\n'),
    ]);
  }
}

Future<void> verifyInternationalizations(String workingDirectory, String dartExecutable) async {
  final EvalResult materialGenResult = await _evalCommand(dartExecutable, <String>[
    path.join('dev', 'tools', 'localization', 'bin', 'gen_localizations.dart'),
    '--material',
    '--remove-undefined',
  ], workingDirectory: workingDirectory);
  final EvalResult cupertinoGenResult = await _evalCommand(dartExecutable, <String>[
    path.join('dev', 'tools', 'localization', 'bin', 'gen_localizations.dart'),
    '--cupertino',
    '--remove-undefined',
  ], workingDirectory: workingDirectory);

  final String materialLocalizationsFile = path.join(
    workingDirectory,
    'packages',
    'flutter_localizations',
    'lib',
    'src',
    'l10n',
    'generated_material_localizations.dart',
  );
  final String cupertinoLocalizationsFile = path.join(
    workingDirectory,
    'packages',
    'flutter_localizations',
    'lib',
    'src',
    'l10n',
    'generated_cupertino_localizations.dart',
  );
  final String expectedMaterialResult = await File(materialLocalizationsFile).readAsString();
  final String expectedCupertinoResult = await File(cupertinoLocalizationsFile).readAsString();

  if (materialGenResult.stdout.trim() != expectedMaterialResult.trim()) {
    foundError(<String>[
      '<<<<<<< $materialLocalizationsFile',
      expectedMaterialResult.trim(),
      '=======',
      materialGenResult.stdout.trim(),
      '>>>>>>> gen_localizations',
      'The contents of $materialLocalizationsFile are different from that produced by gen_localizations.',
      '',
      'Did you forget to run gen_localizations.dart after updating a .arb file?',
    ]);
  }
  if (cupertinoGenResult.stdout.trim() != expectedCupertinoResult.trim()) {
    foundError(<String>[
      '<<<<<<< $cupertinoLocalizationsFile',
      expectedCupertinoResult.trim(),
      '=======',
      cupertinoGenResult.stdout.trim(),
      '>>>>>>> gen_localizations',
      'The contents of $cupertinoLocalizationsFile are different from that produced by gen_localizations.',
      '',
      'Did you forget to run gen_localizations.dart after updating a .arb file?',
    ]);
  }
}

Future<void> verifyStockAppLocalizations(String workingDirectory) async {
  final Directory appRoot = Directory(
    path.join(workingDirectory, 'dev', 'benchmarks', 'test_apps', 'stocks'),
  );
  if (!appRoot.existsSync()) {
    foundError(<String>['Stocks app does not exist at expected location: ${appRoot.path}']);
  }

  // Regenerate the localizations.
  final String flutterExecutable = path.join(
    workingDirectory,
    'bin',
    'flutter${Platform.isWindows ? '.bat' : ''}',
  );
  await _evalCommand(flutterExecutable, const <String>['gen-l10n'], workingDirectory: appRoot.path);
  final Directory i10nDirectory = Directory(path.join(appRoot.path, 'lib', 'i18n'));
  if (!i10nDirectory.existsSync()) {
    foundError(<String>[
      'Localization files for stocks app not found at expected location: ${i10nDirectory.path}',
    ]);
  }

  // Check that regeneration did not dirty the tree.
  final EvalResult result = await _evalCommand('git', <String>[
    'diff',
    '--name-only',
    '--exit-code',
    i10nDirectory.path,
  ], workingDirectory: workingDirectory);
  if (result.exitCode == 1) {
    foundError(<String>[
      'The following localization files for the stocks app appear to be out of date:',
      ...(const LineSplitter().convert(result.stdout).map((String line) => ' * $line')),
      'Run "flutter gen-l10n" in "${path.relative(appRoot.path, from: workingDirectory)}" to regenerate.',
    ]);
  } else if (result.exitCode != 0) {
    foundError(<String>[
      'Failed to run "git diff" on localization files of stocks app:',
      result.stderr,
    ]);
  }
}

/// Verifies that all instances of "checked mode" have been migrated to "debug mode".
Future<void> verifyNoCheckedMode(String workingDirectory) async {
  final String flutterPackages = path.join(workingDirectory, 'packages');
  final List<File> files = await _allFiles(
    flutterPackages,
    'dart',
    minimumMatches: 400,
  ).where((File file) => path.extension(file.path) == '.dart').toList();
  final List<String> problems = <String>[];
  for (final File file in files) {
    int lineCount = 0;
    for (final String line in file.readAsLinesSync()) {
      if (line.toLowerCase().contains('checked mode')) {
        problems.add(
          '${file.path}:$lineCount uses deprecated "checked mode" instead of "debug mode".',
        );
      }
      lineCount += 1;
    }
  }
  if (problems.isNotEmpty) {
    foundError(problems);
  }
}

Future<void> verifyNoRuntimeTypeInToString(String workingDirectory) async {
  final String flutterLib = path.join(workingDirectory, 'packages', 'flutter', 'lib');
  final Set<String> excludedFiles = <String>{
    path.join(flutterLib, 'src', 'foundation', 'object.dart'), // Calls this from within an assert.
  };
  final List<File> files = await _allFiles(
    flutterLib,
    'dart',
    minimumMatches: 400,
  ).where((File file) => !excludedFiles.contains(file.path)).toList();
  final RegExp toStringRegExp = RegExp(r'^\s+String\s+to(.+?)?String(.+?)?\(\)\s+(\{|=>)');
  final List<String> problems = <String>[];
  for (final File file in files) {
    final List<String> lines = file.readAsLinesSync();
    for (int index = 0; index < lines.length; index++) {
      if (toStringRegExp.hasMatch(lines[index])) {
        final int sourceLine = index + 1;
        bool checkForRuntimeType(String line) {
          if (line.contains(r'$runtimeType') || line.contains('runtimeType.toString()')) {
            problems.add('${file.path}:$sourceLine}: toString calls runtimeType.toString');
            return true;
          }
          return false;
        }

        if (checkForRuntimeType(lines[index])) {
          continue;
        }
        if (lines[index].contains('=>')) {
          while (!lines[index].contains(';')) {
            index++;
            assert(index < lines.length, 'Source file $file has unterminated toString method.');
            if (checkForRuntimeType(lines[index])) {
              break;
            }
          }
        } else {
          int openBraceCount =
              '{'.allMatches(lines[index]).length - '}'.allMatches(lines[index]).length;
          while (!lines[index].contains('}') && openBraceCount > 0) {
            index++;
            assert(
              index < lines.length,
              'Source file $file has unbalanced braces in a toString method.',
            );
            if (checkForRuntimeType(lines[index])) {
              break;
            }
            openBraceCount += '{'.allMatches(lines[index]).length;
            openBraceCount -= '}'.allMatches(lines[index]).length;
          }
        }
      }
    }
  }
  if (problems.isNotEmpty) {
    foundError(problems);
  }
}

Future<void> verifyNoTrailingSpaces(String workingDirectory, {int minimumMatches = 4000}) async {
  final List<File> files = await _allFiles(workingDirectory, null, minimumMatches: minimumMatches)
      .where((File file) => path.basename(file.path) != 'serviceaccount.enc')
      .where((File file) => path.basename(file.path) != 'Ahem.ttf')
      .where((File file) => path.extension(file.path) != '.snapshot')
      .where((File file) => path.extension(file.path) != '.png')
      .where((File file) => path.extension(file.path) != '.jpg')
      .where((File file) => path.extension(file.path) != '.ico')
      .where((File file) => path.extension(file.path) != '.jar')
      .where((File file) => path.extension(file.path) != '.swp')
      .toList();
  final List<String> problems = <String>[];
  for (final File file in files) {
    final List<String> lines = file.readAsLinesSync();
    for (int index = 0; index < lines.length; index += 1) {
      if (lines[index].endsWith(' ')) {
        problems.add('${file.path}:${index + 1}: trailing U+0020 space character');
      } else if (lines[index].endsWith('\t')) {
        problems.add('${file.path}:${index + 1}: trailing U+0009 tab character');
      }
    }
    if (lines.isNotEmpty && lines.last == '') {
      problems.add('${file.path}:${lines.length}: trailing blank line');
    }
  }
  if (problems.isNotEmpty) {
    foundError(problems);
  }
}

final RegExp _flowControlStatementWithoutSpace = RegExp(
  r'(^|[ \t])(if|switch|for|do|while|catch)\(',
  multiLine: true,
);

Future<void> verifySpacesAfterFlowControlStatements(
  String workingDirectory, {
  int minimumMatches = 4000,
}) async {
  const Set<String> extensions = <String>{
    // .dart omitted from this list because the Dart auto formatter ensures
    // spaces after flow control statements.
    '.java',
    '.js',
    '.kt',
    '.swift',
    '.c',
    '.cc',
    '.cpp',
    '.h',
    '.m',
  };
  final List<File> files = await _allFiles(
    workingDirectory,
    null,
    minimumMatches: minimumMatches,
  ).where((File file) => extensions.contains(path.extension(file.path))).toList();
  final List<String> problems = <String>[];
  for (final File file in files) {
    final List<String> lines = file.readAsLinesSync();
    for (int index = 0; index < lines.length; index += 1) {
      if (lines[index].contains(_flowControlStatementWithoutSpace)) {
        problems.add('${file.path}:${index + 1}: no space after flow control statement');
      }
    }
  }
  if (problems.isNotEmpty) {
    foundError(problems);
  }
}

String _bullets(String value) => ' * $value';

Future<void> verifyIssueLinks(String workingDirectory) async {
  const String issueLinkPrefix = 'https://github.com/flutter/flutter/issues/new';
  const Set<String> stops = <String>{'\n', ' ', "'", '"', r'\', ')', '>'};
  assert(
    !stops.contains('.'),
  ); // instead of "visit https://foo." say "visit: https://foo", it copy-pastes better
  const String kGiveTemplates =
      'Prefer to provide a link either to $issueLinkPrefix/choose (the list of issue '
      'templates) or to a specific template directly ($issueLinkPrefix?template=...).\n';
  final Set<String> templateNames =
      Directory(path.join(workingDirectory, '.github', 'ISSUE_TEMPLATE'))
          .listSync()
          .whereType<File>()
          .where(
            (File file) =>
                path.extension(file.path) == '.md' || path.extension(file.path) == '.yml',
          )
          .map<String>((File file) => path.basename(file.path))
          .toSet();
  final String kTemplates =
      'The available templates are:\n${templateNames.map(_bullets).join("\n")}';
  final List<String> problems = <String>[];
  final Set<String> suggestions = <String>{};
  final List<File> files = await _gitFiles(workingDirectory);
  for (final File file in files) {
    if (path.basename(file.path).endsWith('_test.dart') ||
        path.basename(file.path) == 'analyze.dart') {
      continue; // Skip tests, they're not public-facing.
    }
    final Uint8List bytes = file.readAsBytesSync();
    // We allow invalid UTF-8 here so that binaries don't trip us up.
    // There's a separate test in this file that verifies that all text
    // files are actually valid UTF-8 (see verifyNoBinaries below).
    final String contents = utf8.decode(bytes, allowMalformed: true);
    int start = 0;
    while ((start = contents.indexOf(issueLinkPrefix, start)) >= 0) {
      int end = start + issueLinkPrefix.length;
      while (end < contents.length && !stops.contains(contents[end])) {
        end += 1;
      }
      final String url = contents.substring(start, end);
      if (url == issueLinkPrefix) {
        if (file.path != path.join(workingDirectory, 'dev', 'bots', 'analyze.dart')) {
          problems.add('${file.path} contains a direct link to $issueLinkPrefix.');
          suggestions.add(kGiveTemplates);
          suggestions.add(kTemplates);
        }
      } else if (url.startsWith('$issueLinkPrefix?')) {
        final Uri parsedUrl = Uri.parse(url);
        final List<String>? templates = parsedUrl.queryParametersAll['template'];
        if (templates == null) {
          problems.add('${file.path} contains $url, which has no "template" argument specified.');
          suggestions.add(kGiveTemplates);
          suggestions.add(kTemplates);
        } else if (templates.length != 1) {
          problems.add(
            '${file.path} contains $url, which has ${templates.length} templates specified.',
          );
          suggestions.add(kGiveTemplates);
          suggestions.add(kTemplates);
        } else if (!templateNames.contains(templates.single)) {
          problems.add(
            '${file.path} contains $url, which specifies a non-existent template ("${templates.single}").',
          );
          suggestions.add(kTemplates);
        } else if (parsedUrl.queryParametersAll.keys.length > 1) {
          problems.add(
            '${file.path} contains $url, which the analyze.dart script is not sure how to handle.',
          );
          suggestions.add(
            'Update analyze.dart to handle the URLs above, or change them to the expected pattern.',
          );
        }
      } else if (url != '$issueLinkPrefix/choose') {
        problems.add(
          '${file.path} contains $url, which the analyze.dart script is not sure how to handle.',
        );
        suggestions.add(
          'Update analyze.dart to handle the URLs above, or change them to the expected pattern.',
        );
      }
      start = end;
    }
  }
  assert(problems.isEmpty == suggestions.isEmpty);
  if (problems.isNotEmpty) {
    foundError(<String>[...problems, ...suggestions]);
  }
}

Future<void> verifyRepositoryLinks(String workingDirectory) async {
  const Set<String> stops = <String>{'\n', ' ', "'", '"', r'\', ')', '>'};
  assert(
    !stops.contains('.'),
  ); // instead of "visit https://foo." say "visit: https://foo", it copy-pastes better

  // Repos whose default branch is still 'master'
  const Set<String> repoExceptions = <String>{
    'chromium/chromium',
    'clojure/clojure',
    'dart-lang/test', // TODO(guidezpl): remove when https://github.com/dart-lang/test/issues/2209 is closed
    'eseidelGoogle/bezier_perf',
    'flutter/devtools', // TODO(guidezpl): remove when https://github.com/flutter/devtools/issues/7551 is closed
    'flutter/flutter-intellij', // TODO(guidezpl): remove when https://github.com/flutter/flutter-intellij/issues/7342 is closed
    'flutter/platform_tests', // TODO(guidezpl): remove when subtask in https://github.com/flutter/flutter/issues/121564 is complete
    'flutter/web_installers',
    'glfw/glfw',
    'GoogleCloudPlatform/artifact-registry-maven-tools',
    'material-components/material-components-android', // TODO(guidezpl): remove when https://github.com/material-components/material-components-android/issues/4144 is closed
    'ninja-build/ninja',
    'torvalds/linux',
    'tpn/winsdk-10',
  };

  // See dev/bots/test/analyze-test-input/root/packages/foo/bad_repository_links.dart
  // for examples of repository links that are not allowed.
  final RegExp pattern = RegExp(
    r'^(https:\/\/(?:cs\.opensource\.google|github|raw\.githubusercontent|source\.chromium|([a-z0-9\-]+)\.googlesource)\.)',
  );

  final List<String> problems = <String>[];
  final Set<String> suggestions = <String>{};
  final List<File> files = await _allFiles(workingDirectory, null, minimumMatches: 10).toList();
  for (final File file in files) {
    final Uint8List bytes = file.readAsBytesSync();
    // We allow invalid UTF-8 here so that binaries don't trip us up.
    // There's a separate test in this file that verifies that all text
    // files are actually valid UTF-8 (see verifyNoBinaries below).
    final String contents = utf8.decode(bytes, allowMalformed: true);
    int start = 0;
    while ((start = contents.indexOf('https://', start)) >= 0) {
      // Find all 'https://' links
      int end = start + 8; // Length of 'https://'
      while (end < contents.length && !stops.contains(contents[end])) {
        end += 1;
      }
      final String url = contents.substring(start, end).replaceAll('\r', '');

      if (pattern.hasMatch(url) && !repoExceptions.any(url.contains)) {
        if (url.contains('master')) {
          problems.add('${file.path} contains $url, which uses the banned "master" branch.');
          suggestions.add(
            'Change the URLs above to the expected pattern by '
            'using the "main" branch if it exists, otherwise adding the '
            'repository to the list of exceptions in analyze.dart.',
          );
        }
      }
      start = end;
    }
  }
  assert(problems.isEmpty == suggestions.isEmpty);
  if (problems.isNotEmpty) {
    foundError(<String>[...problems, ...suggestions]);
  }
}

@immutable
class Hash256 {
  const Hash256(this.a, this.b, this.c, this.d);

  factory Hash256.fromDigest(Digest digest) {
    assert(digest.bytes.length == 32);
    return Hash256(
      digest.bytes[0] << 56 |
          digest.bytes[1] << 48 |
          digest.bytes[2] << 40 |
          digest.bytes[3] << 32 |
          digest.bytes[4] << 24 |
          digest.bytes[5] << 16 |
          digest.bytes[6] << 8 |
          digest.bytes[7] << 0,
      digest.bytes[8] << 56 |
          digest.bytes[9] << 48 |
          digest.bytes[10] << 40 |
          digest.bytes[11] << 32 |
          digest.bytes[12] << 24 |
          digest.bytes[13] << 16 |
          digest.bytes[14] << 8 |
          digest.bytes[15] << 0,
      digest.bytes[16] << 56 |
          digest.bytes[17] << 48 |
          digest.bytes[18] << 40 |
          digest.bytes[19] << 32 |
          digest.bytes[20] << 24 |
          digest.bytes[21] << 16 |
          digest.bytes[22] << 8 |
          digest.bytes[23] << 0,
      digest.bytes[24] << 56 |
          digest.bytes[25] << 48 |
          digest.bytes[26] << 40 |
          digest.bytes[27] << 32 |
          digest.bytes[28] << 24 |
          digest.bytes[29] << 16 |
          digest.bytes[30] << 8 |
          digest.bytes[31] << 0,
    );
  }

  final int a;
  final int b;
  final int c;
  final int d;

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is Hash256 && other.a == a && other.b == b && other.c == c && other.d == d;
  }

  @override
  int get hashCode => Object.hash(a, b, c, d);
}

// DO NOT ADD ANY ENTRIES TO THIS LIST.
// We have a policy of not checking in binaries into this repository.
// If you are adding/changing template images, use the flutter_template_images
// package and a .img.tmpl placeholder instead.
// If you have other binaries to add, please consult johnmccutchan for advice.
final Set<Hash256> _legacyBinaries = <Hash256>{
  // DEFAULT ICON IMAGES

  // packages/flutter_tools/templates/app/android.tmpl/app/src/main/res/mipmap-hdpi/ic_launcher.png
  // packages/flutter_tools/templates/module/android/host_app_common/app.tmpl/src/main/res/mipmap-hdpi/ic_launcher.png
  // (also used by many examples)
  const Hash256(0x6A7C8F0D703E3682, 0x108F9662F8133022, 0x36240D3F8F638BB3, 0x91E32BFB96055FEF),

  // packages/flutter_tools/templates/app/android.tmpl/app/src/main/res/mipmap-mdpi/ic_launcher.png
  // (also used by many examples)
  const Hash256(0xC7C0C0189145E4E3, 0x2A401C61C9BDC615, 0x754B0264E7AFAE24, 0xE834BB81049EAF81),

  // packages/flutter_tools/templates/app/android.tmpl/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  // (also used by many examples)
  const Hash256(0xE14AA40904929BF3, 0x13FDED22CF7E7FFC, 0xBF1D1AAC4263B5EF, 0x1BE8BFCE650397AA),

  // packages/flutter_tools/templates/app/android.tmpl/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  // (also used by many examples)
  const Hash256(0x4D470BF22D5C17D8, 0x4EDC5F82516D1BA8, 0xA1C09559CD761CEF, 0xB792F86D9F52B540),

  // packages/flutter_tools/templates/app/android.tmpl/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  // (also used by many examples)
  const Hash256(0x3C34E1F298D0C9EA, 0x3455D46DB6B7759C, 0x8211A49E9EC6E44B, 0x635FC5C87DFB4180),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  // (also used by a few examples)
  const Hash256(0x7770183009E91411, 0x2DE7D8EF1D235A6A, 0x30C5834424858E0D, 0x2F8253F6B8D31926),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
  // (also used by many examples)
  const Hash256(0x5925DAB509451F9E, 0xCBB12CE8A625F9D4, 0xC104718EE20CAFF8, 0xB1B51032D1CD8946),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
  // (also used by many examples)
  const Hash256(0xC4D9A284C12301D0, 0xF50E248EC53ED51A, 0x19A10147B774B233, 0x08399250B0D44C55),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
  // (also used by many examples)
  const Hash256(0xBF97F9D3233F33E1, 0x389B09F7B8ADD537, 0x41300CB834D6C7A5, 0xCA32CBED363A4FB2),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
  // (also used by many examples)
  const Hash256(0x285442F69A06B45D, 0x9D79DF80321815B5, 0x46473548A37B7881, 0x9B68959C7B8ED237),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
  // (also used by many examples)
  const Hash256(0x2AB64AF8AC727EA9, 0x9C6AB9EAFF847F46, 0xFBF2A9A0A78A0ABC, 0xBF3180F3851645B4),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
  // (also used by many examples)
  const Hash256(0x9DCA09F4E5ED5684, 0xD3C4DFF41F4E8B7C, 0xB864B438172D72BE, 0x069315FA362930F9),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
  // (also used by many examples)
  const Hash256(0xD5AD04DE321EF37C, 0xACC5A7B960AFCCE7, 0x1BDCB96FA020C482, 0x49C1545DD1A0F497),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
  // (also used by many examples)
  const Hash256(0x809ABFE75C440770, 0xC13C4E2E46D09603, 0xC22053E9D4E0E227, 0x5DCB9C1DCFBB2C75),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
  // (also used by many examples)
  const Hash256(0x3DB08CB79E7B01B9, 0xE81F956E3A0AE101, 0x48D0FAFDE3EA7AA7, 0x0048DF905AA52CFD),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
  // (also used by many examples)
  const Hash256(0x23C13D463F5DCA5C, 0x1F14A14934003601, 0xC29F1218FD461016, 0xD8A22CEF579A665F),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
  // (also used by many examples)
  const Hash256(0x6DB7726530D71D3F, 0x52CB59793EB69131, 0x3BAA04796E129E1E, 0x043C0A58A1BFFD2F),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
  // (also used by many examples)
  const Hash256(0xCEE565F5E6211656, 0x9B64980B209FD5CA, 0x4B3D3739011F5343, 0x250B33A1A2C6EB65),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
  // (also used by many examples)
  const Hash256(0x93AE7D494FAD0FB3, 0x0CBF3AE746A39C4B, 0xC7A0F8BBF87FBB58, 0x7A3F3C01F3C5CE20),

  // packages/flutter_tools/templates/app/macos.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
  // (also used by a few examples)
  const Hash256(0xB18BEBAAD1AD6724, 0xE48BCDF699BA3927, 0xDF3F258FEBE646A3, 0xAB5C62767C6BAB40),

  // packages/flutter_tools/templates/app/macos.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
  // (also used by a few examples)
  const Hash256(0xF90D839A289ECADB, 0xF2B0B3400DA43EB8, 0x08B84908335AE4A0, 0x07457C4D5A56A57C),

  // packages/flutter_tools/templates/app/macos.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
  // (also used by a few examples)
  const Hash256(0x592C2ABF84ADB2D3, 0x91AED8B634D3233E, 0x2C65369F06018DCD, 0x8A4B27BA755EDCBE),

  // packages/flutter_tools/templates/app/macos.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
  // (also used by a few examples)
  const Hash256(0x75D9A0C034113CA8, 0xA1EC11C24B81F208, 0x6630A5A5C65C7D26, 0xA5DC03A1C0A4478C),

  // packages/flutter_tools/templates/app/macos.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
  // (also used by a few examples)
  const Hash256(0xA896E65745557732, 0xC72BD4EE3A10782F, 0xE2AA95590B5AF659, 0x869E5808DB9C01C1),

  // packages/flutter_tools/templates/app/macos.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
  // (also used by a few examples)
  const Hash256(0x3A69A8A1AAC5D9A8, 0x374492AF4B6D07A4, 0xCE637659EB24A784, 0x9C4DFB261D75C6A3),

  // packages/flutter_tools/templates/app/macos.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
  // (also used by a few examples)
  const Hash256(0xD29D4E0AF9256DC9, 0x2D0A8F8810608A5E, 0x64A132AD8B397CA2, 0xC4DDC0B1C26A68C3),

  // packages/flutter_tools/templates/app/web/icons/Icon-192.png.copy.tmpl
  // dev/integration_tests/flutter_gallery/web/icons/Icon-192.png
  const Hash256(0x3DCE99077602F704, 0x21C1C6B2A240BC9B, 0x83D64D86681D45F2, 0x154143310C980BE3),

  // packages/flutter_tools/templates/app/web/icons/Icon-512.png.copy.tmpl
  // dev/integration_tests/flutter_gallery/web/icons/Icon-512.png
  const Hash256(0xBACCB205AE45f0B4, 0x21BE1657259B4943, 0xAC40C95094AB877F, 0x3BCBE12CD544DCBE),

  // packages/flutter_tools/templates/app/web/favicon.png.copy.tmpl
  // dev/integration_tests/flutter_gallery/web/favicon.png
  const Hash256(0x7AB2525F4B86B65D, 0x3E4C70358A17E5A1, 0xAAF6F437f99CBCC0, 0x46DAD73d59BB9015),

  // GALLERY ICONS

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-hdpi/ic_background.png
  const Hash256(0x03CFDE53C249475C, 0x277E8B8E90AC8A13, 0xE5FC13C358A94CCB, 0x67CA866C9862A0DD),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-hdpi/ic_foreground.png
  const Hash256(0x86A83E23A505EFCC, 0x39C358B699EDE12F, 0xC088EE516A1D0C73, 0xF3B5D74DDAD164B1),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
  const Hash256(0xD813B1A77320355E, 0xB68C485CD47D0F0F, 0x3C7E1910DCD46F08, 0x60A6401B8DC13647),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xhdpi/ic_background.png
  const Hash256(0x35AFA76BD5D6053F, 0xEE927436C78A8794, 0xA8BA5F5D9FC9653B, 0xE5B96567BB7215ED),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xhdpi/ic_foreground.png
  const Hash256(0x263CE9B4F1F69B43, 0xEBB08AE9FE8F80E7, 0x95647A59EF2C040B, 0xA8AEB246861A7DFF),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  const Hash256(0x5E1A93C3653BAAFF, 0x1AAC6BCEB8DCBC2F, 0x2AE7D68ECB07E507, 0xCB1FA8354B28313A),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xxhdpi/ic_background.png
  const Hash256(0xA5C77499151DDEC6, 0xDB40D0AC7321FD74, 0x0646C0C0F786743F, 0x8F3C3C408CAC5E8C),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xxhdpi/ic_foreground.png
  const Hash256(0x33DE450980A2A16B, 0x1982AC7CDC1E7B01, 0x919E07E0289C2139, 0x65F85BCED8895FEF),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  const Hash256(0xC3B8577F4A89BA03, 0x830944FB06C3566B, 0x4C99140A2CA52958, 0x089BFDC3079C59B7),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xxxhdpi/ic_background.png
  const Hash256(0xDEBC241D6F9C5767, 0x8980FDD46FA7ED0C, 0x5B8ACD26BCC5E1BC, 0x473C89B432D467AD),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xxxhdpi/ic_foreground.png
  const Hash256(0xBEFE5F7E82BF8B64, 0x148D869E3742004B, 0xF821A9F5A1BCDC00, 0x357D246DCC659DC2),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  const Hash256(0xC385404341FF9EDD, 0x30FBE76F0EC99155, 0x8EA4F4AFE8CC0C60, 0x1CA3EDEF177E1DA8),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-1024.png
  const Hash256(0x6BE5751A29F57A80, 0x36A4B31CC542C749, 0x984E49B22BD65CAA, 0x75AE8B2440848719),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-120.png
  const Hash256(0x9972A2264BFA8F8D, 0x964AFE799EADC1FA, 0x2247FB31097F994A, 0x1495DC32DF071793),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-152.png
  const Hash256(0x4C7CC9B09BEEDA24, 0x45F57D6967753910, 0x57D68E1A6B883D2C, 0x8C52701A74F1400F),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-167.png
  const Hash256(0x66DACAC1CFE4D349, 0xDBE994CB9125FFD7, 0x2D795CFC9CF9F739, 0xEDBB06CE25082E9C),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-180.png
  const Hash256(0x5188621015EBC327, 0xC9EF63AD76E60ECE, 0xE82BDC3E4ABF09E2, 0xEE0139FA7C0A2BE5),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-20.png
  const Hash256(0x27D2752D04EE9A6B, 0x78410E208F74A6CD, 0xC90D9E03B73B8C60, 0xD05F7D623E790487),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-29.png
  const Hash256(0xBB20556B2826CF85, 0xD5BAC73AA69C2AC3, 0x8E71DAD64F15B855, 0xB30CB73E0AF89307),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-40.png
  const Hash256(0x623820FA45CDB0AC, 0x808403E34AD6A53E, 0xA3E9FDAE83EE0931, 0xB020A3A4EF2CDDE7),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-58.png
  const Hash256(0xC6D631D1E107215E, 0xD4A58FEC5F3AA4B5, 0x0AE9724E07114C0C, 0x453E5D87C2CAD3B3),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-60.png
  const Hash256(0x4B6F58D1EB8723C6, 0xE717A0D09FEC8806, 0x90C6D1EF4F71836E, 0x618672827979B1A2),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-76.png
  const Hash256(0x0A1744CC7634D508, 0xE85DD793331F0C8A, 0x0B7C6DDFE0975D8F, 0x29E91C905BBB1BED),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-80.png
  const Hash256(0x24032FBD1E6519D6, 0x0BA93C0D5C189554, 0xF50EAE23756518A2, 0x3FABACF4BD5DAF08),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-87.png
  const Hash256(0xC17BAE6DF6BB234A, 0xE0AF4BEB0B805F12, 0x14E74EB7AA9A30F1, 0x5763689165DA7DDF),

  // STOCKS ICONS

  // dev/benchmarks/test_apps/stocks/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
  const Hash256(0x74052AB5241D4418, 0x7085180608BC3114, 0xD12493C50CD8BBC7, 0x56DED186C37ACE84),

  // dev/benchmarks/test_apps/stocks/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
  const Hash256(0xE37947332E3491CB, 0x82920EE86A086FEA, 0xE1E0A70B3700A7DA, 0xDCAFBDD8F40E2E19),

  // dev/benchmarks/test_apps/stocks/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  const Hash256(0xE608CDFC0C8579FB, 0xE38873BAAF7BC944, 0x9C9D2EE3685A4FAE, 0x671EF0C8BC41D17C),

  // dev/benchmarks/test_apps/stocks/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  const Hash256(0xBD53D86977DF9C54, 0xF605743C5ABA114C, 0x9D51D1A8BB917E1A, 0x14CAA26C335CAEBD),

  // dev/benchmarks/test_apps/stocks/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  const Hash256(0x64E4D02262C4F3D0, 0xBB4FDC21CD0A816C, 0x4CD2A0194E00FB0F, 0x1C3AE4142FAC0D15),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png
  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png
  const Hash256(0x5BA3283A76918FC0, 0xEE127D0F22D7A0B6, 0xDF03DAED61669427, 0x93D89DDD87A08117),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png
  const Hash256(0xCD7F26ED31DEA42A, 0x535D155EC6261499, 0x34E6738255FDB2C4, 0xBD8D4BDDE9A99B05),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-76.png
  const Hash256(0x3FA1225FC9A96A7E, 0xCD071BC42881AB0E, 0x7747EB72FFB72459, 0xA37971BBAD27EE24),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png
  const Hash256(0xCD867001ACD7BBDB, 0x25CDFD452AE89FA2, 0x8C2DC980CAF55F48, 0x0B16C246CFB389BC),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png
  const Hash256(0x848E9736E5C4915A, 0x7945BCF6B32FD56B, 0x1F1E7CDDD914352E, 0xC9681D38EF2A70DA),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Notification.png
  const Hash256(0x654BA7D6C4E05CA0, 0x7799878884EF8F11, 0xA383E1F24CEF5568, 0x3C47604A966983C8),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Notification@2x.png
  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small-40.png
  const Hash256(0x743056FE7D83FE42, 0xA2990825B6AD0415, 0x1AF73D0D43B227AA, 0x07EBEA9B767381D9),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Notification@3x.png
  const Hash256(0xA7E1570812D119CF, 0xEF4B602EF28DD0A4, 0x100D066E66F5B9B9, 0x881765DC9303343B),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png
  const Hash256(0xB4102839A1E41671, 0x62DACBDEFA471953, 0xB1EE89A0AB7594BE, 0x1D9AC1E67DC2B2CE),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small.png
  const Hash256(0x70AC6571B593A967, 0xF1CBAEC9BC02D02D, 0x93AD766D8290ADE6, 0x840139BF9F219019),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png
  const Hash256(0x5D87A78386DA2C43, 0xDDA8FEF2CA51438C, 0xE5A276FE28C6CF0A, 0xEBE89085B56665B6),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png
  const Hash256(0x4D9F5E81F668DA44, 0xB20A77F8BF7BA2E1, 0xF384533B5AD58F07, 0xB3A2F93F8635CD96),

  // LEGACY ICONS

  // dev/benchmarks/complex_layout/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@3x.png
  // dev/benchmarks/microbenchmarks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@3x.png
  // examples/flutter_view/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@3x.png
  // (not really sure where this came from, or why neither the template nor most examples use them)
  const Hash256(0x6E645DC9ED913AAD, 0xB50ED29EEB16830D, 0xB32CA12F39121DB9, 0xB7BC1449DDDBF8B8),

  // dev/benchmarks/macrobenchmarks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  // dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  // dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  // dev/integration_tests/release_smoke_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  const Hash256(0xDEFAC77E08EC71EC, 0xA04CCA3C95D1FC33, 0xB9F26E1CB15CB051, 0x47DEFC79CDD7C158),

  // examples/flutter_view/ios/Runner/ic_add.png
  // examples/platform_view/ios/Runner/ic_add.png
  const Hash256(0x3CCE7450334675E2, 0xE3AABCA20B028993, 0x127BE82FE0EB3DFF, 0x8B027B3BAF052F2F),

  // examples/image_list/images/coast.jpg
  const Hash256(0xDA957FD30C51B8D2, 0x7D74C2C918692DC4, 0xD3C5C99BB00F0D6B, 0x5EBB30395A6EDE82),

  // examples/image_list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  const Hash256(0xB5792CA06F48A431, 0xD4379ABA2160BD5D, 0xE92339FC64C6A0D3, 0x417AA359634CD905),

  // TEST ASSETS

  // dev/benchmarks/macrobenchmarks/assets/999x1000.png
  const Hash256(0x553E9C36DFF3E610, 0x6A608BDE822A0019, 0xDE4F1769B6FBDB97, 0xBC3C20E26B839F59),

  // dev/bots/test/analyze-test-input/root/packages/foo/serviceaccount.enc
  const Hash256(0xA8100AE6AA1940D0, 0xB663BB31CD466142, 0xEBBDBD5187131B92, 0xD93818987832EB89),

  // dev/automated_tests/icon/test.png
  const Hash256(0xE214B4A0FEEEC6FA, 0x8E7AA8CC9BFBEC40, 0xBCDAC2F2DEBC950F, 0x75AF8EBF02BCE459),

  // dev/integration_tests/android_splash_screens/splash_screen_kitchen_sink/android/app/src/main/res/drawable-land-xxhdpi/flutter_splash_screen.png
  // dev/integration_tests/android_splash_screens/splash_screen_kitchen_sink/android/app/src/main/res/mipmap-land-xxhdpi/flutter_splash_screen.png
  const Hash256(0x2D4F8D7A3DFEF9D3, 0xA0C66938E169AB58, 0x8C6BBBBD1973E34E, 0x03C428416D010182),

  // dev/integration_tests/android_splash_screens/splash_screen_kitchen_sink/android/app/src/main/res/drawable-xxhdpi/flutter_splash_screen.png
  // dev/integration_tests/android_splash_screens/splash_screen_kitchen_sink/android/app/src/main/res/mipmap-xxhdpi/flutter_splash_screen.png
  const Hash256(0xCD46C01BAFA3B243, 0xA6AA1645EEDDE481, 0x143AC8ABAB1A0996, 0x22CAA9D41F74649A),

  // dev/integration_tests/flutter_driver_screenshot_test/assets/red_square.png
  const Hash256(0x40054377E1E084F4, 0x4F4410CE8F44C210, 0xABA945DFC55ED0EF, 0x23BDF9469E32F8D3),

  // dev/integration_tests/flutter_driver_screenshot_test/test_driver/goldens/red_square_image/iPhone7,2.png
  const Hash256(0x7F9D27C7BC418284, 0x01214E21CA886B2F, 0x40D9DA2B31AE7754, 0x71D68375F9C8A824),

  // examples/flutter_view/assets/flutter-mark-square-64.png
  // examples/platform_view/assets/flutter-mark-square-64.png
  const Hash256(0xF416B0D8AC552EC8, 0x819D1F492D1AB5E6, 0xD4F20CF45DB47C22, 0x7BB431FEFB5B67B2),

  // packages/flutter_tools/test/data/intellij/plugins/Dart/lib/Dart.jar
  const Hash256(0x576E489D788A13DB, 0xBF40E4A39A3DAB37, 0x15CCF0002032E79C, 0xD260C69B29E06646),

  // packages/flutter_tools/test/data/intellij/plugins/flutter-intellij.jar
  const Hash256(0x4C67221E25626CB2, 0x3F94E1F49D34E4CF, 0x3A9787A514924FC5, 0x9EF1E143E5BC5690),

  // MISCELLANEOUS

  // dev/bots/serviceaccount.enc
  const Hash256(0x1F19ADB4D80AFE8C, 0xE61899BA776B1A8D, 0xCA398C75F5F7050D, 0xFB0E72D7FBBBA69B),

  // dev/docs/favicon.ico
  const Hash256(0x67368CA1733E933A, 0xCA3BC56EF0695012, 0xE862C371AD4412F0, 0x3EC396039C609965),

  // dev/snippets/assets/code_sample.png
  const Hash256(0xAB2211A47BDA001D, 0x173A52FD9C75EBC7, 0xE158942FFA8243AD, 0x2A148871990D4297),

  // dev/snippets/assets/code_snippet.png
  const Hash256(0xDEC70574DA46DFBB, 0xFA657A771F3E1FBD, 0xB265CFC6B2AA5FE3, 0x93BA4F325D1520BA),

  // packages/flutter_tools/static/Ahem.ttf
  const Hash256(0x63D2ABD0041C3E3B, 0x4B52AD8D382353B5, 0x3C51C6785E76CE56, 0xED9DACAD2D2E31C4),
};

Future<void> verifyNoBinaries(String workingDirectory, {Set<Hash256>? legacyBinaries}) async {
  // Please do not add anything to the _legacyBinaries set above.
  // We have a policy of not checking in binaries into this repository.
  // If you are adding/changing template images, use the flutter_template_images
  // package and a .img.tmpl placeholder instead.
  // If you have other binaries to add, please consult johnmccutchan for advice.
  assert(
    _legacyBinaries
            .expand<int>((Hash256 hash) => <int>[hash.a, hash.b, hash.c, hash.d])
            .reduce((int value, int element) => value ^ element) ==
        0x606B51C908B40BFA, // Please do not modify this line.
  );
  legacyBinaries ??= _legacyBinaries;
  if (!Platform.isWindows) {
    // TODO(ianh): Port this to Windows
    final List<File> files = await _gitFiles(workingDirectory);
    final List<String> problems = <String>[];
    for (final File file in files) {
      final Uint8List bytes = file.readAsBytesSync();
      try {
        utf8.decode(bytes);
      } on FormatException catch (error) {
        final Digest digest = sha256.convert(bytes);
        if (!legacyBinaries.contains(Hash256.fromDigest(digest))) {
          problems.add('${file.path}:${error.offset}: file is not valid UTF-8');
        }
      }
    }
    if (problems.isNotEmpty) {
      foundError(<String>[
        ...problems,
        'All files in this repository must be UTF-8. In particular, images and other binaries',
        'must not be checked into this repository. This is because we are very sensitive to the',
        'size of the repository as it is distributed to all our developers. If you have a binary',
        'to which you need access, you should consider how to fetch it from another repository;',
        'for example, the "assets-for-api-docs" repository is used for images in API docs.',
        'To add assets to flutter_tools templates, see the instructions in the wiki:',
        'https://github.com/flutter/flutter/blob/main/docs/tool/Managing-template-image-assets.md',
      ]);
    }
  }
}

// UTILITY FUNCTIONS

bool _listEquals<T>(List<T> a, List<T> b) {
  if (a.length != b.length) {
    return false;
  }
  for (int index = 0; index < a.length; index += 1) {
    if (a[index] != b[index]) {
      return false;
    }
  }
  return true;
}

Future<List<File>> _gitFiles(String workingDirectory, {bool runSilently = true}) async {
  final EvalResult evalResult = await _evalCommand(
    'git',
    <String>['ls-files', '-z'],
    workingDirectory: workingDirectory,
    runSilently: runSilently,
  );
  if (evalResult.exitCode != 0) {
    foundError(<String>[
      'git ls-files failed with exit code ${evalResult.exitCode}',
      '${bold}stdout:$reset',
      evalResult.stdout,
      '${bold}stderr:$reset',
      evalResult.stderr,
    ]);
  }
  final List<String> filenames = evalResult.stdout.split('\x00');
  assert(filenames.last.isEmpty); // git ls-files gives a trailing blank 0x00
  filenames.removeLast();
  return filenames
      .where((String filename) => !filename.startsWith('engine/'))
      .map<File>((String filename) => File(path.join(workingDirectory, filename)))
      .toList();
}

Stream<File> _allFiles(
  String workingDirectory,
  String? extension, {
  required int minimumMatches,
}) async* {
  final Set<String> gitFileNamesSet = <String>{};
  gitFileNamesSet.addAll(
    (await _gitFiles(workingDirectory)).map((File f) => path.canonicalize(f.absolute.path)),
  );

  assert(
    extension == null || !extension.startsWith('.'),
    'Extension argument should not start with a period.',
  );
  final Set<FileSystemEntity> pending = <FileSystemEntity>{Directory(workingDirectory)};
  int matches = 0;
  while (pending.isNotEmpty) {
    final FileSystemEntity entity = pending.first;
    pending.remove(entity);
    if (path.extension(entity.path) == '.tmpl') {
      continue;
    }
    if (entity is File) {
      if (!gitFileNamesSet.contains(path.canonicalize(entity.absolute.path))) {
        continue;
      }
      if (_isGeneratedPluginRegistrant(entity)) {
        continue;
      }
      switch (path.basename(entity.path)) {
        case 'flutter_export_environment.sh' || 'gradlew.bat' || '.DS_Store':
          continue;
      }
      if (extension == null || path.extension(entity.path) == '.$extension') {
        matches += 1;
        yield entity;
      }
    } else if (entity is Directory) {
      if (File(path.join(entity.path, '.dartignore')).existsSync()) {
        continue;
      }
      switch (path.basename(entity.path)) {
        case '.git' || '.idea' || '.gradle' || '.dart_tool' || 'build':
          continue;
      }
      pending.addAll(entity.listSync());
    }
  }
  assert(
    matches >= minimumMatches,
    'Expected to find at least $minimumMatches files with extension ".$extension" in "$workingDirectory", but only found $matches.',
  );
}

class EvalResult {
  EvalResult({required this.stdout, required this.stderr, this.exitCode = 0});

  final String stdout;
  final String stderr;
  final int exitCode;
}

// TODO(ianh): Refactor this to reuse the code in run_command.dart
Future<EvalResult> _evalCommand(
  String executable,
  List<String> arguments, {
  required String workingDirectory,
  Map<String, String>? environment,
  bool allowNonZeroExit = false,
  bool runSilently = false,
}) async {
  final String commandDescription =
      '${path.relative(executable, from: workingDirectory)} ${arguments.join(' ')}';
  final String relativeWorkingDir = path.relative(workingDirectory);

  if (!runSilently) {
    print('RUNNING: cd $cyan$relativeWorkingDir$reset; $green$commandDescription$reset');
  }

  final Stopwatch time = Stopwatch()..start();
  final Process process = await Process.start(
    executable,
    arguments,
    workingDirectory: workingDirectory,
    environment: environment,
  );

  final Future<List<List<int>>> savedStdout = process.stdout.toList();
  final Future<List<List<int>>> savedStderr = process.stderr.toList();
  final int exitCode = await process.exitCode;
  final EvalResult result = EvalResult(
    stdout: utf8.decode((await savedStdout).expand<int>((List<int> ints) => ints).toList()),
    stderr: utf8.decode((await savedStderr).expand<int>((List<int> ints) => ints).toList()),
    exitCode: exitCode,
  );

  if (!runSilently) {
    print(
      'ELAPSED TIME: $bold${prettyPrintDuration(time.elapsed)}$reset for $commandDescription in $relativeWorkingDir',
    );
  }

  if (exitCode != 0 && !allowNonZeroExit) {
    foundError(<String>[
      result.stderr,
      '${bold}ERROR:$red Last command exited with $exitCode.$reset',
      '${bold}Command:$red $commandDescription$reset',
      '${bold}Relative working directory:$red $relativeWorkingDir$reset',
    ]);
  }

  return result;
}

Future<void> _checkConsumerDependencies() async {
  const List<String> kCorePackages = <String>[
    'flutter',
    'flutter_test',
    'flutter_driver',
    'flutter_localizations',
    'integration_test',
    'fuchsia_remote_debug_protocol',
  ];
  final Set<String> dependencies = <String>{};

  // Parse the output of pub deps --json to determine all of the
  // current packages used by the core set of flutter packages.
  for (final String package in kCorePackages) {
    final ProcessResult result = await Process.run(flutter, <String>[
      'pub',
      'deps',
      '--json',
      '--directory=${path.join(flutterRoot, 'packages', package)}',
    ]);
    if (result.exitCode != 0) {
      foundError(<String>[result.stdout.toString(), result.stderr.toString()]);
      return;
    }
    final Map<String, Object?> rawJson =
        json.decode(result.stdout as String) as Map<String, Object?>;
    final Map<String, Map<String, Object?>> dependencyTree = <String, Map<String, Object?>>{
      for (final Map<String, Object?> package
          in (rawJson['packages']! as List<Object?>).cast<Map<String, Object?>>())
        package['name']! as String: package,
    };
    final List<Map<String, Object?>> workset = <Map<String, Object?>>[];
    workset.add(dependencyTree[package]!);

    while (workset.isNotEmpty) {
      final Map<String, Object?> currentPackage = workset.removeLast();
      if (currentPackage['kind'] == 'dev') {
        continue;
      }
      dependencies.add(currentPackage['name']! as String);

      final List<String> currentDependencies =
          (currentPackage['directDependencies']! as List<Object?>).cast<String>();
      for (final String dependency in currentDependencies) {
        // Don't add dependencies we've already seen or we will get stuck
        // forever if there are any circular references.
        // TODO(dantup): Consider failing gracefully with the names of the
        //  packages once the cycle between test_api and matcher is resolved.
        //  https://github.com/dart-lang/test/issues/1979
        if (!dependencies.contains(dependency)) {
          workset.add(dependencyTree[dependency]!);
        }
      }
    }
  }

  final Set<String> removed = kCorePackageAllowList.difference(dependencies);
  final Set<String> added = dependencies.difference(kCorePackageAllowList);

  String plural(int n, String s, String p) => n == 1 ? s : p;

  if (added.isNotEmpty) {
    foundError(<String>[
      'The transitive closure of package dependencies contains ${plural(added.length, "a non-allowlisted package", "non-allowlisted packages")}:',
      '  ${added.join(', ')}',
      'We strongly desire to keep the number of dependencies to a minimum and',
      'therefore would much prefer not to add new dependencies.',
      'See dev/bots/allowlist.dart for instructions on how to update the package',
      'allowlist if you nonetheless believe this is a necessary addition.',
    ]);
  }

  if (removed.isNotEmpty) {
    foundError(<String>[
      'Excellent news! ${plural(removed.length, "A package dependency has been removed!", "Multiple package dependencies have been removed!")}',
      '  ${removed.join(', ')}',
      'To make sure we do not accidentally add ${plural(removed.length, "this dependency", "these dependencies")} back in the future,',
      'please remove ${plural(removed.length, "this", "these")} packages from the allow-list in dev/bots/allowlist.dart.',
      'Thanks!',
    ]);
  }
}

class _DebugOnlyFieldVisitor extends RecursiveAstVisitor<void> {
  _DebugOnlyFieldVisitor(this.parseResult);

  final ParseStringResult parseResult;
  final List<AstNode> errors = <AstNode>[];

  static const String _kDebugOnlyAnnotation = '_debugOnly';
  static final RegExp _nullInitializedField = RegExp(r'kDebugMode \? [\w<> ,{}()]+ : null;');

  @override
  void visitFieldDeclaration(FieldDeclaration node) {
    super.visitFieldDeclaration(node);
    if (node.metadata.any(
      (Annotation annotation) => annotation.name.name == _kDebugOnlyAnnotation,
    )) {
      if (!node.toSource().contains(_nullInitializedField)) {
        errors.add(node.fields); // Use the fields node for line number.
      }
    }
  }
}

Future<void> verifyNullInitializedDebugExpensiveFields(
  String workingDirectory, {
  int minimumMatches = 400,
}) async {
  final String flutterLib = path.join(workingDirectory, 'packages', 'flutter', 'lib');
  final List<File> files = await _allFiles(
    flutterLib,
    'dart',
    minimumMatches: minimumMatches,
  ).toList();
  final List<String> errors = <String>[];
  for (final File file in files) {
    final ParseStringResult parsedFile = parseFile(
      featureSet: _parsingFeatureSet(),
      path: file.absolute.path,
    );
    final _DebugOnlyFieldVisitor visitor = _DebugOnlyFieldVisitor(parsedFile);
    visitor.visitCompilationUnit(parsedFile.unit);
    for (final AstNode badNode in visitor.errors) {
      errors.add(
        '${file.path}:${parsedFile.lineInfo.getLocation(badNode.offset).lineNumber}: fields annotated with @_debugOnly must null initialize.',
      );
    }
  }
  if (errors.isNotEmpty) {
    foundError(<String>[
      ...errors,
      '',
      '$bold${red}Fields annotated with @_debugOnly must null initialize,$reset',
      'to ensure both the field and initializer are removed from profile/release mode.',
      'These fields should be written as:',
      'field = kDebugMode ? <DebugValue> : null;',
    ]);
  }
}

final RegExp tabooPattern = RegExp(r'^ *///.*\b(simply|note:|note that)\b', caseSensitive: false);

Future<void> verifyTabooDocumentation(String workingDirectory, {int minimumMatches = 100}) async {
  final List<String> errors = <String>[];
  await for (final File file in _allFiles(
    workingDirectory,
    'dart',
    minimumMatches: minimumMatches,
  )) {
    final List<String> lines = file.readAsLinesSync();
    for (int index = 0; index < lines.length; index += 1) {
      final String line = lines[index];
      final Match? match = tabooPattern.firstMatch(line);
      if (match != null) {
        errors.add(
          '${file.path}:${index + 1}: Found use of the taboo word "${match.group(1)}" in documentation string.',
        );
      }
    }
  }
  if (errors.isNotEmpty) {
    foundError(<String>[
      ...errors,
      '',
      '${bold}Avoid the word "simply" in documentation. See https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#use-the-passive-voice-recommend-do-not-require-never-say-things-are-simple for details.$reset',
      '${bold}In many cases these words can be omitted without loss of generality; in other cases it may require a bit of rewording to avoid implying that the task is simple.$reset',
      '${bold}Similarly, avoid using "note:" or the phrase "note that". See https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#avoid-empty-prose for details.$reset',
    ]);
  }
}

final Map<String, String> _kKotlinTemplateKeys = <String, String>{
  'androidIdentifier': 'dummyPackage',
  'pluginClass': 'PluginClass',
  'projectName': 'dummy',
  'agpVersion': '0.0.0.1',
  'kotlinVersion': '0.0.0.1',
};

final String _kKotlinTemplateRelativePath = path.join('packages', 'flutter_tools', 'templates');

const List<String> _kKotlinExtList = <String>['.kt.tmpl', '.kts.tmpl'];
const String _kKotlinTmplExt = '.tmpl';
final RegExp _kKotlinTemplatePattern = RegExp(r'{{(.*?)}}');

/// Copy kotlin template files from [_kKotlinTemplateRelativePath] into a system tmp folder
/// then replace template values with values from [_kKotlinTemplateKeys] or "'dummy'" if an
/// unknown key is found. Then run ktlint on the tmp folder to check for lint errors in the
/// generated Kotlin files.
Future<void> lintKotlinTemplatedFiles(String workingDirectory) async {
  final String templatePath = path.join(workingDirectory, _kKotlinTemplateRelativePath);
  final Iterable<File> files = Directory(templatePath)
      .listSync(recursive: true)
      .toList()
      .whereType<File>()
      .where((File file) => _kKotlinExtList.contains(path.extension(file.path, 2)));

  if (files.isEmpty) {
    foundError(<String>['No Kotlin template files found']);
    return;
  }

  final Directory tempDir = Directory.systemTemp.createTempSync('template_output');
  for (final File templateFile in files) {
    final String inputContent = await templateFile.readAsString();
    final String modifiedContent = inputContent.replaceAllMapped(
      _kKotlinTemplatePattern,
      (Match match) => _kKotlinTemplateKeys[match[1]] ?? 'dummy',
    );

    String outputFilename = path.basename(templateFile.path);
    outputFilename = outputFilename.substring(
      0,
      outputFilename.length - _kKotlinTmplExt.length,
    ); // Remove '.tmpl' from file path

    // Ensure the first letter of the generated class is uppercase (instead of pluginClass)
    outputFilename = outputFilename.substring(0, 1).toUpperCase() + outputFilename.substring(1);

    final String relativePath = path.dirname(path.relative(templateFile.path, from: templatePath));
    final String outputDir = path.join(tempDir.path, relativePath);
    await Directory(outputDir).create(recursive: true);
    final String outputFile = path.join(outputDir, outputFilename);
    final File output = File(outputFile);
    await output.writeAsString(modifiedContent);
  }
  return lintKotlinFiles(tempDir.path).whenComplete(() {
    tempDir.deleteSync(recursive: true);
  });
}

Future<void> lintKotlinFiles(String workingDirectory) async {
  const String baselineRelativePath = 'dev/bots/test/analyze-test-input/ktlint-baseline.xml';
  const String editorConfigRelativePath = 'dev/bots/test/analyze-test-input/.editorconfig';
  final EvalResult lintResult = await _evalCommand('ktlint', <String>[
    '--baseline=$flutterRoot/$baselineRelativePath',
    '--editorconfig=$flutterRoot/$editorConfigRelativePath',
  ], workingDirectory: workingDirectory);
  if (lintResult.exitCode != 0) {
    final String errorMessage =
        'Found lint violations in Kotlin files:\n ${lintResult.stdout}\n\n'
        'To reproduce this lint locally:\n'
        '1. Identify the CIPD version tag used to resolve this particular version of ktlint (check the dependencies section of this shard in the ci.yaml). \n'
        '2. Download that version from https://chrome-infra-packages.appspot.com/p/flutter/ktlint/linux-amd64/+/<version_tag>\n'
        '3. From the repository root, run `<path_to_ktlint>/ktlint --editorconfig=$editorConfigRelativePath --baseline=$baselineRelativePath`\n'
        'Alternatively, if you use Android Studio, follow the docs at docs/platforms/android/Kotlin-android-studio-formatting.md to enable auto formatting.';
    foundError(<String>[errorMessage]);
  }
}

const List<String> _kIgnoreList = <String>['Runner.rc.tmpl', 'flutter_window.cpp'];
final String _kIntegrationTestsRelativePath = path.join('dev', 'integration_tests');
final String _kTemplateRelativePath = path.join(
  'packages',
  'flutter_tools',
  'templates',
  'app',
  'windows.tmpl',
  'runner',
);
final String _kWindowsRunnerSubPath = path.join('windows', 'runner');
const String _kProjectNameKey = '{{projectName}}';
const String _kTmplExt = '.tmpl';

String _getFlutterLicense() {
  return '// Copyright 2014 The Flutter Authors. All rights reserved.\n'
      '// Use of this source code is governed by a BSD-style license that can be\n'
      '// found in the LICENSE file.\n'
      '\n';
}

String _removeLicenseIfPresent(String fileContents, String license) {
  if (fileContents.startsWith(license)) {
    return fileContents.substring(license.length);
  }
  return fileContents;
}

Future<void> verifyIntegrationTestTemplateFiles(String flutterRoot) async {
  final List<String> errors = <String>[];
  final String license = _getFlutterLicense();
  final String integrationTestsPath = path.join(flutterRoot, _kIntegrationTestsRelativePath);
  final String templatePath = path.join(flutterRoot, _kTemplateRelativePath);
  final Iterable<Directory> subDirs = Directory(
    integrationTestsPath,
  ).listSync().toList().whereType<Directory>();
  for (final Directory testPath in subDirs) {
    final String projectName = path.basename(testPath.path);
    final String runnerPath = path.join(testPath.path, _kWindowsRunnerSubPath);
    final Directory runner = Directory(runnerPath);
    if (!runner.existsSync()) {
      continue;
    }
    final Iterable<File> files = Directory(templatePath).listSync().toList().whereType<File>();
    for (final File templateFile in files) {
      final String fileName = path.basename(templateFile.path);
      if (_kIgnoreList.contains(fileName)) {
        continue;
      }
      String templateFileContents = templateFile.readAsLinesSync().join('\n');
      String appFilePath = path.join(runnerPath, fileName);
      if (fileName.endsWith(_kTmplExt)) {
        appFilePath = appFilePath.substring(
          0,
          appFilePath.length - _kTmplExt.length,
        ); // Remove '.tmpl' from app file path
        templateFileContents = templateFileContents.replaceAll(
          _kProjectNameKey,
          projectName,
        ); // Substitute template project name
      }
      String appFileContents = File(appFilePath).readAsLinesSync().join('\n');
      appFileContents = _removeLicenseIfPresent(appFileContents, license);
      if (appFileContents != templateFileContents) {
        int indexOfDifference;
        for (
          indexOfDifference = 0;
          indexOfDifference < appFileContents.length;
          indexOfDifference++
        ) {
          if (indexOfDifference >= templateFileContents.length ||
              templateFileContents.codeUnitAt(indexOfDifference) !=
                  appFileContents.codeUnitAt(indexOfDifference)) {
            break;
          }
        }
        final String error =
            '''
Error: file $fileName mismatched for integration test $testPath
Verify the integration test has been migrated to the latest app template.
=====$appFilePath======
$appFileContents
=====${templateFile.path}======
$templateFileContents
==========
Diff at character #$indexOfDifference
        ''';
        errors.add(error);
      }
    }
  }
  if (errors.isNotEmpty) {
    foundError(errors);
  }
}

Future<CommandResult> _runFlutterAnalyze(
  String workingDirectory, {
  List<String> options = const <String>[],
  String? failureMessage,
}) async {
  return runCommand(
    flutter,
    <String>['analyze', ...options],
    workingDirectory: workingDirectory,
    failureMessage: failureMessage,
  );
}

// These files legitimately require executable permissions
const Set<String> kExecutableAllowlist = <String>{
  '.autoroller-preupload.sh',
  'bin/dart',
  'bin/flutter',
  'bin/flutter-dev',
  'bin/internal/last_engine_commit.sh',
  'bin/internal/update_dart_sdk.sh',
  'bin/internal/update_engine_version.sh',
  'bin/internal/content_aware_hash.sh',

  'dev/bots/codelabs_build_test.sh',
  'dev/bots/docs.sh',

  'dev/checks',

  'dev/customer_testing/ci.sh',

  'dev/integration_tests/flutter_gallery/tool/run_instrumentation_test.sh',

  'dev/integration_tests/ios_add2app_life_cycle/build_and_test.sh',

  'dev/integration_tests/deferred_components_test/download_assets.sh',
  'dev/integration_tests/deferred_components_test/run_release_test.sh',

  'dev/packages_autoroller/run',

  'dev/tools/gen_keycodes/bin/gen_keycodes',
  'dev/tools/repackage_gradle_wrapper.sh',
  'dev/tools/bin/engine_hash.sh',
  'dev/tools/format.sh',
  'dev/tools/test/mock_git.sh',

  'packages/flutter_tools/bin/macos_assemble.sh',
  'packages/flutter_tools/bin/tool_backend.sh',
  'packages/flutter_tools/bin/xcode_backend.sh',
};

Future<void> _checkForNewExecutables() async {
  // 0b001001001
  const int executableBitMask = 0x49;
  final List<File> files = await _gitFiles(flutterRoot);
  final List<String> errors = <String>[];
  for (final File file in files) {
    final String relativePath = path.relative(file.path, from: flutterRoot);
    final FileStat stat = file.statSync();
    final bool isExecutable = stat.mode & executableBitMask != 0x0;
    if (isExecutable && !kExecutableAllowlist.contains(relativePath)) {
      errors.add('$relativePath is executable: ${(stat.mode & 0x1FF).toRadixString(2)}');
    }
  }
  if (errors.isNotEmpty) {
    throw Exception(
      '${errors.join('\n')}\n'
      'found ${errors.length} unexpected executable file'
      '${errors.length == 1 ? '' : 's'}! If this was intended, you '
      'must add this file to kExecutableAllowlist in dev/bots/analyze.dart',
    );
  }
}

final RegExp _importPattern = RegExp(r'''^\s*import (['"])package:flutter/([^.]+)\.dart\1''');
final RegExp _importMetaPattern = RegExp(r'''^\s*import (['"])package:meta/meta\.dart\1''');

Future<Set<String>> _findFlutterDependencies(
  String srcPath,
  List<String> errors, {
  bool checkForMeta = false,
}) async {
  return _allFiles(srcPath, 'dart', minimumMatches: 1)
      .map<Set<String>>((File file) {
        final Set<String> result = <String>{};
        for (final String line in file.readAsLinesSync()) {
          Match? match = _importPattern.firstMatch(line);
          if (match != null) {
            result.add(match.group(2)!);
          }
          if (checkForMeta) {
            match = _importMetaPattern.firstMatch(line);
            if (match != null) {
              errors.add(
                '${file.path}\nThis package imports the ${yellow}meta$reset package.\n'
                'You should instead import the "foundation.dart" library.',
              );
            }
          }
        }
        return result;
      })
      .reduce((Set<String>? value, Set<String> element) {
        value ??= <String>{};
        value.addAll(element);
        return value;
      });
}

List<T>? _deepSearch<T>(Map<T, Set<T>> map, T start, [Set<T>? seen]) {
  if (map[start] == null) {
    return null; // We catch these separately.
  }

  for (final T key in map[start]!) {
    if (key == start) {
      continue; // we catch these separately
    }
    if (seen != null && seen.contains(key)) {
      return <T>[start, key];
    }
    final List<T>? result = _deepSearch<T>(map, key, <T>{
      if (seen == null) start else ...seen,
      key,
    });
    if (result != null) {
      result.insert(0, start);
      // Only report the shortest chains.
      // For example a->b->a, rather than c->a->b->a.
      // Since we visit every node, we know the shortest chains are those
      // that start and end on the loop.
      if (result.first == result.last) {
        return result;
      }
    }
  }
  return null;
}

bool _isGeneratedPluginRegistrant(File file) {
  final String filename = path.basename(file.path);
  return !file.path.contains('.pub-cache') &&
      (filename == 'GeneratedPluginRegistrant.java' ||
          filename == 'GeneratedPluginRegistrant.swift' ||
          filename == 'GeneratedPluginRegistrant.h' ||
          filename == 'GeneratedPluginRegistrant.m' ||
          filename == 'generated_plugin_registrant.dart' ||
          filename == 'generated_plugin_registrant.h' ||
          filename == 'generated_plugin_registrant.cc');
}
