// 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 './globals.dart';
import './proto/conductor_state.pb.dart' as pb;
import './proto/conductor_state.pbenum.dart';
import './repository.dart';
import './state.dart';
import './stdio.dart';

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

/// Command to proceed from one [pb.ReleasePhase] to the next.
class NextCommand extends Command<void> {
  NextCommand({
    required this.checkouts,
  }) {
    final String defaultPath = 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
  void run() {
    runNext(
      autoAccept: argResults![kYesFlag] as bool,
      checkouts: checkouts,
      force: argResults![kForceFlag] as bool,
      stateFile: checkouts.fileSystem.file(argResults![kStateOption]),
    );
  }
}

@visibleForTesting
bool prompt(String message, Stdio stdio) {
  stdio.write('${message.trim()} (y/n) ');
  final String response = stdio.readLineSync().trim();
  final String firstChar = response[0].toUpperCase();
  if (firstChar == 'Y') {
    return true;
  }
  if (firstChar == 'N') {
    return false;
  }
  throw ConductorException(
    'Unknown user input (expected "y" or "n"): $response',
  );
}

@visibleForTesting
void runNext({
  required bool autoAccept,
  required bool force,
  required Checkouts checkouts,
  required File stateFile,
}) {
  final Stdio stdio = checkouts.stdio;
  const List<CherrypickState> finishedStates = <CherrypickState>[
    CherrypickState.COMPLETED,
    CherrypickState.ABANDONED,
  ];
  if (!stateFile.existsSync()) {
    throw ConductorException(
      'No persistent state file found at ${stateFile.path}.',
    );
  }

  final pb.ConductorState state = readStateFromFile(stateFile);

  switch (state.currentPhase) {
    case pb.ReleasePhase.APPLY_ENGINE_CHERRYPICKS:
      final List<pb.Cherrypick> unappliedCherrypicks = <pb.Cherrypick>[];
      for (final pb.Cherrypick cherrypick in state.engine.cherrypicks) {
        if (!finishedStates.contains(cherrypick.state)) {
          unappliedCherrypicks.add(cherrypick);
        }
      }

      if (!requiresEnginePR(state)) {
        stdio.printStatus(
          'This release has no engine cherrypicks. No Engine PR is necessary.\n',
        );
        break;
      }

      if (unappliedCherrypicks.isEmpty) {
        stdio.printStatus('All engine cherrypicks have been auto-applied by the conductor.\n');
      } 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 == false) {
        final bool response = prompt(
          'Are you ready to push your engine branch to the repository '
          '${state.engine.mirror.url}?',
          stdio,
        );
        if (!response) {
          stdio.printError('Aborting command.');
          writeStateToFile(stateFile, state, stdio.logs);
          return;
        }
      }
      final Remote upstream = Remote(
        name: RemoteName.upstream,
        url: state.engine.upstream.url,
      );
      final EngineRepository engine = EngineRepository(
        checkouts,
        initialRef: state.engine.workingBranch,
        upstreamRemote: upstream,
        previousCheckoutLocation: state.engine.checkoutPath,
      );
      final String headRevision = engine.reverseParse('HEAD');

      engine.pushRef(
        fromRef: headRevision,
        toRef: state.engine.workingBranch,
        remote: state.engine.mirror.name,
      );

      break;
    case pb.ReleasePhase.CODESIGN_ENGINE_BINARIES:
      stdio.printStatus(<String>[
        'You must validate pre-submit CI for your engine PR, merge it, and codesign',
        'binaries before proceeding.\n',
      ].join('\n'));
      if (autoAccept == false) {
        // TODO(fujino): actually test if binaries have been codesigned on macOS
        final bool response = prompt(
          'Has CI passed for the engine PR and binaries been codesigned?',
          stdio,
        );
        if (!response) {
          stdio.printError('Aborting command.');
          writeStateToFile(stateFile, state, stdio.logs);
          return;
        }
      }
      break;
    case pb.ReleasePhase.APPLY_FRAMEWORK_CHERRYPICKS:
      final List<pb.Cherrypick> unappliedCherrypicks = <pb.Cherrypick>[];
      for (final pb.Cherrypick cherrypick in state.framework.cherrypicks) {
        if (!finishedStates.contains(cherrypick.state)) {
          unappliedCherrypicks.add(cherrypick);
        }
      }

      if (state.engine.cherrypicks.isEmpty && state.engine.dartRevision.isEmpty) {
        stdio.printStatus(
          'This release has no engine cherrypicks, and thus the engine.version file\n'
          'in the framework does not need to be updated.',
        );

        if (state.framework.cherrypicks.isEmpty) {
          stdio.printStatus(
            'This release also has no framework cherrypicks. Therefore, a framework\n'
            'pull request is not required.',
          );
          break;
        }
      }
      final Remote engineUpstreamRemote = Remote(
        name: RemoteName.upstream,
        url: 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 = engine.reverseParse('HEAD');

      final Remote upstream = Remote(
        name: RemoteName.upstream,
        url: state.framework.upstream.url,
      );
      final FrameworkRepository framework = FrameworkRepository(
        checkouts,
        initialRef: state.framework.workingBranch,
        upstreamRemote: upstream,
        previousCheckoutLocation: state.framework.checkoutPath,
      );
      final String headRevision = framework.reverseParse('HEAD');

      stdio.printStatus('Rolling new engine hash $engineRevision to framework checkout...');
      framework.updateEngineRevision(engineRevision);
      framework.commit(
          'Update Engine revision to $engineRevision for ${state.releaseChannel} release ${state.releaseVersion}',
          addFirst: true);

      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 {
        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 == false) {
        final bool response = prompt(
          'Are you ready to push your framework branch to the repository '
          '${state.framework.mirror.url}?',
          stdio,
        );
        if (!response) {
          stdio.printError('Aborting command.');
          writeStateToFile(stateFile, state, stdio.logs);
          return;
        }
      }

      framework.pushRef(
        fromRef: headRevision,
        toRef: state.framework.workingBranch,
        remote: state.framework.mirror.name,
      );
      break;
    case pb.ReleasePhase.PUBLISH_VERSION:
      stdio.printStatus('Please ensure that you have merged your framework PR and that');
      stdio.printStatus('post-submit CI has finished successfully.\n');
      final Remote upstream = Remote(
        name: RemoteName.upstream,
        url: state.framework.upstream.url,
      );
      final FrameworkRepository framework = FrameworkRepository(
        checkouts,
        // We explicitly want to check out the merged version from upstream
        initialRef: '${upstream.name}/${state.framework.candidateBranch}',
        upstreamRemote: upstream,
        previousCheckoutLocation: state.framework.checkoutPath,
      );
      final String headRevision = framework.reverseParse('HEAD');
      if (autoAccept == false) {
        final bool response = prompt(
          'Are you ready to tag commit $headRevision as ${state.releaseVersion}\n'
          'and push to remote ${state.framework.upstream.url}?',
          stdio,
        );
        if (!response) {
          stdio.printError('Aborting command.');
          writeStateToFile(stateFile, state, stdio.logs);
          return;
        }
      }
      framework.tag(headRevision, state.releaseVersion, upstream.name);
      break;
    case pb.ReleasePhase.PUBLISH_CHANNEL:
      final Remote upstream = Remote(
        name: RemoteName.upstream,
        url: state.framework.upstream.url,
      );
      final FrameworkRepository framework = FrameworkRepository(
        checkouts,
        // We explicitly want to check out the merged version from upstream
        initialRef: '${upstream.name}/${state.framework.candidateBranch}',
        upstreamRemote: upstream,
        previousCheckoutLocation: state.framework.checkoutPath,
      );
      final String headRevision = framework.reverseParse('HEAD');
      if (autoAccept == false) {
        // dryRun: true means print out git command
        framework.pushRef(
          fromRef: headRevision,
          toRef: state.releaseChannel,
          remote: state.framework.upstream.url,
          force: force,
          dryRun: true,
        );

        final bool response = prompt(
          'Are you ready to publish this release?',
          stdio,
        );
        if (!response) {
          stdio.printError('Aborting command.');
          writeStateToFile(stateFile, state, stdio.logs);
          return;
        }
      }
      framework.pushRef(
        fromRef: headRevision,
        toRef: state.releaseChannel,
        remote: state.framework.upstream.url,
        force: force,
      );
      break;
    case pb.ReleasePhase.VERIFY_RELEASE:
      stdio.printStatus(
        'The current status of packaging builds can be seen at:\n'
        '\t$kLuciPackagingConsoleLink',
      );
      if (autoAccept == false) {
        final bool response = prompt(
          'Have all packaging builds finished successfully?',
          stdio,
        );
        if (!response) {
          stdio.printError('Aborting command.');
          writeStateToFile(stateFile, state, stdio.logs);
          return;
        }
      }
      break;
    case pb.ReleasePhase.RELEASE_COMPLETED:
      throw ConductorException('This release is finished.');
  }
  final ReleasePhase nextPhase = getNextPhase(state.currentPhase);
  stdio.printStatus('\nUpdating phase from ${state.currentPhase} to $nextPhase...\n');
  state.currentPhase = nextPhase;
  stdio.printStatus(phaseInstructions(state));

  writeStateToFile(stateFile, state, stdio.logs);
}
