// 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 'package:args/command_runner.dart';
import 'package:conductor_core/src/git.dart';
import 'package:conductor_core/src/globals.dart';
import 'package:conductor_core/src/next.dart';
import 'package:conductor_core/src/proto/conductor_state.pb.dart' as pb;
import 'package:conductor_core/src/proto/conductor_state.pbenum.dart' show ReleasePhase;
import 'package:conductor_core/src/repository.dart';
import 'package:conductor_core/src/state.dart';
import 'package:conductor_core/src/stdio.dart';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:platform/platform.dart';

import './common.dart';

void main() {
  const String flutterRoot = '/flutter';
  const String checkoutsParentDirectory = '$flutterRoot/dev/conductor';
  const String candidateBranch = 'flutter-1.2-candidate.3';
  const String workingBranch = 'cherrypicks-$candidateBranch';
  const String remoteUrl = 'https://github.com/org/repo.git';
  const String revision1 = 'd3af60d18e01fcb36e0c0fa06c8502e4935ed095';
  const String revision2 = 'f99555c1e1392bf2a8135056b9446680c2af4ddf';
  const String revision4 = '280e23318a0d8341415c66aa32581352a421d974';
  const String releaseVersion = '1.2.0-3.0.pre';
  const String releaseChannel = 'beta';
  const String stateFile = '/state-file.json';
  final String localPathSeparator = const LocalPlatform().pathSeparator;
  final String localOperatingSystem = const LocalPlatform().pathSeparator;

  group('next command', () {
    late MemoryFileSystem fileSystem;
    late TestStdio stdio;

    setUp(() {
      stdio = TestStdio();
      fileSystem = MemoryFileSystem.test();
    });

    CommandRunner<void> createRunner({
      required Checkouts checkouts,
    }) {
      final NextCommand command = NextCommand(
        checkouts: checkouts,
      );
      return CommandRunner<void>('codesign-test', '')..addCommand(command);
    }

    test('throws if no state file found', () async {
      final FakeProcessManager processManager = FakeProcessManager.list(
        <FakeCommand>[],
      );
      final FakePlatform platform = FakePlatform(
        environment: <String, String>{
          'HOME': <String>['path', 'to', 'home'].join(localPathSeparator),
        },
        operatingSystem: localOperatingSystem,
        pathSeparator: localPathSeparator,
      );
      final Checkouts checkouts = Checkouts(
        fileSystem: fileSystem,
        parentDirectory: fileSystem.directory(checkoutsParentDirectory)..createSync(recursive: true),
        platform: platform,
        processManager: processManager,
        stdio: stdio,
      );
      final CommandRunner<void> runner = createRunner(checkouts: checkouts);
      expect(
        () async => runner.run(<String>[
          'next',
          '--$kStateOption',
          stateFile,
        ]),
        throwsExceptionWith('No persistent state file found at $stateFile'),
      );
    });

    group('APPLY_ENGINE_CHERRYPICKS to CODESIGN_ENGINE_BINARIES', () {
      test('does not prompt user and updates currentPhase if there are no engine cherrypicks', () async {
        final FakeProcessManager processManager = FakeProcessManager.empty();
        final FakePlatform platform = FakePlatform(
          environment: <String, String>{
            'HOME': <String>['path', 'to', 'home'].join(localPathSeparator),
          },
          operatingSystem: localOperatingSystem,
          pathSeparator: localPathSeparator,
        );
        final File ciYaml = fileSystem.file('$checkoutsParentDirectory/engine/.ci.yaml')
            ..createSync(recursive: true);
        // this branch already present in ciYaml
        _initializeCiYamlFile(ciYaml, enabledBranches: <String>[candidateBranch]);
        final pb.ConductorState state = pb.ConductorState(
          currentPhase: ReleasePhase.APPLY_ENGINE_CHERRYPICKS,
          engine: pb.Repository(
            candidateBranch: candidateBranch,
            checkoutPath: fileSystem.path.join(checkoutsParentDirectory, 'engine'),
            workingBranch: workingBranch,
            startingGitHead: revision1,
            upstream: pb.Remote(name: 'upstream', url: remoteUrl),
          ),
        );
        writeStateToFile(
          fileSystem.file(stateFile),
          state,
          <String>[],
        );
        final Checkouts checkouts = Checkouts(
          fileSystem: fileSystem,
          parentDirectory: fileSystem.directory(checkoutsParentDirectory)..createSync(recursive: true),
          platform: platform,
          processManager: processManager,
          stdio: stdio,
        );
        final CommandRunner<void> runner = createRunner(checkouts: checkouts);
        await runner.run(<String>[
          'next',
          '--$kStateOption',
          stateFile,
        ]);

        final pb.ConductorState finalState = readStateFromFile(
          fileSystem.file(stateFile),
        );

        expect(processManager, hasNoRemainingExpectations);
        expect(finalState.currentPhase, ReleasePhase.CODESIGN_ENGINE_BINARIES);
        expect(stdio.error, isEmpty);
        expect(
          stdio.stdout,
          contains('You must now codesign the engine binaries for commit $revision1'));
      });

      test('confirms to stdout when all engine cherrypicks were auto-applied', () async {
        stdio.stdin.add('n');
        final File ciYaml = fileSystem.file('$checkoutsParentDirectory/engine/.ci.yaml')
            ..createSync(recursive: true);
        _initializeCiYamlFile(ciYaml);
        final FakeProcessManager processManager = FakeProcessManager.empty();
        final FakePlatform platform = FakePlatform(
          environment: <String, String>{
            'HOME': <String>['path', 'to', 'home'].join(localPathSeparator),
          },
          operatingSystem: localOperatingSystem,
          pathSeparator: localPathSeparator,
        );
        final pb.ConductorState state = pb.ConductorState(
          engine: pb.Repository(
            candidateBranch: candidateBranch,
            cherrypicks: <pb.Cherrypick>[
              pb.Cherrypick(
                trunkRevision: 'abc123',
                state: pb.CherrypickState.COMPLETED,
              ),
            ],
            checkoutPath: fileSystem.path.join(checkoutsParentDirectory, 'engine'),
            workingBranch: workingBranch,
            upstream: pb.Remote(name: 'upstream', url: remoteUrl),
            mirror: pb.Remote(name: 'mirror', url: remoteUrl),
          ),
          currentPhase: ReleasePhase.APPLY_ENGINE_CHERRYPICKS,
        );
        writeStateToFile(
          fileSystem.file(stateFile),
          state,
          <String>[],
        );
        final Checkouts checkouts = Checkouts(
          fileSystem: fileSystem,
          parentDirectory: fileSystem.directory(checkoutsParentDirectory)..createSync(recursive: true),
          platform: platform,
          processManager: processManager,
          stdio: stdio,
        );
        final CommandRunner<void> runner = createRunner(checkouts: checkouts);
        await runner.run(<String>[
          'next',
          '--$kStateOption',
          stateFile,
        ]);

        expect(processManager, hasNoRemainingExpectations);
        expect(
          stdio.stdout,
          contains('All engine cherrypicks have been auto-applied by the conductor'),
        );
      });

      test('updates lastPhase if user responds yes', () async {
        const String remoteUrl = 'https://github.com/org/repo.git';
        const String releaseChannel = 'dev';
        stdio.stdin.add('y');
        final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
          const FakeCommand(
            command: <String>['git', 'fetch', 'upstream'],
          ),
          FakeCommand(
            command: const <String>['git', 'checkout', workingBranch],
            onRun: () {
              final File file = fileSystem.file('$checkoutsParentDirectory/engine/.ci.yaml')
                  ..createSync(recursive: true);
              _initializeCiYamlFile(file);
            },
          ),
          const FakeCommand(command: <String>['git', 'push', 'mirror', 'HEAD:refs/heads/$workingBranch']),
        ]);
        final FakePlatform platform = FakePlatform(
          environment: <String, String>{
            'HOME': <String>['path', 'to', 'home'].join(localPathSeparator),
          },
          operatingSystem: localOperatingSystem,
          pathSeparator: localPathSeparator,
        );
        final pb.ConductorState state = pb.ConductorState(
          currentPhase: ReleasePhase.APPLY_ENGINE_CHERRYPICKS,
          engine: pb.Repository(
            candidateBranch: candidateBranch,
            checkoutPath: fileSystem.path.join(checkoutsParentDirectory, 'engine'),
            cherrypicks: <pb.Cherrypick>[
              pb.Cherrypick(
                trunkRevision: revision2,
                state: pb.CherrypickState.PENDING,
              ),
            ],
            workingBranch: workingBranch,
            upstream: pb.Remote(name: 'upstream', url: remoteUrl),
            mirror: pb.Remote(name: 'mirror', url: remoteUrl),
          ),
          releaseChannel: releaseChannel,
          releaseVersion: releaseVersion,
        );
        writeStateToFile(
          fileSystem.file(stateFile),
          state,
          <String>[],
        );
        // engine dir is expected to already exist
        fileSystem.directory(checkoutsParentDirectory).childDirectory('engine').createSync(recursive: true);
        final Checkouts checkouts = Checkouts(
          fileSystem: fileSystem,
          parentDirectory: fileSystem.directory(checkoutsParentDirectory),
          platform: platform,
          processManager: processManager,
          stdio: stdio,
        );
        final CommandRunner<void> runner = createRunner(checkouts: checkouts);
        await runner.run(<String>[
          'next',
          '--$kStateOption',
          stateFile,
        ]);

        final pb.ConductorState finalState = readStateFromFile(
          fileSystem.file(stateFile),
        );

        expect(processManager, hasNoRemainingExpectations);
        expect(
          stdio.stdout,
          contains('You must now open a pull request at https://github.com/flutter/engine/compare/flutter-1.2-candidate.3...org:cherrypicks-flutter-1.2-candidate.3?expand=1'));
        expect(stdio.stdout, contains(
                'Are you ready to push your engine branch to the repository $remoteUrl? (y/n) '));
        expect(finalState.currentPhase, ReleasePhase.CODESIGN_ENGINE_BINARIES);
        expect(stdio.error, isEmpty);
      });
    });

    group('CODESIGN_ENGINE_BINARIES to APPLY_FRAMEWORK_CHERRYPICKS', () {
      late pb.ConductorState state;
      late FakeProcessManager processManager;
      late FakePlatform platform;

      setUp(() {
        state = pb.ConductorState(
          engine: pb.Repository(
            cherrypicks: <pb.Cherrypick>[
              pb.Cherrypick(
                trunkRevision: 'abc123',
                state: pb.CherrypickState.PENDING,
              ),
            ],
          ),
          currentPhase: ReleasePhase.CODESIGN_ENGINE_BINARIES,
        );

        processManager = FakeProcessManager.empty();

        platform = FakePlatform(
          environment: <String, String>{
            'HOME': <String>['path', 'to', 'home'].join(localPathSeparator),
          },
          operatingSystem: localOperatingSystem,
          pathSeparator: localPathSeparator,
        );
      });

      test('does not update currentPhase if user responds no', () async {
        stdio.stdin.add('n');
        writeStateToFile(
          fileSystem.file(stateFile),
          state,
          <String>[],
        );
        final Checkouts checkouts = Checkouts(
          fileSystem: fileSystem,
          parentDirectory: fileSystem.directory(checkoutsParentDirectory)..createSync(recursive: true),
          platform: platform,
          processManager: processManager,
          stdio: stdio,
        );
        final CommandRunner<void> runner = createRunner(checkouts: checkouts);
        await runner.run(<String>[
          'next',
          '--$kStateOption',
          stateFile,
        ]);

        final pb.ConductorState finalState = readStateFromFile(
          fileSystem.file(stateFile),
        );

        expect(processManager, hasNoRemainingExpectations);
        expect(stdio.stdout, contains('Has CI passed for the engine PR and binaries been codesigned? (y/n) '));
        expect(finalState.currentPhase, ReleasePhase.CODESIGN_ENGINE_BINARIES);
        expect(stdio.error.contains('Aborting command.'), true);
      });

      test('updates currentPhase if user responds yes', () async {
        stdio.stdin.add('y');
        final FakePlatform platform = FakePlatform(
          environment: <String, String>{
            'HOME': <String>['path', 'to', 'home'].join(localPathSeparator),
          },
          operatingSystem: localOperatingSystem,
          pathSeparator: localPathSeparator,
        );
        writeStateToFile(
          fileSystem.file(stateFile),
          state,
          <String>[],
        );
        final Checkouts checkouts = Checkouts(
          fileSystem: fileSystem,
          parentDirectory: fileSystem.directory(checkoutsParentDirectory)..createSync(recursive: true),
          platform: platform,
          processManager: processManager,
          stdio: stdio,
        );
        final CommandRunner<void> runner = createRunner(checkouts: checkouts);
        await runner.run(<String>[
          'next',
          '--$kStateOption',
          stateFile,
        ]);

        final pb.ConductorState finalState = readStateFromFile(
          fileSystem.file(stateFile),
        );

        expect(processManager, hasNoRemainingExpectations);
        expect(stdio.stdout, contains('Has CI passed for the engine PR and binaries been codesigned? (y/n) '));
        expect(finalState.currentPhase, ReleasePhase.APPLY_FRAMEWORK_CHERRYPICKS);
      });
    });

    group('APPLY_FRAMEWORK_CHERRYPICKS to PUBLISH_VERSION', () {
      const String mirrorRemoteUrl = 'https://github.com/org/repo.git';
      const String upstreamRemoteUrl = 'https://github.com/mirror/repo.git';
      const String engineUpstreamRemoteUrl = 'https://github.com/mirror/engine.git';
      const String frameworkCheckoutPath = '$checkoutsParentDirectory/framework';
      const String engineCheckoutPath = '$checkoutsParentDirectory/engine';
      const String oldEngineVersion = '000000001';
      const String frameworkCherrypick = '431ae69b4dd2dd48f7ba0153671e0311014c958b';
      late FakeProcessManager processManager;
      late FakePlatform platform;
      late pb.ConductorState state;

      setUp(() {
        processManager = FakeProcessManager.empty();
        platform = FakePlatform(
          environment: <String, String>{
            'HOME': <String>['path', 'to', 'home'].join(localPathSeparator),
          },
          operatingSystem: localOperatingSystem,
          pathSeparator: localPathSeparator,
        );
        state = pb.ConductorState(
          releaseChannel: releaseChannel,
          releaseVersion: releaseVersion,
          framework: pb.Repository(
            candidateBranch: candidateBranch,
            checkoutPath: frameworkCheckoutPath,
            cherrypicks: <pb.Cherrypick>[
              pb.Cherrypick(
                trunkRevision: frameworkCherrypick,
                state: pb.CherrypickState.PENDING,
              ),
            ],
            mirror: pb.Remote(name: 'mirror', url: mirrorRemoteUrl),
            upstream: pb.Remote(name: 'upstream', url: upstreamRemoteUrl),
            workingBranch: workingBranch,
          ),
          engine: pb.Repository(
            candidateBranch: candidateBranch,
            checkoutPath: engineCheckoutPath,
            dartRevision: 'cdef0123',
            workingBranch: workingBranch,
            upstream: pb.Remote(name: 'upstream', url: engineUpstreamRemoteUrl),
          ),
          currentPhase: ReleasePhase.APPLY_FRAMEWORK_CHERRYPICKS,
        );
        // create engine repo
        fileSystem.directory(engineCheckoutPath).createSync(recursive: true);
        // create framework repo
        final Directory frameworkDir = fileSystem.directory(frameworkCheckoutPath);
        final File engineRevisionFile = frameworkDir
            .childDirectory('bin')
            .childDirectory('internal')
            .childFile('engine.version');
        engineRevisionFile.createSync(recursive: true);
        engineRevisionFile.writeAsStringSync(oldEngineVersion, flush: true);
      });

      test('with no dart, engine or framework cherrypicks, no user input, no PR needed', () async {
        state = pb.ConductorState(
          framework: pb.Repository(
            candidateBranch: candidateBranch,
            checkoutPath: frameworkCheckoutPath,
            mirror: pb.Remote(name: 'mirror', url: mirrorRemoteUrl),
            upstream: pb.Remote(name: 'upstream', url: upstreamRemoteUrl),
            workingBranch: workingBranch,
          ),
          engine: pb.Repository(
            candidateBranch: candidateBranch,
            checkoutPath: engineCheckoutPath,
            upstream: pb.Remote(name: 'upstream', url: engineUpstreamRemoteUrl),
          ),
          currentPhase: ReleasePhase.APPLY_FRAMEWORK_CHERRYPICKS,
        );

        writeStateToFile(
          fileSystem.file(stateFile),
          state,
          <String>[],
        );

        final Checkouts checkouts = Checkouts(
          fileSystem: fileSystem,
          parentDirectory: fileSystem.directory(checkoutsParentDirectory)..createSync(recursive: true),
          platform: platform,
          processManager: processManager,
          stdio: stdio,
        );
        final CommandRunner<void> runner = createRunner(checkouts: checkouts);

        await runner.run(<String>[
          'next',
          '--$kStateOption',
          stateFile,
        ]);

        final pb.ConductorState finalState = readStateFromFile(
          fileSystem.file(stateFile),
        );

        expect(finalState.currentPhase, ReleasePhase.PUBLISH_VERSION);
        expect(stdio.error, isEmpty);
        expect(
          stdio.stdout,
          contains('pull request is not required'),
        );
      });

      test('with no engine cherrypicks but a dart revision update, updates engine revision', () async {
        stdio.stdin.add('n');
        processManager.addCommands(<FakeCommand>[
          const FakeCommand(command: <String>['git', 'fetch', 'upstream']),
          // we want merged upstream commit, not local working commit
          const FakeCommand(command: <String>['git', 'checkout', 'upstream/$candidateBranch']),
          const FakeCommand(
            command: <String>['git', 'rev-parse', 'HEAD'],
            stdout: revision1,
          ),
          const FakeCommand(command: <String>['git', 'fetch', 'upstream']),
          FakeCommand(
            command: const <String>['git', 'checkout', workingBranch],
            onRun: () {
              final File file = fileSystem.file('$checkoutsParentDirectory/framework/.ci.yaml')
                  ..createSync();
              _initializeCiYamlFile(file);
            },
          ),
          const FakeCommand(
            command: <String>['git', 'status', '--porcelain'],
            stdout: 'MM /path/to/engine.version',
          ),
          const FakeCommand(command: <String>['git', 'add', '--all']),
          const FakeCommand(command: <String>[
            'git',
            'commit',
            "--message='Update Engine revision to $revision1 for $releaseChannel release $releaseVersion'",
          ]),
          const FakeCommand(
            command: <String>['git', 'rev-parse', 'HEAD'],
            stdout: revision4,
          ),
        ]);
        final pb.ConductorState state = pb.ConductorState(
          releaseChannel: releaseChannel,
          releaseVersion: releaseVersion,
          currentPhase: ReleasePhase.APPLY_FRAMEWORK_CHERRYPICKS,
          framework: pb.Repository(
            candidateBranch: candidateBranch,
            checkoutPath: frameworkCheckoutPath,
            mirror: pb.Remote(name: 'mirror', url: mirrorRemoteUrl),
            upstream: pb.Remote(name: 'upstream', url: upstreamRemoteUrl),
            workingBranch: workingBranch,
          ),
          engine: pb.Repository(
            candidateBranch: candidateBranch,
            checkoutPath: engineCheckoutPath,
            upstream: pb.Remote(name: 'upstream', url: engineUpstreamRemoteUrl),
            dartRevision: 'abc123',
          ),
        );
        writeStateToFile(
          fileSystem.file(stateFile),
          state,
          <String>[],
        );
        final Checkouts checkouts = Checkouts(
          fileSystem: fileSystem,
          parentDirectory: fileSystem.directory(checkoutsParentDirectory)..createSync(recursive: true),
          platform: platform,
          processManager: processManager,
          stdio: stdio,
        );
        final CommandRunner<void> runner = createRunner(checkouts: checkouts);
        await runner.run(<String>[
          'next',
          '--$kStateOption',
          stateFile,
        ]);

        expect(processManager, hasNoRemainingExpectations);
        expect(stdio.stdout, contains('Updating engine revision from $oldEngineVersion to $revision1'));
        expect(stdio.stdout, contains('Are you ready to push your framework branch'));
      });

      test('does not update state.currentPhase if user responds no', () async {
        stdio.stdin.add('n');
        processManager.addCommands(<FakeCommand>[
          const FakeCommand(command: <String>['git', 'fetch', 'upstream']),
          // we want merged upstream commit, not local working commit
          FakeCommand(
            command: const <String>['git', 'checkout', 'upstream/$candidateBranch'],
            onRun: () {
              final File file = fileSystem.file('$checkoutsParentDirectory/framework/.ci.yaml')
                  ..createSync();
              _initializeCiYamlFile(file);
            },
          ),
          const FakeCommand(
            command: <String>['git', 'rev-parse', 'HEAD'],
            stdout: revision1,
          ),
          const FakeCommand(command: <String>['git', 'fetch', 'upstream']),
          const FakeCommand(command: <String>['git', 'checkout', workingBranch]),
          const FakeCommand(
            command: <String>['git', 'status', '--porcelain'],
            stdout: 'MM path/to/engine.version',
          ),
          const FakeCommand(command: <String>['git', 'add', '--all']),
          const FakeCommand(command: <String>[
            'git',
            'commit',
            "--message='Update Engine revision to $revision1 for $releaseChannel release $releaseVersion'",
          ]),
          const FakeCommand(
            command: <String>['git', 'rev-parse', 'HEAD'],
            stdout: revision4,
          ),
        ]);
        writeStateToFile(
          fileSystem.file(stateFile),
          state,
          <String>[],
        );
        final Checkouts checkouts = Checkouts(
          fileSystem: fileSystem,
          parentDirectory: fileSystem.directory(checkoutsParentDirectory)..createSync(recursive: true),
          platform: platform,
          processManager: processManager,
          stdio: stdio,
        );
        final CommandRunner<void> runner = createRunner(checkouts: checkouts);
        await runner.run(<String>[
          'next',
          '--$kStateOption',
          stateFile,
        ]);

        final pb.ConductorState finalState = readStateFromFile(
          fileSystem.file(stateFile),
        );

        expect(stdio.stdout, contains('Are you ready to push your framework branch to the repository $mirrorRemoteUrl? (y/n) '));
        expect(stdio.error, contains('Aborting command.'));
        expect(finalState.currentPhase, ReleasePhase.APPLY_FRAMEWORK_CHERRYPICKS);
      });

      test('updates state.currentPhase if user responds yes', () async {
        stdio.stdin.add('y');
        processManager.addCommands(<FakeCommand>[
          // Engine repo
          const FakeCommand(command: <String>['git', 'fetch', 'upstream']),
          // we want merged upstream commit, not local working commit
          const FakeCommand(command: <String>['git', 'checkout', 'upstream/$candidateBranch']),
          const FakeCommand(
            command: <String>['git', 'rev-parse', 'HEAD'],
            stdout: revision1,
          ),
          // Framework repo
          const FakeCommand(command: <String>['git', 'fetch', 'upstream']),
          FakeCommand(
            command: const <String>['git', 'checkout', workingBranch],
            onRun: () {
              final File file = fileSystem.file('$checkoutsParentDirectory/framework/.ci.yaml')
                  ..createSync();
              _initializeCiYamlFile(file);
            },
          ),
          const FakeCommand(
            command: <String>['git', 'status', '--porcelain'],
            stdout: 'MM path/to/.ci.yaml',
          ),
          const FakeCommand(command: <String>['git', 'add', '--all']),
          const FakeCommand(command: <String>[
            'git',
            'commit',
            "--message='Update Engine revision to $revision1 for $releaseChannel release $releaseVersion'",
          ]),
          const FakeCommand(
            command: <String>['git', 'rev-parse', 'HEAD'],
            stdout: revision4,
          ),
          const FakeCommand(
            command: <String>['git', 'push', 'mirror', 'HEAD:refs/heads/$workingBranch'],
          ),
        ]);
        writeStateToFile(
          fileSystem.file(stateFile),
          state,
          <String>[],
        );
        final Checkouts checkouts = Checkouts(
          fileSystem: fileSystem,
          parentDirectory: fileSystem.directory(checkoutsParentDirectory)..createSync(recursive: true),
          platform: platform,
          processManager: processManager,
          stdio: stdio,
        );
        final CommandRunner<void> runner = createRunner(checkouts: checkouts);
        await runner.run(<String>[
          'next',
          '--$kStateOption',
          stateFile,
        ]);

        final pb.ConductorState finalState = readStateFromFile(
          fileSystem.file(stateFile),
        );

        expect(finalState.currentPhase, ReleasePhase.PUBLISH_VERSION);
        expect(
          stdio.stdout,
          contains('Rolling new engine hash $revision1 to framework checkout...'),
        );
        expect(
          stdio.stdout,
          contains('There was 1 cherrypick that was not auto-applied'),
        );
        expect(
          stdio.stdout,
          contains('Are you ready to push your framework branch to the repository $mirrorRemoteUrl? (y/n)'),
        );
        expect(
          stdio.stdout,
          contains('Executed command: `git push mirror HEAD:refs/heads/$workingBranch`'),
        );
        expect(stdio.error, isEmpty);
      });
    });

    group('PUBLISH_VERSION to PUBLISH_CHANNEL', () {
      const String remoteName = 'upstream';
      const String releaseVersion = '1.2.0-3.0.pre';
      late pb.ConductorState state;
      late FakePlatform platform;

      setUp(() {
        state = pb.ConductorState(
          currentPhase: ReleasePhase.PUBLISH_VERSION,
          framework: pb.Repository(
            candidateBranch: candidateBranch,
            upstream: pb.Remote(url: FrameworkRepository.defaultUpstream),
          ),
          releaseVersion: releaseVersion,
        );
        platform = FakePlatform(
          environment: <String, String>{
            'HOME': <String>['path', 'to', 'home'].join(localPathSeparator),
          },
          operatingSystem: localOperatingSystem,
          pathSeparator: localPathSeparator,
        );
      });

      test('does not update state.currentPhase if user responds no', () async {
        stdio.stdin.add('n');
        final FakeProcessManager processManager = FakeProcessManager.list(
          <FakeCommand>[
            const FakeCommand(
              command: <String>['git', 'fetch', 'upstream'],
            ),
            const FakeCommand(
              command: <String>['git', 'checkout', '$remoteName/$candidateBranch'],
            ),
            const FakeCommand(
              command: <String>['git', 'rev-parse', 'HEAD'],
              stdout: revision1,
            ),
          ],
        );
        writeStateToFile(
          fileSystem.file(stateFile),
          state,
          <String>[],
        );
        final Checkouts checkouts = Checkouts(
          fileSystem: fileSystem,
          parentDirectory: fileSystem.directory(checkoutsParentDirectory)..createSync(recursive: true),
          platform: platform,
          processManager: processManager,
          stdio: stdio,
        );
        final CommandRunner<void> runner = createRunner(checkouts: checkouts);
        await runner.run(<String>[
          'next',
          '--$kStateOption',
          stateFile,
        ]);

        final pb.ConductorState finalState = readStateFromFile(
          fileSystem.file(stateFile),
        );

        expect(processManager, hasNoRemainingExpectations);
        expect(stdio.stdout, contains('Are you ready to tag commit $revision1 as $releaseVersion'));
        expect(stdio.error, contains('Aborting command.'));
        expect(finalState.currentPhase, ReleasePhase.PUBLISH_VERSION);
        expect(finalState.logs, stdio.logs);
      });

      test('updates state.currentPhase if user responds yes', () async {
        stdio.stdin.add('y');
        final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
          const FakeCommand(
            command: <String>['git', 'fetch', 'upstream'],
          ),
          const FakeCommand(
            command: <String>['git', 'checkout', '$remoteName/$candidateBranch'],
          ),
          const FakeCommand(
            command: <String>['git', 'rev-parse', 'HEAD'],
            stdout: revision1,
          ),
          const FakeCommand(
            command: <String>['git', 'tag', releaseVersion, revision1],
          ),
          const FakeCommand(
            command: <String>['git', 'push', remoteName, releaseVersion],
          ),
        ]);
        final FakePlatform platform = FakePlatform(
          environment: <String, String>{
            'HOME': <String>['path', 'to', 'home'].join(localPathSeparator),
          },
          operatingSystem: localOperatingSystem,
          pathSeparator: localPathSeparator,
        );
        writeStateToFile(
          fileSystem.file(stateFile),
          state,
          <String>[],
        );
        final Checkouts checkouts = Checkouts(
          fileSystem: fileSystem,
          parentDirectory: fileSystem.directory(checkoutsParentDirectory)..createSync(recursive: true),
          platform: platform,
          processManager: processManager,
          stdio: stdio,
        );
        final CommandRunner<void> runner = createRunner(checkouts: checkouts);
        await runner.run(<String>[
          'next',
          '--$kStateOption',
          stateFile,
        ]);

        final pb.ConductorState finalState = readStateFromFile(
          fileSystem.file(stateFile),
        );

        expect(processManager, hasNoRemainingExpectations);
        expect(finalState.currentPhase, ReleasePhase.PUBLISH_CHANNEL);
        expect(stdio.stdout, contains('Are you ready to tag commit $revision1 as $releaseVersion'));
        expect(finalState.logs, stdio.logs);
      });
    });

    group('PUBLISH_CHANNEL to VERIFY_RELEASE', () {
      const String remoteName = 'upstream';
      late pb.ConductorState state;
      late FakePlatform platform;

      setUp(() {
        state = pb.ConductorState(
          currentPhase: ReleasePhase.PUBLISH_CHANNEL,
          framework: pb.Repository(
            candidateBranch: candidateBranch,
            upstream: pb.Remote(url: FrameworkRepository.defaultUpstream),
          ),
          releaseChannel: releaseChannel,
          releaseVersion: releaseVersion,
        );
        platform = FakePlatform(
          environment: <String, String>{
            'HOME': <String>['path', 'to', 'home'].join(localPathSeparator),
          },
          operatingSystem: localOperatingSystem,
          pathSeparator: localPathSeparator,
        );
      });

      test('does not update currentPhase if user responds no', () async {
        stdio.stdin.add('n');
        final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
          const FakeCommand(
            command: <String>['git', 'fetch', 'upstream'],
          ),
          const FakeCommand(
            command: <String>['git', 'checkout', '$remoteName/$candidateBranch'],
          ),
          const FakeCommand(
            command: <String>['git', 'rev-parse', 'HEAD'],
            stdout: revision1,
          ),
        ]);
        writeStateToFile(
          fileSystem.file(stateFile),
          state,
          <String>[],
        );
        final Checkouts checkouts = Checkouts(
          fileSystem: fileSystem,
          parentDirectory: fileSystem.directory(checkoutsParentDirectory)..createSync(recursive: true),
          platform: platform,
          processManager: processManager,
          stdio: stdio,
        );
        final CommandRunner<void> runner = createRunner(checkouts: checkouts);
        await runner.run(<String>[
          'next',
          '--$kStateOption',
          stateFile,
        ]);

        final pb.ConductorState finalState = readStateFromFile(
          fileSystem.file(stateFile),
        );

        expect(processManager, hasNoRemainingExpectations);
        expect(stdio.error, contains('Aborting command.'));
        expect(
          stdio.stdout,
          contains('About to execute command: `git push ${FrameworkRepository.defaultUpstream} $revision1:$releaseChannel`'),
        );
        expect(finalState.currentPhase, ReleasePhase.PUBLISH_CHANNEL);
      });

      test('updates currentPhase if user responds yes', () async {
        stdio.stdin.add('y');
        // for kSynchronizeDevWithBeta
        stdio.stdin.add('y');
        final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
          const FakeCommand(
            command: <String>['git', 'fetch', 'upstream'],
          ),
          const FakeCommand(
            command: <String>['git', 'checkout', '$remoteName/$candidateBranch'],
          ),
          const FakeCommand(
            command: <String>['git', 'rev-parse', 'HEAD'],
            stdout: revision1,
          ),
          const FakeCommand(
            command: <String>['git', 'push', FrameworkRepository.defaultUpstream, '$revision1:$releaseChannel'],
          ),
          // for kSynchronizeDevWithBeta
          const FakeCommand(
            command: <String>['git', 'push', FrameworkRepository.defaultUpstream, '$revision1:dev'],
          ),
        ]);
        writeStateToFile(
          fileSystem.file(stateFile),
          state,
          <String>[],
        );
        final Checkouts checkouts = Checkouts(
          fileSystem: fileSystem,
          parentDirectory: fileSystem.directory(checkoutsParentDirectory)..createSync(recursive: true),
          platform: platform,
          processManager: processManager,
          stdio: stdio,
        );
        final CommandRunner<void> runner = createRunner(checkouts: checkouts);
        await runner.run(<String>[
          'next',
          '--$kStateOption',
          stateFile,
        ]);

        final pb.ConductorState finalState = readStateFromFile(
          fileSystem.file(stateFile),
        );

        expect(processManager, hasNoRemainingExpectations);
        expect(stdio.error, isEmpty);
        expect(
          stdio.stdout,
          contains('About to execute command: `git push ${FrameworkRepository.defaultUpstream} $revision1:$releaseChannel`'),
        );
        expect(
          stdio.stdout,
          contains('Release archive packages must be verified on cloud storage: https://ci.chromium.org/p/flutter/g/beta_packaging/console'),
        );
        expect(finalState.currentPhase, ReleasePhase.VERIFY_RELEASE);
      });
    });

    test('throws exception if state.currentPhase is RELEASE_COMPLETED', () async {
      final FakeProcessManager processManager = FakeProcessManager.empty();
      final FakePlatform platform = FakePlatform(
        environment: <String, String>{
          'HOME': <String>['path', 'to', 'home'].join(localPathSeparator),
        },
        operatingSystem: localOperatingSystem,
        pathSeparator: localPathSeparator,
      );
      final pb.ConductorState state = pb.ConductorState(
        currentPhase: ReleasePhase.RELEASE_COMPLETED,
      );
      writeStateToFile(
        fileSystem.file(stateFile),
        state,
        <String>[],
      );
      final Checkouts checkouts = Checkouts(
        fileSystem: fileSystem,
        parentDirectory: fileSystem.directory(checkoutsParentDirectory)..createSync(recursive: true),
        platform: platform,
        processManager: processManager,
        stdio: stdio,
      );
      final CommandRunner<void> runner = createRunner(checkouts: checkouts);
      expect(
        () async => runner.run(<String>[
          'next',
          '--$kStateOption',
          stateFile,
        ]),
        throwsExceptionWith('This release is finished.'),
      );
    });
  }, onPlatform: <String, dynamic>{
    'windows': const Skip('Flutter Conductor only supported on macos/linux'),
  });

  group('prompt', () {
    test('can be overridden for different frontend implementations', () async {
      final FileSystem fileSystem = MemoryFileSystem.test();
      final Stdio stdio = _UnimplementedStdio.instance;
      final Checkouts checkouts = Checkouts(
        fileSystem: fileSystem,
        parentDirectory: fileSystem.directory('/'),
        platform: FakePlatform(),
        processManager: FakeProcessManager.empty(),
        stdio: stdio,
      );
      final _TestNextContext context = _TestNextContext(
        checkouts: checkouts,
        stateFile: fileSystem.file('/statefile.json'),
      );

      final bool response = await context.prompt(
        'A prompt that will immediately be agreed to',
      );
      expect(response, true);
    });

    test('throws if user inputs character that is not "y" or "n"', () {
      final FileSystem fileSystem = MemoryFileSystem.test();
      final TestStdio stdio = TestStdio(
        stdin: <String>['x'],
        verbose: true,
      );
      final Checkouts checkouts = Checkouts(
        fileSystem: fileSystem,
        parentDirectory: fileSystem.directory('/'),
        platform: FakePlatform(),
        processManager: FakeProcessManager.empty(),
        stdio: stdio,
      );
      final NextContext context = NextContext(
        autoAccept: false,
        force: false,
        checkouts: checkouts,
        stateFile: fileSystem.file('/statefile.json'),
      );

      expect(
        () => context.prompt('Asking a question?'),
        throwsExceptionWith('Unknown user input (expected "y" or "n")'),
      );
    });
  });

  group('.pushWorkingBranch()', () {
    late MemoryFileSystem fileSystem;
    late TestStdio stdio;
    late Platform platform;

    setUp(() {
      stdio = TestStdio();
      fileSystem = MemoryFileSystem.test();
      platform = FakePlatform();
    });

    test('catches GitException if the push was rejected and instead throws a helpful ConductorException', () async {
      const String gitPushErrorMessage = '''
 To github.com:user/engine.git

  ! [rejected]            HEAD -> cherrypicks-flutter-2.8-candidate.3 (non-fast-forward)
 error: failed to push some refs to 'github.com:user/engine.git'
 hint: Updates were rejected because the tip of your current branch is behind
 hint: its remote counterpart. Integrate the remote changes (e.g.
 hint: 'git pull ...') before pushing again.
 hint: See the 'Note about fast-forwards' in 'git push --help' for details.
''';
      final Checkouts checkouts = Checkouts(
        fileSystem: fileSystem,
        parentDirectory: fileSystem.directory(checkoutsParentDirectory)..createSync(recursive: true),
        platform: platform,
        processManager: FakeProcessManager.empty(),
        stdio: stdio,
      );
      final Repository testRepository = _TestRepository.fromCheckouts(checkouts);
      final pb.Repository testPbRepository = pb.Repository();
      (checkouts.processManager as FakeProcessManager).addCommands(<FakeCommand>[
        FakeCommand(
          command: <String>['git', 'clone', '--origin', 'upstream', '--', testRepository.upstreamRemote.url, '/flutter/dev/conductor/flutter_conductor_checkouts/test-repo/test-repo'],
        ),
        const FakeCommand(
          command: <String>['git', 'rev-parse', 'HEAD'],
          stdout: revision1,
        ),
        FakeCommand(
          command: const <String>['git', 'push', '', 'HEAD:refs/heads/'],
          exception: GitException(gitPushErrorMessage, <String>['git', 'push', '--force', '', 'HEAD:refs/heads/']),
        )
      ]);
      final NextContext nextContext = NextContext(
        autoAccept: false,
        checkouts: checkouts,
        force: false,
        stateFile: fileSystem.file(stateFile),
      );

      expect(
        () => nextContext.pushWorkingBranch(testRepository, testPbRepository),
        throwsA(isA<ConductorException>().having(
          (ConductorException exception) => exception.message,
          'has correct message',
          contains('Re-run this command with --force to overwrite the remote branch'),
        )),
      );
    });
  });
}

/// A [Stdio] that will throw an exception if any of its methods are called.
class _UnimplementedStdio implements Stdio {
  const _UnimplementedStdio();

  static const _UnimplementedStdio _instance = _UnimplementedStdio();
  static _UnimplementedStdio get instance => _instance;

  Never _throw() => throw Exception('Unimplemented!');

  @override
  List<String> get logs => _throw();

  @override
  void printError(String message) => _throw();

  @override
  void printWarning(String message) => _throw();

  @override
  void printStatus(String message) => _throw();

  @override
  void printTrace(String message) => _throw();

  @override
  void write(String message) => _throw();

  @override
  String readLineSync() => _throw();
}

class _TestRepository extends Repository {
  _TestRepository.fromCheckouts(Checkouts checkouts, [String name = 'test-repo']) : super(
    fileSystem: checkouts.fileSystem,
    parentDirectory: checkouts.directory.childDirectory(name),
    platform: checkouts.platform,
    processManager: checkouts.processManager,
    name: name,
    requiredLocalBranches: <String>[],
    stdio: checkouts.stdio,
    upstreamRemote: const Remote(name: RemoteName.upstream, url: 'git@github.com:upstream/repo.git'),
  );

  @override
  Future<_TestRepository> cloneRepository(String? cloneName) async {
    throw Exception('Unimplemented!');
  }
}

class _TestNextContext extends NextContext {
  const _TestNextContext({
    bool autoAccept = false,
    bool force = false,
    required File stateFile,
    required Checkouts checkouts,
  }) : super(
    autoAccept: autoAccept,
    force: force,
    checkouts: checkouts,
    stateFile: stateFile,
  );

  @override
  Future<bool> prompt(String message) {
    // always say yes
    return Future<bool>.value(true);
  }
}

void _initializeCiYamlFile(
  File file, {
  List<String>? enabledBranches,
}) {
  enabledBranches ??= <String>['master', 'dev', 'beta', 'stable'];
  file.createSync(recursive: true);
  final StringBuffer buffer = StringBuffer('enabled_branches:\n');
  for (final String branch in enabledBranches) {
    buffer.writeln('  - $branch');
  }
  buffer.writeln('''

platform_properties:
  linux:
    properties:
    caches: ["name":"openjdk","path":"java"]

targets:
  - name: Linux analyze
    recipe: flutter/flutter
    timeout: 60
    properties:
      tags: >
        ["framework","hostonly"]
      validation: analyze
      validation_name: Analyze
    scheduler: luci
''');
  file.writeAsStringSync(buffer.toString());
}
