// 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 = 'ffffffffffffffffffffffffffffffffffffffff';
  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().operatingSystem;

  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 = 'beta';
        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 bin/internal/release-candidate-branch.version',
          ),
          const FakeCommand(command: <String>['git', 'add', '--all']),
          const FakeCommand(command: <String>[
            'git',
            'commit',
            '--message',
            'Create candidate branch version $candidateBranch for $releaseChannel',
          ]),
          const FakeCommand(
            command: <String>['git', 'rev-parse', 'HEAD'],
            stdout: revision3,
          ),
          const FakeCommand(
            command: <String>['git', 'status', '--porcelain'],
            stdout: 'MM bin/internal/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('release-candidate-branch.version containing $candidateBranch'));
        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 bin/internal/release-candidate-branch.version',
          ),
          const FakeCommand(command: <String>['git', 'add', '--all']),
          const FakeCommand(command: <String>[
            'git',
            'commit',
            '--message',
            'Create candidate branch version $candidateBranch for $releaseChannel',
          ]),
          const FakeCommand(
            command: <String>['git', 'rev-parse', 'HEAD'],
            stdout: revision3,
          ),
          const FakeCommand(
            command: <String>['git', 'status', '--porcelain'],
            stdout: 'MM bin/internal/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 bin/internal/release-candidate-branch.version',
          ),
          const FakeCommand(command: <String>['git', 'add', '--all']),
          const FakeCommand(command: <String>[
            'git',
            'commit',
            '--message',
            'Create candidate branch version $candidateBranch for $releaseChannel',
          ]),
          const FakeCommand(
            command: <String>['git', 'rev-parse', 'HEAD'],
            stdout: revision3,
          ),
          const FakeCommand(
            command: <String>['git', 'status', '--porcelain'],
            stdout: 'MM bin/internal/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');
        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'],
          ),
        ]);
        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({
    required super.stateFile,
    required super.checkouts,
  }) : super(autoAccept: false, force: false);

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

void _initializeCiYamlFile(
  File file, {
  List<String>? enabledBranches,
}) {
  enabledBranches ??= <String>['master', '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());
}
