// 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 revision3 = '98a5ca242b9d270ce000b26309b8a3cdc9c89df5';
  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.list(<FakeCommand>[
          const FakeCommand(command: <String>['git', 'fetch', 'upstream']),
          const FakeCommand(
            command: <String>['git', 'checkout', workingBranch],
          ),
        ]);
        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.list(<FakeCommand>[
          const FakeCommand(command: <String>['git', 'fetch', 'upstream']),
          const FakeCommand(command: <String>['git', 'checkout', workingBranch]),
          const FakeCommand(
            command: <String>['git', 'status', '--porcelain'],
            stdout: 'MM blah',
          ),
          const FakeCommand(command: <String>['git', 'add', '--all']),
          const FakeCommand(command: <String>[
            'git',
            'commit',
            "--message='add branch $candidateBranch to enabled_branches in .ci.yaml'",
          ]),
          const FakeCommand(
            command: <String>['git', 'rev-parse', 'HEAD'],
            stdout: revision2,
          ),
        ]);
        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', 'status', '--porcelain'],
            stdout: 'MM .ci.yaml',
          ),
          const FakeCommand(command: <String>['git', 'add', '--all']),
          const FakeCommand(command: <String>['git', 'commit', "--message='add branch $candidateBranch to enabled_branches in .ci.yaml'"]),
          const FakeCommand(
            command: <String>['git', 'rev-parse', 'HEAD'],
            stdout: revision2,
          ),
          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(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(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/.ci.yaml',
          ),
          const FakeCommand(command: <String>['git', 'add', '--all']),
          const FakeCommand(command: <String>[
            'git',
            'commit',
            "--message='add branch $candidateBranch to enabled_branches in .ci.yaml'",
          ]),
          const FakeCommand(
            command: <String>['git', 'rev-parse', 'HEAD'],
            stdout: revision3,
          ),
          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/.ci.yaml',
          ),
          const FakeCommand(command: <String>['git', 'add', '--all']),
          const FakeCommand(command: <String>[
            'git',
            'commit',
            "--message='add branch $candidateBranch to enabled_branches in .ci.yaml'",
          ]),
          const FakeCommand(
            command: <String>['git', 'rev-parse', 'HEAD'],
            stdout: revision3,
          ),
          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='add branch $candidateBranch to enabled_branches in .ci.yaml'",
          ]),
          const FakeCommand(
            command: <String>['git', 'rev-parse', 'HEAD'],
            stdout: revision3,
          ),
          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,
          ),
          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());
}
