// 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:async';
import 'dart:convert';
import 'dart:core' hide print;
import 'dart:io' as system show exit;
import 'dart:io' hide exit;
import 'dart:math' as math;

import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:collection/collection.dart';
import 'package:file/file.dart' as fs;
import 'package:file/local.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;

import 'luci_resultdb.dart';
import 'run_command.dart';
import 'tool_subsharding.dart';

typedef ShardRunner = Future<void> Function();

/// A function used to validate the output of a test.
///
/// If the output matches expectations, the function shall return null.
///
/// If the output does not match expectations, the function shall return an
/// appropriate error message.
typedef OutputChecker = String? Function(CommandResult);

const Duration _quietTimeout = Duration(
  minutes: 10,
); // how long the output should be hidden between calls to printProgress before just being verbose

// If running from LUCI set to False.
final bool isLuci = Platform.environment['LUCI_CI'] == 'True';
final bool hasColor = stdout.supportsAnsiEscapes && !isLuci;
final bool _isRandomizationOff =
    bool.tryParse(Platform.environment['TEST_RANDOMIZATION_OFF'] ?? '') ?? false;

final String bold = hasColor ? '\x1B[1m' : ''; // shard titles
final String red = hasColor ? '\x1B[31m' : ''; // errors
final String green = hasColor ? '\x1B[32m' : ''; // section titles, commands
final String yellow = hasColor
    ? '\x1B[33m'
    : ''; // indications that a test was skipped (usually renders orange or brown)
final String cyan = hasColor ? '\x1B[36m' : ''; // paths
final String reverse = hasColor ? '\x1B[7m' : ''; // clocks
final String gray = hasColor
    ? '\x1B[30m'
    : ''; // subtle decorative items (usually renders as dark gray)
final String white = hasColor ? '\x1B[37m' : ''; // last log line (usually renders as light gray)
final String reset = hasColor ? '\x1B[0m' : '';

final String exe = Platform.isWindows ? '.exe' : '';
final String bat = Platform.isWindows ? '.bat' : '';
final String flutterRoot = path.dirname(path.dirname(path.dirname(path.fromUri(Platform.script))));
final String flutter = path.join(flutterRoot, 'bin', 'flutter$bat');
final String dart = path.join(flutterRoot, 'bin', 'cache', 'dart-sdk', 'bin', 'dart$exe');
final String pubCache = path.join(flutterRoot, '.pub-cache');
final String engineVersionFile = path.join(flutterRoot, 'bin', 'cache', 'engine.stamp');
final String engineInfoFile = path.join(flutterRoot, 'bin', 'cache', 'engine_stamp.json');
final String luciBotId = Platform.environment['SWARMING_BOT_ID'] ?? '';
final bool runningInDartHHHBot =
    luciBotId.startsWith('luci-dart-') || luciBotId.startsWith('dart-tests-');

const String kShardKey = 'SHARD';
const String kSubshardKey = 'SUBSHARD';
const String kTestHarnessShardName = 'test_harness_tests';

/// Environment variables to override the local engine when running `pub test`,
/// if such flags are provided to `test.dart`.
final Map<String, String> localEngineEnv = <String, String>{};

/// The arguments to pass to `flutter test` (typically the local engine
/// configuration) -- prefilled with  the arguments passed to test.dart.
final List<String> flutterTestArgs = <String>[];

/// Whether execution should be simulated for debugging purposes.
///
/// When `true`, calls to [runCommand] print to [io.stdout] instead of running
/// the process. This is useful for determining what an invocation of `test.dart`
/// _might_ due if not invoked with `--dry-run`, or otherwise determine what the
/// different test shards and sub-shards are configured as.
bool get dryRun => _dryRun ?? false;

/// Switches [dryRun] to `true`.
///
/// Expected to be called at most once during execution of a process.
void enableDryRun() {
  if (_dryRun != null) {
    throw StateError('Should only be called at most once');
  }
  _dryRun = true;
}

bool? _dryRun;

const int kESC = 0x1B;
const int kOpenSquareBracket = 0x5B;
const int kCSIParameterRangeStart = 0x30;
const int kCSIParameterRangeEnd = 0x3F;
const int kCSIIntermediateRangeStart = 0x20;
const int kCSIIntermediateRangeEnd = 0x2F;
const int kCSIFinalRangeStart = 0x40;
const int kCSIFinalRangeEnd = 0x7E;

int get terminalColumns {
  try {
    return stdout.terminalColumns;
  } catch (e) {
    return 40;
  }
}

String get redLine {
  if (hasColor) {
    return '$red${'━' * terminalColumns}$reset';
  }
  return '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━';
}

String get clock {
  final now = DateTime.now();
  return '$reverse▌'
      '${now.hour.toString().padLeft(2, "0")}:'
      '${now.minute.toString().padLeft(2, "0")}:'
      '${now.second.toString().padLeft(2, "0")}'
      '▐$reset';
}

String prettyPrintDuration(Duration duration) {
  var result = '';
  final int minutes = duration.inMinutes;
  if (minutes > 0) {
    result += '${minutes}min ';
  }
  final int seconds = duration.inSeconds - minutes * 60;
  final int milliseconds = duration.inMilliseconds - (seconds * 1000 + minutes * 60 * 1000);
  result += '$seconds.${milliseconds.toString().padLeft(3, "0")}s';
  return result;
}

typedef PrintCallback = void Function(Object? line);
typedef VoidCallback = void Function();

// Allow print() to be overridden, for tests.
//
// Files that import this library should not import `print` from dart:core
// and should not use dart:io's `stdout` or `stderr`.
//
// By default this hides log lines between `printProgress` calls unless a
// timeout expires or anything calls `foundError`.
//
// Also used to implement `--verbose` in test.dart.
PrintCallback print = _printQuietly;

// Called by foundError and used to implement `--abort-on-error` in test.dart.
VoidCallback? onError;

bool get hasError => _hasError;
bool _hasError = false;

List<List<String>> _errorMessages = <List<String>>[];

final List<String> _pendingLogs = <String>[];
Timer? _hideTimer; // When this is null, the output is verbose.

void foundError(List<String> messages) {
  if (dryRun) {
    printProgress(messages.join('\n'));
    return;
  }
  assert(messages.isNotEmpty);
  // Make the error message easy to notice in the logs by
  // wrapping it in a red box.
  final int width = math.max(15, (hasColor ? terminalColumns : 80) - 1);
  final title = 'ERROR #${_errorMessages.length + 1}';
  print('$red╔═╡$bold$title$reset$red╞═${"═" * (width - 4 - title.length)}');
  for (final String message in messages.expand((String line) => line.split('\n'))) {
    print('$red║$reset $message');
  }
  print('$red╚${"═" * width}');
  // Normally, "print" actually prints to the log. To make the errors visible,
  // and to include useful context, print the entire log up to this point, and
  // clear it. Subsequent messages will continue to not be logged until there is
  // another error.
  _pendingLogs.forEach(_printLoudly);
  _pendingLogs.clear();
  _errorMessages.add(messages);
  _hasError = true;
  onError?.call();
}

@visibleForTesting
void resetErrorStatus() {
  _hasError = false;
  _errorMessages.clear();
  _pendingLogs.clear();
  _hideTimer?.cancel();
  _hideTimer = null;
}

Never reportSuccessAndExit(String message) {
  _hideTimer?.cancel();
  _hideTimer = null;
  print('$clock $message$reset');
  system.exit(0);
}

Never reportErrorsAndExit(String message) {
  _hideTimer?.cancel();
  _hideTimer = null;
  print('$clock $message$reset');
  print(redLine);
  print('${red}The error messages reported above are repeated here:$reset');
  final bool printSeparators = _errorMessages.any((List<String> messages) => messages.length > 1);
  if (printSeparators) {
    print('  -- This line intentionally left blank --  ');
  }
  for (var index = 0; index < _errorMessages.length * 2 - 1; index += 1) {
    if (index.isEven) {
      _errorMessages[index ~/ 2].forEach(print);
    } else if (printSeparators) {
      print('  -- This line intentionally left blank --  ');
    }
  }
  print(redLine);
  print('You may find the errors by searching for "╡ERROR #" in the logs.');
  system.exit(1);
}

void printProgress(String message) {
  _pendingLogs.clear();
  _hideTimer?.cancel();
  _hideTimer = null;
  print('$clock $message$reset');
  if (hasColor) {
    // This sets up a timer to switch to verbose mode when the tests take too long,
    // so that if a test hangs we can see the logs.
    // (This is only supported with a color terminal. When the terminal doesn't
    // support colors, the scripts just print everything verbosely, that way in
    // CI there's nothing hidden.)
    _hideTimer = Timer(_quietTimeout, () {
      _hideTimer = null;
      _pendingLogs.forEach(_printLoudly);
      _pendingLogs.clear();
    });
  }
}

final Pattern _lineBreak = RegExp(r'[\r\n]');

void _printQuietly(Object? message) {
  // The point of this function is to avoid printing its output unless the timer
  // has gone off in which case the function assumes verbose mode is active and
  // prints everything. To show that progress is still happening though, rather
  // than showing nothing at all, it instead shows the last line of output and
  // keeps overwriting it. To do this in color mode, carefully measures the line
  // of text ignoring color codes, which is what the parser below does.
  if (_hideTimer != null) {
    _pendingLogs.add(message.toString());
    String line = '$message'.trimRight();
    final int start = line.lastIndexOf(_lineBreak) + 1;
    var index = start;
    var length = 0;
    while (index < line.length && length < terminalColumns) {
      if (line.codeUnitAt(index) == kESC) {
        // 0x1B
        index += 1;
        if (index < line.length && line.codeUnitAt(index) == kOpenSquareBracket) {
          // 0x5B, [
          // That was the start of a CSI sequence.
          index += 1;
          while (index < line.length &&
              line.codeUnitAt(index) >= kCSIParameterRangeStart &&
              line.codeUnitAt(index) <= kCSIParameterRangeEnd) {
            // 0x30..0x3F
            index += 1; // ...parameter bytes...
          }
          while (index < line.length &&
              line.codeUnitAt(index) >= kCSIIntermediateRangeStart &&
              line.codeUnitAt(index) <= kCSIIntermediateRangeEnd) {
            // 0x20..0x2F
            index += 1; // ...intermediate bytes...
          }
          if (index < line.length &&
              line.codeUnitAt(index) >= kCSIFinalRangeStart &&
              line.codeUnitAt(index) <= kCSIFinalRangeEnd) {
            // 0x40..0x7E
            index += 1; // ...final byte.
          }
        }
      } else {
        index += 1;
        length += 1;
      }
    }
    line = line.substring(start, index);
    if (line.isNotEmpty) {
      stdout.write('\r\x1B[2K$white$line$reset');
    }
  } else {
    _printLoudly('$message');
  }
}

void _printLoudly(String message) {
  if (hasColor) {
    // Overwrite the last line written by _printQuietly.
    stdout.writeln('\r\x1B[2K$reset${message.trimRight()}');
  } else {
    stdout.writeln(message);
  }
}

// THE FOLLOWING CODE IS A VIOLATION OF OUR STYLE GUIDE
// BECAUSE IT INTRODUCES A VERY FLAKY RACE CONDITION
// https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#never-check-if-a-port-is-available-before-using-it-never-add-timeouts-and-other-race-conditions
// DO NOT USE THE FOLLOWING FUNCTIONS
// DO NOT WRITE CODE LIKE THE FOLLOWING FUNCTIONS
// https://github.com/flutter/flutter/issues/109474

int _portCounter = 8080;

/// Finds the next available local port.
Future<int> findAvailablePortAndPossiblyCauseFlakyTests() async {
  while (!await _isPortAvailable(_portCounter)) {
    _portCounter += 1;
  }
  return _portCounter++;
}

Future<bool> _isPortAvailable(int port) async {
  try {
    final RawSocket socket = await RawSocket.connect('localhost', port);
    socket.shutdown(SocketDirection.both);
    await socket.close();
    return false;
  } on SocketException {
    return true;
  }
}

String locationInFile(ResolvedUnitResult unit, AstNode node, String workingDirectory) {
  return '${path.relative(path.relative(unit.path, from: workingDirectory))}:${unit.lineInfo.getLocation(node.offset).lineNumber}';
}

/// Whether the given [AstNode] within the `compilationUnit` is under the effect
/// of an inline ignore directive described by `ignoreDirectivePattern`.
///
/// The `compilationUnit` parameter is the parsed dart file containing the given
/// [AstNode]. The `ignoreDirectivePattern` is a [Pattern] that should precisely
/// match the ignore directive of interest (including the slashes, example:
/// `// flutter_ignore: deprecation_syntax`).
///
/// The implementation assumes the `ignoreDirectivePattern` matches no more than
/// one line. It searches for the given `ignoreDirectivePattern` in the
/// `compilationUnit`, that either starts the line above the given `node`, or
/// appears after `node` but on the same line, such that the ignore directive
/// works the same way as dart's "ignore" comment: it can either be added above
/// or after the line that needs to be exemped.
bool hasInlineIgnore(
  AstNode node,
  ParseStringResult compilationUnit,
  Pattern ignoreDirectivePattern,
) {
  final LineInfo lineInfo = compilationUnit.lineInfo;
  // In case the node has multiple lines, match from its start offset.
  final String textAfterNode = compilationUnit.content.substring(
    node.offset,
    // This assumes every line ends with a newline character (including the last
    // line) and the new line character is not included to match the given pattern.
    lineInfo.getOffsetOfLineAfter(node.offset) - 1,
  );
  if (textAfterNode.contains(ignoreDirectivePattern)) {
    return true;
  }
  // The lineNumber getter uses one-based index while everything else uses zero-based index.
  final int lineNumber = lineInfo.getLocation(node.offset).lineNumber - 1;
  if (lineNumber <= 0) {
    return false;
  }
  return compilationUnit.content
      .substring(lineInfo.getOffsetOfLine(lineNumber - 1), lineInfo.getOffsetOfLine(lineNumber))
      .trimLeft()
      .contains(ignoreDirectivePattern);
}

// The seed used to shuffle tests. If not passed with
// --test-randomize-ordering-seed=<seed> on the command line, it will be set the
// first time it is accessed. Pass zero to turn off shuffling.
String? _shuffleSeed;

set shuffleSeed(String? newSeed) {
  _shuffleSeed = newSeed;
}

String get shuffleSeed {
  if (_shuffleSeed != null) {
    return _shuffleSeed!;
  }
  // Attempt to load from the command-line argument
  final String? seedArg = Platform.environment['--test-randomize-ordering-seed'];
  if (seedArg != null) {
    return seedArg;
  }
  // Fallback to the original time-based seed generation
  final DateTime seedTime = DateTime.now().toUtc().subtract(const Duration(hours: 7));
  _shuffleSeed = '${seedTime.year * 10000 + seedTime.month * 100 + seedTime.day}';
  return _shuffleSeed!;
}

// TODO(sigmund): includeLocalEngineEnv should default to true. Currently we
// only enable it on flutter-web test because some test suites do not work
// properly when overriding the local engine (for example, because some platform
// dependent targets are only built on some engines).
// See https://github.com/flutter/flutter/issues/72368
Future<void> runDartTest(
  String workingDirectory, {
  List<String>? testPaths,
  bool enableFlutterToolAsserts = true,
  bool useBuildRunner = false,
  String? coverage,
  bool forceSingleCore = false,
  Duration? perTestTimeout,
  bool includeLocalEngineEnv = false,
  bool ensurePrecompiledTool = true,
  bool shuffleTests = true,
  bool collectMetrics = false,
  List<String>? tags,
  bool runSkipped = false,
}) async {
  // TODO(matanlurey): Consider Platform.numberOfProcessors instead.
  // See https://github.com/flutter/flutter/issues/161399.
  var cpus = 2;

  // Integration tests that depend on external processes like chrome
  // can get stuck if there are multiple instances running at once.
  if (forceSingleCore) {
    cpus = 1;
  }

  const fileSystem = LocalFileSystem();
  final suffix = DateTime.now().microsecondsSinceEpoch.toString();
  final File metricFile = fileSystem.systemTempDirectory.childFile('metrics_$suffix.json');
  final args = <String>[
    'run',
    'test',
    '--reporter=expanded',
    '--file-reporter=json:${metricFile.path}',
    if (shuffleTests) '--test-randomize-ordering-seed=$shuffleSeed',
    '-j$cpus',
    if (!hasColor) '--no-color',
    if (coverage != null) '--coverage=$coverage',
    if (perTestTimeout != null) '--timeout=${perTestTimeout.inMilliseconds}ms',
    if (runSkipped) '--run-skipped',
    ...?tags?.map((String t) => '--tags=$t'),
    if (testPaths != null)
      for (final String testPath in testPaths) testPath,
  ];
  final environment = <String, String>{
    'FLUTTER_ROOT': flutterRoot,
    if (includeLocalEngineEnv) ...localEngineEnv,
    if (Directory(pubCache).existsSync()) 'PUB_CACHE': pubCache,
  };
  if (enableFlutterToolAsserts) {
    adjustEnvironmentToEnableFlutterAsserts(environment);
  }
  if (ensurePrecompiledTool) {
    // We rerun the `flutter` tool here just to make sure that it is compiled
    // before tests run, because the tests might time out if they have to rebuild
    // the tool themselves.
    await runCommand(flutter, <String>['--version'], environment: environment);
  }
  await runCommand(
    dart,
    args,
    workingDirectory: workingDirectory,
    environment: environment,
    removeLine: useBuildRunner ? (String line) => line.startsWith('[INFO]') : null,
  );

  if (dryRun) {
    return;
  }

  final test = TestFileReporterResults.fromFile(metricFile); // --file-reporter name
  final File info = fileSystem.file(path.join(flutterRoot, 'error.log'));
  info.writeAsStringSync(json.encode(test.errors));

  if (collectMetrics) {
    try {
      final testList = <String>[];
      final Map<int, TestSpecs> allTestSpecs = test.allTestSpecs;
      for (final TestSpecs testSpecs in allTestSpecs.values) {
        testList.add(testSpecs.toJson());
      }
      if (testList.isNotEmpty) {
        final String testJson = json.encode(testList);
        final File testResults = fileSystem.file(path.join(flutterRoot, 'test_results.json'));
        testResults.writeAsStringSync(testJson);
      }
    } on fs.FileSystemException catch (e) {
      print('Failed to generate metrics: $e');
    }
  }

  // Report the individual test cases to LUCI ResultDB (no-op when not on LUCI).
  await reportTestResultsToResultDb(test, workingDirectory: workingDirectory);

  // metriciFile is a transitional file that needs to be deleted once it is parsed.
  // TODO(godofredoc): Ensure metricFile is parsed and aggregated before deleting.
  // https://github.com/flutter/flutter/issues/146003
  metricFile.deleteSync();
}

Future<void> runFlutterTest(
  String workingDirectory, {
  String? script,
  bool expectFailure = false,
  bool printOutput = true,
  OutputChecker? outputChecker,
  List<String> options = const <String>[],
  Map<String, String>? environment,
  List<String> tests = const <String>[],
  bool shuffleTests = true,
  bool fatalWarnings = true,
}) async {
  assert(
    !printOutput || outputChecker == null,
    'Output either can be printed or checked but not both',
  );

  final tags = <String>[];
  // Recipe-configured reduced test shards will only execute tests with the
  // appropriate tag.
  if (Platform.environment['REDUCED_TEST_SET'] == 'True') {
    tags.addAll(<String>['-t', 'reduced-test-set']);
  }

  const fileSystem = LocalFileSystem();
  final suffix = DateTime.now().microsecondsSinceEpoch.toString();
  final File metricFile = fileSystem.systemTempDirectory.childFile('metrics_$suffix.json');
  final args = <String>[
    'test',
    '--reporter=expanded',
    '--file-reporter=json:${metricFile.path}',
    if (shuffleTests && !_isRandomizationOff) '--test-randomize-ordering-seed=$shuffleSeed',
    if (fatalWarnings) '--fatal-warnings',
    ...options,
    ...tags,
    ...flutterTestArgs,
  ];

  if (script != null) {
    final String fullScriptPath = path.join(workingDirectory, script);
    if (!FileSystemEntity.isFileSync(fullScriptPath)) {
      foundError(<String>[
        '${red}Could not find test$reset: $green$fullScriptPath$reset',
        'Working directory: $cyan$workingDirectory$reset',
        'Script: $green$script$reset',
        if (!printOutput) 'This is one of the tests that does not normally print output.',
      ]);
      return;
    }
    args.add(script);
  }

  args.addAll(tests);

  final OutputMode outputMode = outputChecker == null && printOutput
      ? OutputMode.print
      : OutputMode.capture;

  final CommandResult result = await runCommand(
    flutter,
    args,
    workingDirectory: workingDirectory,
    expectNonZeroExit: expectFailure,
    outputMode: outputMode,
    environment: environment,
  );

  // metriciFile is a transitional file that needs to be deleted once it is parsed.
  // TODO(godofredoc): Ensure metricFile is parsed and aggregated before deleting.
  // https://github.com/flutter/flutter/issues/146003
  if (!dryRun) {
    // Parse the test results and report the individual test cases to LUCI
    // ResultDB (no-op off LUCI) so `flutter test`-based shards populate the
    // "Test Results" tab.
    if (metricFile.existsSync()) {
      final test = TestFileReporterResults.fromFile(metricFile);
      await reportTestResultsToResultDb(
        test,
        workingDirectory: workingDirectory,
        expectFailure: expectFailure,
      );
    }
    metricFile.deleteSync();
  }

  if (outputChecker != null) {
    final String? message = outputChecker(result);
    if (message != null) {
      foundError(<String>[message]);
    }
  }
}

/// Reports the individual test cases in [test] to LUCI ResultDB so that they
/// show up in the "Test Results" tab of the LUCI build.
///
/// Uses the ResultDB Recorder API, which is available whenever the build has a
/// ResultDB invocation (the case for Flutter builds with ResultDB enabled).
///
/// This is a no-op when not running inside a LUCI build with ResultDB enabled
/// (for example, local runs), and any failure to report is logged but does not
/// fail the test run.
///
/// [workingDirectory] is the directory the shard ran the tests in; it is used to
/// resolve relative suite paths into repo-relative module names.
///
/// When [expectFailure] is true, the whole `flutter test` invocation was
/// expected to fail, so the reported results are marked as expected failures
/// (rather than red regressions) in ResultDB.
Future<void> reportTestResultsToResultDb(
  TestFileReporterResults test, {
  String? workingDirectory,
  bool expectFailure = false,
}) async {
  final List<LuciTestResult> results = convertToLuciTestResultsFormat(
    test,
    expectFailure: expectFailure,
    workingDirectory: workingDirectory,
    rootDirectory: flutterRoot,
  );
  if (results.isEmpty) {
    return;
  }

  ResultDbRecorder? recorder;
  try {
    recorder = ResultDbRecorder.fromEnvironment();
    if (recorder == null) {
      print('ResultDB is not available; skipping test result reporting.');
      return;
    }
    await recorder.reportTestResults(results);
    print('Reported ${results.length} test result(s) to ResultDB.');
  } catch (e) {
    print('Failed to report test results to ResultDB: $e');
  } finally {
    recorder?.close();
  }
}

/// This will force the next run of the Flutter tool (if it uses the provided
/// environment) to have asserts enabled, by setting an environment variable.
void adjustEnvironmentToEnableFlutterAsserts(Map<String, String> environment) {
  // If an existing env variable exists append to it, but only if
  // it doesn't appear to already include enable-asserts.
  String toolsArgs = Platform.environment['FLUTTER_TOOL_ARGS'] ?? '';
  if (!toolsArgs.contains('--enable-asserts')) {
    toolsArgs += ' --enable-asserts';
  }
  environment['FLUTTER_TOOL_ARGS'] = toolsArgs.trim();
}

Future<void> selectShard(Map<String, ShardRunner> shards) =>
    _runFromList(shards, kShardKey, 'shard', 0);
Future<void> selectSubshard(Map<String, ShardRunner> subshards) =>
    _runFromList(subshards, kSubshardKey, 'subshard', 1);

Future<void> runShardRunnerIndexOfTotalSubshard(List<ShardRunner> tests) async {
  final List<ShardRunner> sublist = selectIndexOfTotalSubshard<ShardRunner>(tests);
  for (final test in sublist) {
    await test();
  }
}

/// Parse (one-)index/total-named subshards from environment variable SUBSHARD
/// and equally distribute [tests] between them.
/// The format of SUBSHARD is "{index}_{total number of shards}".
/// The scheduler can change the number of total shards without needing an additional
/// commit in this repository.
///
/// Examples:
/// 1_3
/// 2_3
/// 3_3
List<T> selectIndexOfTotalSubshard<T>(List<T> tests, {String subshardKey = kSubshardKey}) {
  // Example: "1_3" means the first (one-indexed) shard of three total shards.
  final String? subshardName = Platform.environment[subshardKey];
  if (subshardName == null) {
    print('$kSubshardKey environment variable is missing, skipping sharding');
    return tests;
  }
  printProgress('$bold$subshardKey=$subshardName$reset');

  final pattern = RegExp(r'^(\d+)_(\d+)$');
  final Match? match = pattern.firstMatch(subshardName);
  if (match == null || match.groupCount != 2) {
    foundError(<String>[
      '${red}Invalid subshard name "$subshardName". Expected format "[int]_[int]" ex. "1_3"',
    ]);
    throw Exception('Invalid subshard name: $subshardName');
  }
  // One-indexed.
  final int index = int.parse(match.group(1)!);
  final int total = int.parse(match.group(2)!);
  if (index > total) {
    foundError(<String>[
      '${red}Invalid subshard name "$subshardName". Index number must be greater or equal to total.',
    ]);
    return <T>[];
  }

  final (int start, int end) = selectTestsForSubShard(
    testCount: tests.length,
    subShardIndex: index,
    subShardCount: total,
  );
  print('Selecting subshard $index of $total (tests ${start + 1}-$end of ${tests.length})');
  return tests.sublist(start, end);
}

/// Finds the interval of tests that a subshard is responsible for testing.
@visibleForTesting
(int start, int end) selectTestsForSubShard({
  required int testCount,
  required int subShardIndex,
  required int subShardCount,
}) {
  // While there exists a closed formula figuring out the range of tests the
  // subshard is responsible for, modeling this as a simulation of distributing
  // items equally into buckets is more intuitive.
  //
  // A bucket represents how many tests a subshard should be allocated.
  final buckets = List<int>.filled(subShardCount, 0);
  // First, allocate an equal number of items to each bucket.
  for (var i = 0; i < buckets.length; i++) {
    buckets[i] = (testCount / subShardCount).floor();
  }
  // For the N leftover items, put one into each of the first N buckets.
  final int remainingItems = testCount % buckets.length;
  for (var i = 0; i < remainingItems; i++) {
    buckets[i] += 1;
  }

  // Lastly, compute the indices of the items in buckets[index].
  // We derive this from the toal number items in previous buckets and the number
  // of items in this bucket.
  final int numberOfItemsInPreviousBuckets = subShardIndex == 0
      ? 0
      : buckets.sublist(0, subShardIndex - 1).sum;
  final start = numberOfItemsInPreviousBuckets;
  final int end = start + buckets[subShardIndex - 1];

  return (start, end);
}

Future<void> _runFromList(
  Map<String, ShardRunner> items,
  String key,
  String name,
  int positionInTaskName,
) async {
  try {
    final String? item = Platform.environment[key];
    if (item == null) {
      for (final String currentItem in items.keys) {
        printProgress('$bold$key=$currentItem$reset');
        await items[currentItem]!();
      }
    } else {
      printProgress('$bold$key=$item$reset');
      if (!items.containsKey(item)) {
        foundError(<String>[
          '${red}Invalid $name: $item$reset',
          'The available ${name}s are: ${items.keys.join(", ")}',
        ]);
        return;
      }
      await items[item]!();
    }
  } catch (_) {
    if (!dryRun) {
      rethrow;
    }
  }
}

/// Provides access to read and parse the `bin/cache/flutter.version.json`.
sealed class Version {
  static final RegExp _pattern = RegExp(r'^(\d+)\.(\d+)\.(\d+)((-\d+\.\d+)?\.pre([-\.]\d+)?)?$');

  /// Attempts to read and resolve the version stored in the [checkoutPath].
  ///
  /// If omitted, defaults the current flutter root using the real file system.
  static Future<Version> resolveIn([fs.Directory? checkoutPath]) async {
    checkoutPath ??= const LocalFileSystem().directory(flutterRoot);
    return resolveFile(
      checkoutPath.childDirectory('bin').childDirectory('cache').childFile('flutter.version.json'),
    );
  }

  /// Attempts to read and resolve the version stored in [file].
  static Future<Version> resolveFile(fs.File file) async {
    if (!file.existsSync()) {
      return VersionError._(
        'The version logic failed to create the Flutter version file: ${file.path}',
        contents: null,
      );
    }
    final Object? json = jsonDecode(await file.readAsString());
    if (json is! Map<String, Object?>) {
      return VersionError._('The version file was in an unexpected format.', contents: '$json');
    }
    final version = json['flutterVersion'] as String?;
    if (version == null) {
      return VersionError._(
        'The version file was missing the key "flutterVersion".',
        contents: '$json',
      );
    }
    if (version == '0.0.0-unknown') {
      return VersionError._(
        'The version logic failed to determine the Flutter version.',
        contents: version,
      );
    }
    if (!version.contains(_pattern)) {
      return VersionError._(
        'The version logic generated an invalid version string: "$version".',
        contents: version,
      );
    }
    return VersionOk._(version);
  }
}

/// A failed result of [Version.resolveFile].
final class VersionError implements Version {
  const VersionError._(this.error, {required this.contents});

  /// Describes the error state.
  final String error;

  /// The contents of the version file, if any.
  final String? contents;

  @override
  String toString() {
    return error;
  }
}

/// A successful result of [Version.resolveFile].
final class VersionOk implements Version {
  const VersionOk._(this.version);

  /// The contents of the version file, successfully parsed.
  final String version;
}
