// 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:file/file.dart' show File;
import 'package:meta/meta.dart' show visibleForTesting;

import 'context.dart';
import 'git.dart';
import 'globals.dart';
import 'proto/conductor_state.pb.dart' as pb;
import 'proto/conductor_state.pbenum.dart';
import 'repository.dart';
import 'state.dart' as state_import;

const String kStateOption = 'state-file';
const String kYesFlag = 'yes';

/// Command to proceed from one [pb.ReleasePhase] to the next.
///
/// After `conductor start`, the rest of the release steps are initiated by the
/// user via `conductor next`. Thus this command's behavior is conditional upon
/// which phase of the release the user is currently in. This is implemented
/// with a switch case statement.
class NextCommand extends Command<void> {
  NextCommand({
    required this.checkouts,
  }) {
    final String defaultPath = state_import.defaultStateFilePath(checkouts.platform);
    argParser.addOption(
      kStateOption,
      defaultsTo: defaultPath,
      help: 'Path to persistent state file. Defaults to $defaultPath',
    );
    argParser.addFlag(
      kYesFlag,
      help: 'Auto-accept any confirmation prompts.',
      hide: true, // primarily for integration testing
    );
    argParser.addFlag(
      kForceFlag,
      help: 'Force push when updating remote git branches.',
    );
  }

  final Checkouts checkouts;

  @override
  String get name => 'next';

  @override
  String get description => 'Proceed to the next release phase.';

  @override
  Future<void> run() async {
    final File stateFile = checkouts.fileSystem.file(argResults![kStateOption]);
    if (!stateFile.existsSync()) {
      throw ConductorException(
          'No persistent state file found at ${stateFile.path}.',
      );
    }
    final pb.ConductorState state = state_import.readStateFromFile(stateFile);

    await NextContext(
      autoAccept: argResults![kYesFlag] as bool,
      checkouts: checkouts,
      force: argResults![kForceFlag] as bool,
      stateFile: stateFile,
    ).run(state);
  }
}

/// Utility class for proceeding to the next step in a release.
///
/// Any calls to functions that cause side effects are wrapped in methods to
/// allow overriding in unit tests.
class NextContext extends Context {
  const NextContext({
    required this.autoAccept,
    required this.force,
    required super.checkouts,
    required super.stateFile,
  });

  final bool autoAccept;
  final bool force;

  Future<void> run(pb.ConductorState state) async {
    const List<CherrypickState> finishedStates = <CherrypickState>[
      CherrypickState.COMPLETED,
      CherrypickState.ABANDONED,
    ];
    switch (state.currentPhase) {
      case pb.ReleasePhase.APPLY_ENGINE_CHERRYPICKS:
        final Remote upstream = Remote.upstream(state.engine.upstream.url);
        final EngineRepository engine = EngineRepository(
            checkouts,
            initialRef: state.engine.workingBranch,
            upstreamRemote: upstream,
            previousCheckoutLocation: state.engine.checkoutPath,
        );
        if (!state_import.requiresEnginePR(state)) {
          stdio.printStatus(
              'This release has no engine cherrypicks. No Engine PR is necessary.\n',
          );
          break;
        }

        final List<pb.Cherrypick> unappliedCherrypicks = <pb.Cherrypick>[
          for (final pb.Cherrypick cherrypick in state.engine.cherrypicks)
            if (!finishedStates.contains(cherrypick.state)) cherrypick,
        ];

        if (unappliedCherrypicks.isEmpty) {
          stdio.printStatus('All engine cherrypicks have been auto-applied by the conductor.\n');
        } else {
          if (unappliedCherrypicks.length == 1) {
            stdio.printStatus('There was ${unappliedCherrypicks.length} cherrypick that was not auto-applied.');
          } else {
            stdio.printStatus('There were ${unappliedCherrypicks.length} cherrypicks that were not auto-applied.');
          }
          stdio.printStatus('These must be applied manually in the directory '
              '${state.engine.checkoutPath} before proceeding.\n');
        }
        if (!autoAccept) {
          final bool response = await prompt(
            'Are you ready to push your engine branch to the repository '
            '${state.engine.mirror.url}?',
          );
          if (!response) {
            stdio.printError('Aborting command.');
            updateState(state, stdio.logs);
            return;
          }
        }

        await pushWorkingBranch(engine, state.engine);
      case pb.ReleasePhase.VERIFY_ENGINE_CI:
        stdio.printStatus('You must validate post-submit CI for your engine PR and merge it');
        if (!autoAccept) {
          final bool response = await prompt(
            'Has CI passed for the engine PR?\n\n'
            '${state_import.luciConsoleLink(state.releaseChannel, 'engine')}'
          );
          if (!response) {
            stdio.printError('Aborting command.');
            updateState(state, stdio.logs);
            return;
          }
        }
      case pb.ReleasePhase.APPLY_FRAMEWORK_CHERRYPICKS:
        final Remote engineUpstreamRemote = Remote.upstream(state.engine.upstream.url);
        final EngineRepository engine = EngineRepository(
            checkouts,
            // We explicitly want to check out the merged version from upstream
            initialRef: '${engineUpstreamRemote.name}/${state.engine.candidateBranch}',
            upstreamRemote: engineUpstreamRemote,
            previousCheckoutLocation: state.engine.checkoutPath,
        );

        final String engineRevision = await engine.reverseParse('HEAD');

        final Remote upstream = Remote.upstream(state.framework.upstream.url);
        final FrameworkRepository framework = FrameworkRepository(
          checkouts,
          initialRef: state.framework.workingBranch,
          upstreamRemote: upstream,
          previousCheckoutLocation: state.framework.checkoutPath,
        );
        stdio.printStatus('Writing candidate branch...');
        bool needsCommit = await framework.updateCandidateBranchVersion(state.framework.candidateBranch);
        if (needsCommit) {
          final String revision = await framework.commit(
              'Create candidate branch version ${state.framework.candidateBranch} for ${state.releaseChannel}',
              addFirst: true,
          );
          // append to list of cherrypicks so we know a PR is required
          state.framework.cherrypicks.add(pb.Cherrypick.create()
                  ..appliedRevision = revision
                  ..state = pb.CherrypickState.COMPLETED
          );
        }
        stdio.printStatus('Rolling new engine hash $engineRevision to framework checkout...');
        needsCommit = await framework.updateEngineRevision(engineRevision);
        if (needsCommit) {
          final String revision = await framework.commit(
              'Update Engine revision to $engineRevision for ${state.releaseChannel} release ${state.releaseVersion}',
              addFirst: true,
          );
          // append to list of cherrypicks so we know a PR is required
          state.framework.cherrypicks.add(pb.Cherrypick.create()
                  ..appliedRevision = revision
                  ..state = pb.CherrypickState.COMPLETED
          );
        }

        final List<pb.Cherrypick> unappliedCherrypicks = <pb.Cherrypick>[
          for (final pb.Cherrypick cherrypick in state.framework.cherrypicks)
            if (!finishedStates.contains(cherrypick.state)) cherrypick,
        ];

        if (state.framework.cherrypicks.isEmpty) {
          stdio.printStatus(
              'This release has no framework cherrypicks. However, a framework PR is still\n'
              'required to roll engine cherrypicks.',
          );
        } else if (unappliedCherrypicks.isEmpty) {
          stdio.printStatus('All framework cherrypicks were auto-applied by the conductor.');
        } else {
          if (unappliedCherrypicks.length == 1) {
            stdio.printStatus('There was ${unappliedCherrypicks.length} cherrypick that was not auto-applied.',);
          }
          else {
            stdio.printStatus('There were ${unappliedCherrypicks.length} cherrypicks that were not auto-applied.',);
          }
          stdio.printStatus(
              'These must be applied manually in the directory '
              '${state.framework.checkoutPath} before proceeding.\n',
          );
        }

        if (!autoAccept) {
          final bool response = await prompt(
            'Are you ready to push your framework branch to the repository '
            '${state.framework.mirror.url}?',
          );
          if (!response) {
            stdio.printError('Aborting command.');
            updateState(state, stdio.logs);
            return;
          }
        }

        await pushWorkingBranch(framework, state.framework);
      case pb.ReleasePhase.PUBLISH_VERSION:
        final String command = '''
          tool-proxy-cli --tool_proxy=/abns/dart-eng-tool-proxy/prod-dart-eng-tool-proxy-tool-proxy.annealed-tool-proxy \\
          --block_on_mpa -I flutter_release \\
          :git_branch ${state.framework.candidateBranch} \\
          :release_channel ${state.releaseChannel} \\
          :tag ${state.releaseVersion} \\
          :force false
        ''';
        stdio.printStatus('Please ensure that you have merged your framework PR');
        stdio.printStatus('and post-submit CI has finished successfully.\n');
        stdio.printStatus('Run the following command, and ask a Googler');
        stdio.printStatus('to review the request\n\n$command');
      case pb.ReleasePhase.VERIFY_RELEASE:
        stdio.printStatus(
            'The current status of packaging builds can be seen at:\n'
            '\t$kLuciPackagingConsoleLink',
        );
        if (!autoAccept) {
          final bool response = await prompt(
              'Have all packaging builds finished successfully and post release announcements been completed?');
          if (!response) {
            stdio.printError('Aborting command.');
            updateState(state, stdio.logs);
            return;
          }
        }
      case pb.ReleasePhase.RELEASE_COMPLETED:
        throw ConductorException('This release is finished.');
    }
    final ReleasePhase nextPhase = state_import.getNextPhase(state.currentPhase);
    stdio.printStatus('\nUpdating phase from ${state.currentPhase} to $nextPhase...\n');
    state.currentPhase = nextPhase;
    stdio.printStatus(state_import.phaseInstructions(state));

    updateState(state, stdio.logs);
  }

  /// Push the working branch to the user's mirror.
  ///
  /// [repository] represents the actual Git repository on disk, and is used to
  /// call `git push`, while [pbRepository] represents the user-specified
  /// configuration for the repository, and is used to read the name of the
  /// working branch and the mirror's remote name.
  ///
  /// May throw either a [ConductorException] if the user already has a branch
  /// of the same name on their mirror, or a [GitException] for any other
  /// failures from the underlying git process call.
  @visibleForTesting
  Future<void> pushWorkingBranch(Repository repository, pb.Repository pbRepository) async {
    try {
      await repository.pushRef(
          fromRef: 'HEAD',
          // Explicitly create new branch
          toRef: 'refs/heads/${pbRepository.workingBranch}',
          remote: pbRepository.mirror.name,
          force: force,
      );
    } on GitException catch (exception) {
      if (exception.type == GitExceptionType.PushRejected && !force) {
        throw ConductorException(
          'Push failed because the working branch named '
          '${pbRepository.workingBranch} already exists on your mirror. '
          'Re-run this command with --force to overwrite the remote branch.\n'
          '${exception.message}',
        );
      }
      rethrow;
    }
  }
}
