// Copyright 2013 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:io' as io;

import 'package:args/command_runner.dart';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_plugin_tools/src/common/core.dart';
import 'package:flutter_plugin_tools/src/common/package_looping_command.dart';
import 'package:flutter_plugin_tools/src/common/process_runner.dart';
import 'package:git/git.dart';
import 'package:mockito/mockito.dart';
import 'package:platform/platform.dart';
import 'package:test/test.dart';

import '../mocks.dart';
import '../util.dart';
import 'package_command_test.mocks.dart';

// Constants for colorized output start and end.
const String _startElapsedTimeColor = '\x1B[90m';
const String _startErrorColor = '\x1B[31m';
const String _startHeadingColor = '\x1B[36m';
const String _startSkipColor = '\x1B[90m';
const String _startSkipWithWarningColor = '\x1B[93m';
const String _startSuccessColor = '\x1B[32m';
const String _startWarningColor = '\x1B[33m';
const String _endColor = '\x1B[0m';

// The filename within a package containing warnings to log during runForPackage.
enum _ResultFileType {
  /// A file containing errors to return.
  errors,

  /// A file containing warnings that should be logged.
  warns,

  /// A file indicating that the package should be skipped, and why.
  skips,

  /// A file indicating that the package should throw.
  throws,
}

// The filename within a package containing errors to return from runForPackage.
const String _errorFile = 'errors';
// The filename within a package indicating that it should be skipped.
const String _skipFile = 'skip';
// The filename within a package containing warnings to log during runForPackage.
const String _warningFile = 'warnings';
// The filename within a package indicating that it should throw.
const String _throwFile = 'throw';

/// Writes a file to [package] to control the behavior of
/// [TestPackageLoopingCommand] for that package.
void _addResultFile(RepositoryPackage package, _ResultFileType type,
    {String? contents}) {
  final File file = package.directory.childFile(_filenameForType(type));
  file.createSync();
  if (contents != null) {
    file.writeAsStringSync(contents);
  }
}

String _filenameForType(_ResultFileType type) {
  switch (type) {
    case _ResultFileType.errors:
      return _errorFile;
    case _ResultFileType.warns:
      return _warningFile;
    case _ResultFileType.skips:
      return _skipFile;
    case _ResultFileType.throws:
      return _throwFile;
  }
}

void main() {
  late FileSystem fileSystem;
  late MockPlatform mockPlatform;
  late Directory packagesDir;
  late Directory thirdPartyPackagesDir;

  setUp(() {
    fileSystem = MemoryFileSystem();
    mockPlatform = MockPlatform();
    packagesDir = createPackagesDirectory(fileSystem: fileSystem);
    thirdPartyPackagesDir = packagesDir.parent
        .childDirectory('third_party')
        .childDirectory('packages');
  });

  /// Creates a TestPackageLoopingCommand instance that uses [gitDiffResponse]
  /// for git diffs, and logs output to [printOutput].
  TestPackageLoopingCommand createTestCommand({
    String gitDiffResponse = '',
    bool hasLongOutput = true,
    PackageLoopingType packageLoopingType = PackageLoopingType.topLevelOnly,
    bool failsDuringInit = false,
    bool warnsDuringInit = false,
    bool warnsDuringCleanup = false,
    bool captureOutput = false,
    String? customFailureListHeader,
    String? customFailureListFooter,
  }) {
    // Set up the git diff response.
    final MockGitDir gitDir = MockGitDir();
    when(gitDir.runCommand(any, throwOnError: anyNamed('throwOnError')))
        .thenAnswer((Invocation invocation) {
      final MockProcessResult mockProcessResult = MockProcessResult();
      if (invocation.positionalArguments[0][0] == 'diff') {
        when<String?>(mockProcessResult.stdout as String?)
            .thenReturn(gitDiffResponse);
      }
      return Future<io.ProcessResult>.value(mockProcessResult);
    });

    return TestPackageLoopingCommand(
      packagesDir,
      platform: mockPlatform,
      hasLongOutput: hasLongOutput,
      packageLoopingType: packageLoopingType,
      failsDuringInit: failsDuringInit,
      warnsDuringInit: warnsDuringInit,
      warnsDuringCleanup: warnsDuringCleanup,
      customFailureListHeader: customFailureListHeader,
      customFailureListFooter: customFailureListFooter,
      captureOutput: captureOutput,
      gitDir: gitDir,
    );
  }

  /// Runs [command] with the given [arguments], and returns its output.
  Future<List<String>> runCommand(
    TestPackageLoopingCommand command, {
    List<String> arguments = const <String>[],
    void Function(Error error)? errorHandler,
  }) async {
    late CommandRunner<void> runner;
    runner = CommandRunner<void>('test_package_looping_command',
        'Test for base package looping functionality');
    runner.addCommand(command);
    return runCapturingPrint(
      runner,
      <String>[command.name, ...arguments],
      errorHandler: errorHandler,
    );
  }

  group('tool exit', () {
    test('is handled during initializeRun', () async {
      final TestPackageLoopingCommand command =
          createTestCommand(failsDuringInit: true);

      expect(() => runCommand(command), throwsA(isA<ToolExit>()));
    });

    test('does not stop looping on error', () async {
      createFakePackage('package_a', packagesDir);
      final RepositoryPackage failingPackage =
          createFakePlugin('package_b', packagesDir);
      createFakePackage('package_c', packagesDir);
      _addResultFile(failingPackage, _ResultFileType.errors);

      final TestPackageLoopingCommand command =
          createTestCommand(hasLongOutput: false);
      Error? commandError;
      final List<String> output =
          await runCommand(command, errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
          output,
          containsAllInOrder(<String>[
            '${_startHeadingColor}Running for package_a...$_endColor',
            '${_startHeadingColor}Running for package_b...$_endColor',
            '${_startHeadingColor}Running for package_c...$_endColor',
          ]));
    });

    test('does not stop looping on exceptions', () async {
      createFakePackage('package_a', packagesDir);
      final RepositoryPackage failingPackage =
          createFakePlugin('package_b', packagesDir);
      createFakePackage('package_c', packagesDir);
      _addResultFile(failingPackage, _ResultFileType.throws);

      final TestPackageLoopingCommand command =
          createTestCommand(hasLongOutput: false);
      Error? commandError;
      final List<String> output =
          await runCommand(command, errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
          output,
          containsAllInOrder(<String>[
            '${_startHeadingColor}Running for package_a...$_endColor',
            '${_startHeadingColor}Running for package_b...$_endColor',
            '${_startHeadingColor}Running for package_c...$_endColor',
          ]));
    });
  });

  group('package iteration', () {
    test('includes plugins and packages', () async {
      final RepositoryPackage plugin =
          createFakePlugin('a_plugin', packagesDir);
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir);

      final TestPackageLoopingCommand command = createTestCommand();
      await runCommand(command);

      expect(command.checkedPackages,
          unorderedEquals(<String>[plugin.path, package.path]));
    });

    test('includes third_party/packages', () async {
      final RepositoryPackage package1 =
          createFakePackage('a_package', packagesDir);
      final RepositoryPackage package2 =
          createFakePackage('another_package', thirdPartyPackagesDir);

      final TestPackageLoopingCommand command = createTestCommand();
      await runCommand(command);

      expect(command.checkedPackages,
          unorderedEquals(<String>[package1.path, package2.path]));
    });

    test('includes all subpackages when requested', () async {
      final RepositoryPackage plugin = createFakePlugin('a_plugin', packagesDir,
          examples: <String>['example1', 'example2']);
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir);
      final RepositoryPackage subPackage = createFakePackage(
          'sub_package', package.directory,
          examples: <String>[]);

      final TestPackageLoopingCommand command = createTestCommand(
          packageLoopingType: PackageLoopingType.includeAllSubpackages);
      await runCommand(command);

      expect(
          command.checkedPackages,
          unorderedEquals(<String>[
            plugin.path,
            getExampleDir(plugin).childDirectory('example1').path,
            getExampleDir(plugin).childDirectory('example2').path,
            package.path,
            getExampleDir(package).path,
            subPackage.path,
          ]));
    });

    test('includes examples when requested', () async {
      final RepositoryPackage plugin = createFakePlugin('a_plugin', packagesDir,
          examples: <String>['example1', 'example2']);
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir);
      final RepositoryPackage subPackage =
          createFakePackage('sub_package', package.directory);

      final TestPackageLoopingCommand command = createTestCommand(
          packageLoopingType: PackageLoopingType.includeExamples);
      await runCommand(command);

      expect(
          command.checkedPackages,
          unorderedEquals(<String>[
            plugin.path,
            getExampleDir(plugin).childDirectory('example1').path,
            getExampleDir(plugin).childDirectory('example2').path,
            package.path,
            getExampleDir(package).path,
          ]));
      expect(command.checkedPackages, isNot(contains(subPackage.path)));
    });

    test('excludes subpackages when main package is excluded', () async {
      final RepositoryPackage excluded = createFakePlugin(
          'a_plugin', packagesDir,
          examples: <String>['example1', 'example2']);
      final RepositoryPackage included =
          createFakePackage('a_package', packagesDir);
      final RepositoryPackage subpackage =
          createFakePackage('sub_package', excluded.directory);

      final TestPackageLoopingCommand command = createTestCommand(
          packageLoopingType: PackageLoopingType.includeAllSubpackages);
      await runCommand(command, arguments: <String>['--exclude=a_plugin']);

      final Iterable<RepositoryPackage> examples = excluded.getExamples();

      expect(
          command.checkedPackages,
          unorderedEquals(<String>[
            included.path,
            getExampleDir(included).path,
          ]));
      expect(command.checkedPackages, isNot(contains(excluded.path)));
      expect(examples.length, 2);
      for (final RepositoryPackage example in examples) {
        expect(command.checkedPackages, isNot(contains(example.path)));
      }
      expect(command.checkedPackages, isNot(contains(subpackage.path)));
    });

    test('excludes examples when main package is excluded', () async {
      final RepositoryPackage excluded = createFakePlugin(
          'a_plugin', packagesDir,
          examples: <String>['example1', 'example2']);
      final RepositoryPackage included =
          createFakePackage('a_package', packagesDir);

      final TestPackageLoopingCommand command = createTestCommand(
          packageLoopingType: PackageLoopingType.includeExamples);
      await runCommand(command, arguments: <String>['--exclude=a_plugin']);

      final Iterable<RepositoryPackage> examples = excluded.getExamples();

      expect(
          command.checkedPackages,
          unorderedEquals(<String>[
            included.path,
            getExampleDir(included).path,
          ]));
      expect(command.checkedPackages, isNot(contains(excluded.path)));
      expect(examples.length, 2);
      for (final RepositoryPackage example in examples) {
        expect(command.checkedPackages, isNot(contains(example.path)));
      }
    });

    test('skips unsupported Flutter versions when requested', () async {
      final RepositoryPackage excluded = createFakePlugin(
          'a_plugin', packagesDir,
          flutterConstraint: '>=2.10.0');
      final RepositoryPackage included =
          createFakePackage('a_package', packagesDir);

      final TestPackageLoopingCommand command = createTestCommand(
          packageLoopingType: PackageLoopingType.includeAllSubpackages,
          hasLongOutput: false);
      final List<String> output = await runCommand(command, arguments: <String>[
        '--skip-if-not-supporting-flutter-version=2.5.0'
      ]);

      expect(
          command.checkedPackages,
          unorderedEquals(<String>[
            included.path,
            getExampleDir(included).path,
          ]));
      expect(command.checkedPackages, isNot(contains(excluded.path)));

      expect(
          output,
          containsAllInOrder(<String>[
            '${_startHeadingColor}Running for a_package...$_endColor',
            '${_startHeadingColor}Running for a_plugin...$_endColor',
            '$_startSkipColor  SKIPPING: Does not support Flutter 2.5.0$_endColor',
          ]));
    });

    test('skips unsupported Dart versions when requested', () async {
      final RepositoryPackage excluded = createFakePackage(
          'excluded_package', packagesDir,
          dartConstraint: '>=2.17.0 <3.0.0');
      final RepositoryPackage included =
          createFakePackage('a_package', packagesDir);

      final TestPackageLoopingCommand command = createTestCommand(
          packageLoopingType: PackageLoopingType.includeAllSubpackages,
          hasLongOutput: false);
      final List<String> output = await runCommand(command,
          arguments: <String>['--skip-if-not-supporting-dart-version=2.14.0']);

      expect(
          command.checkedPackages,
          unorderedEquals(<String>[
            included.path,
            getExampleDir(included).path,
          ]));
      expect(command.checkedPackages, isNot(contains(excluded.path)));

      expect(
          output,
          containsAllInOrder(<String>[
            '${_startHeadingColor}Running for a_package...$_endColor',
            '${_startHeadingColor}Running for excluded_package...$_endColor',
            '$_startSkipColor  SKIPPING: Does not support Dart 2.14.0$_endColor',
          ]));
    });
  });

  group('output', () {
    test('has the expected package headers for long-form output', () async {
      createFakePlugin('package_a', packagesDir);
      createFakePackage('package_b', packagesDir);

      final TestPackageLoopingCommand command = createTestCommand();
      final List<String> output = await runCommand(command);

      const String separator =
          '============================================================';
      expect(
          output,
          containsAllInOrder(<String>[
            '$_startHeadingColor\n$separator\n|| Running for package_a\n$separator\n$_endColor',
            '$_startHeadingColor\n$separator\n|| Running for package_b\n$separator\n$_endColor',
          ]));
    });

    test('has the expected package headers for short-form output', () async {
      createFakePlugin('package_a', packagesDir);
      createFakePackage('package_b', packagesDir);

      final TestPackageLoopingCommand command =
          createTestCommand(hasLongOutput: false);
      final List<String> output = await runCommand(command);

      expect(
          output,
          containsAllInOrder(<String>[
            '${_startHeadingColor}Running for package_a...$_endColor',
            '${_startHeadingColor}Running for package_b...$_endColor',
          ]));
    });

    test('prints timing info in long-form output when requested', () async {
      createFakePlugin('package_a', packagesDir);
      createFakePackage('package_b', packagesDir);

      final TestPackageLoopingCommand command = createTestCommand();
      final List<String> output =
          await runCommand(command, arguments: <String>['--log-timing']);

      const String separator =
          '============================================================';
      expect(
          output,
          containsAllInOrder(<String>[
            '$_startHeadingColor\n$separator\n|| Running for package_a [@0:00]\n$separator\n$_endColor',
            '$_startElapsedTimeColor\n[package_a completed in 0m 0s]$_endColor',
            '$_startHeadingColor\n$separator\n|| Running for package_b [@0:00]\n$separator\n$_endColor',
            '$_startElapsedTimeColor\n[package_b completed in 0m 0s]$_endColor',
          ]));
    });

    test('prints timing info in short-form output when requested', () async {
      createFakePlugin('package_a', packagesDir);
      createFakePackage('package_b', packagesDir);

      final TestPackageLoopingCommand command =
          createTestCommand(hasLongOutput: false);
      final List<String> output =
          await runCommand(command, arguments: <String>['--log-timing']);

      expect(
          output,
          containsAllInOrder(<String>[
            '$_startHeadingColor[0:00] Running for package_a...$_endColor',
            '$_startHeadingColor[0:00] Running for package_b...$_endColor',
          ]));
      // Short-form output should not include elapsed time.
      expect(output, isNot(contains('[package_a completed in 0m 0s]')));
    });

    test('shows the success message when nothing fails', () async {
      createFakePackage('package_a', packagesDir);
      createFakePackage('package_b', packagesDir);

      final TestPackageLoopingCommand command =
          createTestCommand(hasLongOutput: false);
      final List<String> output = await runCommand(command);

      expect(
          output,
          containsAllInOrder(<String>[
            '\n',
            '${_startSuccessColor}No issues found!$_endColor',
          ]));
    });

    test('shows failure summaries when something fails without extra details',
        () async {
      createFakePackage('package_a', packagesDir);
      final RepositoryPackage failingPackage1 =
          createFakePlugin('package_b', packagesDir);
      createFakePackage('package_c', packagesDir);
      final RepositoryPackage failingPackage2 =
          createFakePlugin('package_d', packagesDir);
      _addResultFile(failingPackage1, _ResultFileType.errors);
      _addResultFile(failingPackage2, _ResultFileType.errors);

      final TestPackageLoopingCommand command =
          createTestCommand(hasLongOutput: false);
      Error? commandError;
      final List<String> output =
          await runCommand(command, errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
          output,
          containsAllInOrder(<String>[
            '\n',
            '${_startErrorColor}The following packages had errors:$_endColor',
            '$_startErrorColor  package_b$_endColor',
            '$_startErrorColor  package_d$_endColor',
            '${_startErrorColor}See above for full details.$_endColor',
          ]));
    });

    test('uses custom summary header and footer if provided', () async {
      createFakePackage('package_a', packagesDir);
      final RepositoryPackage failingPackage1 =
          createFakePlugin('package_b', packagesDir);
      createFakePackage('package_c', packagesDir);
      final RepositoryPackage failingPackage2 =
          createFakePlugin('package_d', packagesDir);
      _addResultFile(failingPackage1, _ResultFileType.errors);
      _addResultFile(failingPackage2, _ResultFileType.errors);

      final TestPackageLoopingCommand command = createTestCommand(
          hasLongOutput: false,
          customFailureListHeader: 'This is a custom header',
          customFailureListFooter: 'And a custom footer!');
      Error? commandError;
      final List<String> output =
          await runCommand(command, errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
          output,
          containsAllInOrder(<String>[
            '\n',
            '${_startErrorColor}This is a custom header$_endColor',
            '$_startErrorColor  package_b$_endColor',
            '$_startErrorColor  package_d$_endColor',
            '${_startErrorColor}And a custom footer!$_endColor',
          ]));
    });

    test('shows failure summaries when something fails with extra details',
        () async {
      createFakePackage('package_a', packagesDir);
      final RepositoryPackage failingPackage1 =
          createFakePlugin('package_b', packagesDir);
      createFakePackage('package_c', packagesDir);
      final RepositoryPackage failingPackage2 =
          createFakePlugin('package_d', packagesDir);
      _addResultFile(failingPackage1, _ResultFileType.errors,
          contents: 'just one detail');
      _addResultFile(failingPackage2, _ResultFileType.errors,
          contents: 'first detail\nsecond detail');

      final TestPackageLoopingCommand command =
          createTestCommand(hasLongOutput: false);
      Error? commandError;
      final List<String> output =
          await runCommand(command, errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
          output,
          containsAllInOrder(<String>[
            '\n',
            '${_startErrorColor}The following packages had errors:$_endColor',
            '$_startErrorColor  package_b:\n    just one detail$_endColor',
            '$_startErrorColor  package_d:\n    first detail\n    second detail$_endColor',
            '${_startErrorColor}See above for full details.$_endColor',
          ]));
    });

    test('is captured, not printed, when requested', () async {
      createFakePlugin('package_a', packagesDir);
      createFakePackage('package_b', packagesDir);

      final TestPackageLoopingCommand command =
          createTestCommand(captureOutput: true);
      final List<String> output = await runCommand(command);

      expect(output, isEmpty);

      // None of the output should be colorized when captured.
      const String separator =
          '============================================================';
      expect(
          command.capturedOutput,
          containsAllInOrder(<String>[
            '\n$separator\n|| Running for package_a\n$separator\n',
            '\n$separator\n|| Running for package_b\n$separator\n',
            'No issues found!',
          ]));
    });

    test('logs skips', () async {
      createFakePackage('package_a', packagesDir);
      final RepositoryPackage skipPackage =
          createFakePackage('package_b', packagesDir);
      _addResultFile(skipPackage, _ResultFileType.skips,
          contents: 'For a reason');

      final TestPackageLoopingCommand command =
          createTestCommand(hasLongOutput: false);
      final List<String> output = await runCommand(command);

      expect(
          output,
          containsAllInOrder(<String>[
            '${_startHeadingColor}Running for package_a...$_endColor',
            '${_startHeadingColor}Running for package_b...$_endColor',
            '$_startSkipColor  SKIPPING: For a reason$_endColor',
          ]));
    });

    test('logs exclusions', () async {
      createFakePackage('package_a', packagesDir);
      createFakePackage('package_b', packagesDir);

      final TestPackageLoopingCommand command =
          createTestCommand(hasLongOutput: false);
      final List<String> output =
          await runCommand(command, arguments: <String>['--exclude=package_b']);

      expect(
          output,
          containsAllInOrder(<String>[
            '${_startHeadingColor}Running for package_a...$_endColor',
            '${_startSkipColor}Not running for package_b; excluded$_endColor',
          ]));
    });

    test('logs warnings', () async {
      final RepositoryPackage warnPackage =
          createFakePackage('package_a', packagesDir);
      _addResultFile(warnPackage, _ResultFileType.warns,
          contents: 'Warning 1\nWarning 2');
      createFakePackage('package_b', packagesDir);

      final TestPackageLoopingCommand command =
          createTestCommand(hasLongOutput: false);
      final List<String> output = await runCommand(command);

      expect(
          output,
          containsAllInOrder(<String>[
            '${_startHeadingColor}Running for package_a...$_endColor',
            '${_startWarningColor}Warning 1$_endColor',
            '${_startWarningColor}Warning 2$_endColor',
            '${_startHeadingColor}Running for package_b...$_endColor',
          ]));
    });

    test('logs unhandled exceptions as errors', () async {
      createFakePackage('package_a', packagesDir);
      final RepositoryPackage failingPackage =
          createFakePlugin('package_b', packagesDir);
      createFakePackage('package_c', packagesDir);
      _addResultFile(failingPackage, _ResultFileType.throws);

      final TestPackageLoopingCommand command =
          createTestCommand(hasLongOutput: false);
      Error? commandError;
      final List<String> output =
          await runCommand(command, errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
          output,
          containsAllInOrder(<String>[
            '${_startErrorColor}Exception: Uh-oh$_endColor',
            '${_startErrorColor}The following packages had errors:$_endColor',
            '$_startErrorColor  package_b:\n    Unhandled exception$_endColor',
          ]));
    });

    test('prints run summary on success', () async {
      final RepositoryPackage warnPackage1 =
          createFakePackage('package_a', packagesDir);
      _addResultFile(warnPackage1, _ResultFileType.warns,
          contents: 'Warning 1\nWarning 2');

      createFakePackage('package_b', packagesDir);

      final RepositoryPackage skipPackage =
          createFakePackage('package_c', packagesDir);
      _addResultFile(skipPackage, _ResultFileType.skips,
          contents: 'For a reason');

      final RepositoryPackage skipAndWarnPackage =
          createFakePackage('package_d', packagesDir);
      _addResultFile(skipAndWarnPackage, _ResultFileType.warns,
          contents: 'Warning');
      _addResultFile(skipAndWarnPackage, _ResultFileType.skips,
          contents: 'See warning');

      final RepositoryPackage warnPackage2 =
          createFakePackage('package_e', packagesDir);
      _addResultFile(warnPackage2, _ResultFileType.warns,
          contents: 'Warning 1\nWarning 2');

      createFakePackage('package_f', packagesDir);

      final TestPackageLoopingCommand command =
          createTestCommand(hasLongOutput: false);
      final List<String> output = await runCommand(command);

      expect(
          output,
          containsAllInOrder(<String>[
            '------------------------------------------------------------',
            'Ran for 4 package(s) (2 with warnings)',
            'Skipped 2 package(s) (1 with warnings)',
            '\n',
            '${_startSuccessColor}No issues found!$_endColor',
          ]));
      // The long-form summary should not be printed for short-form commands.
      expect(output, isNot(contains('Run summary:')));
      expect(output, isNot(contains(contains('package a - ran'))));
    });

    test('counts exclusions as skips in run summary', () async {
      createFakePackage('package_a', packagesDir);

      final TestPackageLoopingCommand command =
          createTestCommand(hasLongOutput: false);
      final List<String> output =
          await runCommand(command, arguments: <String>['--exclude=package_a']);

      expect(
          output,
          containsAllInOrder(<String>[
            '------------------------------------------------------------',
            'Skipped 1 package(s)',
            '\n',
            '${_startSuccessColor}No issues found!$_endColor',
          ]));
    });

    test('prints long-form run summary for long-output commands', () async {
      final RepositoryPackage warnPackage1 =
          createFakePackage('package_a', packagesDir);
      _addResultFile(warnPackage1, _ResultFileType.warns,
          contents: 'Warning 1\nWarning 2');

      createFakePackage('package_b', packagesDir);

      final RepositoryPackage skipPackage =
          createFakePackage('package_c', packagesDir);
      _addResultFile(skipPackage, _ResultFileType.skips,
          contents: 'For a reason');

      final RepositoryPackage skipAndWarnPackage =
          createFakePackage('package_d', packagesDir);
      _addResultFile(skipAndWarnPackage, _ResultFileType.warns,
          contents: 'Warning');
      _addResultFile(skipAndWarnPackage, _ResultFileType.skips,
          contents: 'See warning');

      final RepositoryPackage warnPackage2 =
          createFakePackage('package_e', packagesDir);
      _addResultFile(warnPackage2, _ResultFileType.warns,
          contents: 'Warning 1\nWarning 2');

      createFakePackage('package_f', packagesDir);

      final TestPackageLoopingCommand command = createTestCommand();
      final List<String> output = await runCommand(command);

      expect(
          output,
          containsAllInOrder(<String>[
            '------------------------------------------------------------',
            'Run overview:',
            '  package_a - ${_startWarningColor}ran (with warning)$_endColor',
            '  package_b - ${_startSuccessColor}ran$_endColor',
            '  package_c - ${_startSkipColor}skipped$_endColor',
            '  package_d - ${_startSkipWithWarningColor}skipped (with warning)$_endColor',
            '  package_e - ${_startWarningColor}ran (with warning)$_endColor',
            '  package_f - ${_startSuccessColor}ran$_endColor',
            '',
            'Ran for 4 package(s) (2 with warnings)',
            'Skipped 2 package(s) (1 with warnings)',
            '\n',
            '${_startSuccessColor}No issues found!$_endColor',
          ]));
    });

    test('prints exclusions as skips in long-form run summary', () async {
      createFakePackage('package_a', packagesDir);

      final TestPackageLoopingCommand command = createTestCommand();
      final List<String> output =
          await runCommand(command, arguments: <String>['--exclude=package_a']);

      expect(
          output,
          containsAllInOrder(<String>[
            '  package_a - ${_startSkipColor}excluded$_endColor',
            '',
            'Skipped 1 package(s)',
            '\n',
            '${_startSuccessColor}No issues found!$_endColor',
          ]));
    });

    test('handles warnings outside of runForPackage', () async {
      createFakePackage('package_a', packagesDir);

      final TestPackageLoopingCommand command = createTestCommand(
        hasLongOutput: false,
        warnsDuringCleanup: true,
        warnsDuringInit: true,
      );
      final List<String> output = await runCommand(command);

      expect(
          output,
          containsAllInOrder(<String>[
            '${_startWarningColor}Warning during initializeRun$_endColor',
            '${_startHeadingColor}Running for package_a...$_endColor',
            '${_startWarningColor}Warning during completeRun$_endColor',
            '------------------------------------------------------------',
            'Ran for 1 package(s)',
            '2 warnings not associated with a package',
            '\n',
            '${_startSuccessColor}No issues found!$_endColor',
          ]));
    });
  });
}

class TestPackageLoopingCommand extends PackageLoopingCommand {
  TestPackageLoopingCommand(
    Directory packagesDir, {
    required Platform platform,
    this.hasLongOutput = true,
    this.packageLoopingType = PackageLoopingType.topLevelOnly,
    this.customFailureListHeader,
    this.customFailureListFooter,
    this.failsDuringInit = false,
    this.warnsDuringInit = false,
    this.warnsDuringCleanup = false,
    this.captureOutput = false,
    ProcessRunner processRunner = const ProcessRunner(),
    GitDir? gitDir,
  }) : super(packagesDir,
            processRunner: processRunner, platform: platform, gitDir: gitDir);

  final List<String> checkedPackages = <String>[];
  final List<String> capturedOutput = <String>[];

  final String? customFailureListHeader;
  final String? customFailureListFooter;

  final bool failsDuringInit;
  final bool warnsDuringInit;
  final bool warnsDuringCleanup;

  @override
  bool hasLongOutput;

  @override
  PackageLoopingType packageLoopingType;

  @override
  String get failureListHeader =>
      customFailureListHeader ?? super.failureListHeader;

  @override
  String get failureListFooter =>
      customFailureListFooter ?? super.failureListFooter;

  @override
  bool captureOutput;

  @override
  final String name = 'loop-test';

  @override
  final String description = 'sample package looping command';

  @override
  Future<void> initializeRun() async {
    if (warnsDuringInit) {
      logWarning('Warning during initializeRun');
    }
    if (failsDuringInit) {
      throw ToolExit(2);
    }
  }

  @override
  Future<PackageResult> runForPackage(RepositoryPackage package) async {
    checkedPackages.add(package.path);
    final File warningFile = package.directory.childFile(_warningFile);
    if (warningFile.existsSync()) {
      final List<String> warnings = warningFile.readAsLinesSync();
      warnings.forEach(logWarning);
    }
    final File skipFile = package.directory.childFile(_skipFile);
    if (skipFile.existsSync()) {
      return PackageResult.skip(skipFile.readAsStringSync());
    }
    final File errorFile = package.directory.childFile(_errorFile);
    if (errorFile.existsSync()) {
      return PackageResult.fail(errorFile.readAsLinesSync());
    }
    final File throwFile = package.directory.childFile(_throwFile);
    if (throwFile.existsSync()) {
      throw Exception('Uh-oh');
    }
    return PackageResult.success();
  }

  @override
  Future<void> completeRun() async {
    if (warnsDuringInit) {
      logWarning('Warning during completeRun');
    }
  }

  @override
  Future<void> handleCapturedOutput(List<String> output) async {
    capturedOutput.addAll(output);
  }
}

class MockProcessResult extends Mock implements io.ProcessResult {}
