// 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/args.dart';

import 'proto/conductor_state.pb.dart' as pb;
import 'repository.dart';

const String gsutilBinary = 'gsutil.py';

const String kFrameworkDefaultBranch = 'master';
const String kForceFlag = 'force';

const List<String> kBaseReleaseChannels = <String>['stable', 'beta'];

const List<String> kReleaseChannels = <String>[...kBaseReleaseChannels, FrameworkRepository.defaultBranch];

const String kReleaseDocumentationUrl = 'https://github.com/flutter/flutter/wiki/Flutter-Cherrypick-Process';

const String kLuciPackagingConsoleLink = 'https://ci.chromium.org/p/flutter/g/packaging/console';

const String kWebsiteReleasesUrl = 'https://docs.flutter.dev/development/tools/sdk/releases';

const String discordReleaseChannel =
    'https://discord.com/channels/608014603317936148/783492179922124850';

const String flutterReleaseHotline =
    'https://mail.google.com/chat/u/0/#chat/space/AAAA6RKcK2k';

const String hotfixToStableWiki =
    'https://github.com/flutter/flutter/wiki/Hotfixes-to-the-Stable-Channel';

const String flutterAnnounceGroup =
    'https://groups.google.com/g/flutter-announce';

const String hotfixDocumentationBestPractices =
    'https://github.com/flutter/flutter/wiki/Hotfix-Documentation-Best-Practices';

final RegExp releaseCandidateBranchRegex = RegExp(
  r'flutter-(\d+)\.(\d+)-candidate\.(\d+)',
);

/// Whether all releases published to the beta channel should be mirrored to
/// dev.
const bool kSynchronizeDevWithBeta = true;

/// Cast a dynamic to String and trim.
String stdoutToString(dynamic input) {
  final String str = input as String;
  return str.trim();
}

class ConductorException implements Exception {
  ConductorException(this.message);

  final String message;

  @override
  String toString() => 'Exception: $message';
}

bool assertsEnabled() {
  // Verify asserts enabled
  bool assertsEnabled = false;

  assert(() {
    assertsEnabled = true;
    return true;
  }());
  return assertsEnabled;
}

/// Either return the value from [env] or fall back to [argResults].
///
/// If the key does not exist in either the environment or CLI args, throws a
/// [ConductorException].
///
/// The environment is favored over CLI args since the latter can have a default
/// value, which the environment should be able to override.
String? getValueFromEnvOrArgs(
  String name,
  ArgResults argResults,
  Map<String, String> env, {
  bool allowNull = false,
}) {
  final String envName = fromArgToEnvName(name);
  if (env[envName] != null) {
    return env[envName];
  }
  final String? argValue = argResults[name] as String?;
  if (argValue != null) {
    return argValue;
  }

  if (allowNull) {
    return null;
  }
  throw ConductorException('Expected either the CLI arg --$name or the environment variable $envName '
      'to be provided!');
}

bool getBoolFromEnvOrArgs(
  String name,
  ArgResults argResults,
  Map<String, String> env,
) {
  final String envName = fromArgToEnvName(name);
  if (env[envName] != null) {
    return (env[envName]?.toUpperCase()) == 'TRUE';
  }
  return argResults[name] as bool;
}

/// Return multiple values from the environment or fall back to [argResults].
///
/// Values read from an environment variable are assumed to be comma-delimited.
///
/// If the key does not exist in either the CLI args or environment, throws a
/// [ConductorException].
///
/// The environment is favored over CLI args since the latter can have a default
/// value, which the environment should be able to override.
List<String> getValuesFromEnvOrArgs(
  String name,
  ArgResults argResults,
  Map<String, String> env,
) {
  final String envName = fromArgToEnvName(name);
  if (env[envName] != null && env[envName] != '') {
    return env[envName]!.split(',');
  }
  final List<String> argValues = argResults[name] as List<String>;
  if (argValues != null) {
    return argValues;
  }

  throw ConductorException('Expected either the CLI arg --$name or the environment variable $envName '
      'to be provided!');
}

/// Translate CLI arg names to env variable names.
///
/// For example, 'state-file' -> 'STATE_FILE'.
String fromArgToEnvName(String argName) {
  return argName.toUpperCase().replaceAll(r'-', r'_');
}

/// Return a web link for the user to open a new PR.
///
/// Includes PR title and body via query params.
String getNewPrLink({
  required String userName,
  required String repoName,
  required pb.ConductorState state,
}) {
  assert(state.releaseChannel.isNotEmpty);
  assert(state.releaseVersion.isNotEmpty);
  late final String candidateBranch;
  late final String workingBranch;
  late final String repoLabel;
  switch (repoName) {
    case 'flutter':
      candidateBranch = state.framework.candidateBranch;
      workingBranch = state.framework.workingBranch;
      repoLabel = 'Framework';
      break;
    case 'engine':
      candidateBranch = state.engine.candidateBranch;
      workingBranch = state.engine.workingBranch;
      repoLabel = 'Engine';
      break;
    default:
      throw ConductorException('Expected repoName to be one of flutter or engine but got $repoName.');
  }
  assert(candidateBranch.isNotEmpty);
  assert(workingBranch.isNotEmpty);
  final String title = '[flutter_releases] Flutter ${state.releaseChannel} '
      '${state.releaseVersion} $repoLabel Cherrypicks';
  final StringBuffer body = StringBuffer();
  body.write('''
# Flutter ${state.releaseChannel} ${state.releaseVersion} $repoLabel

## Scheduled Cherrypicks

''');
  if (repoName == 'engine') {
    if (state.engine.dartRevision.isNotEmpty) {
      // shorten hashes to make final link manageable
      // prefix with github org/repo so GitHub will auto-generate a hyperlink
      body.writeln('- Roll dart revision: dart-lang/sdk@${state.engine.dartRevision.substring(0, 9)}');
    }
    for (final pb.Cherrypick cp in state.engine.cherrypicks) {
      // Only list commits that map to a commit that exists upstream.
      if (cp.trunkRevision.isNotEmpty) {
        body.writeln('- commit: flutter/engine@${cp.trunkRevision.substring(0, 9)}');
      }
    }
  } else {
    for (final pb.Cherrypick cp in state.framework.cherrypicks) {
      // Only list commits that map to a commit that exists upstream.
      if (cp.trunkRevision.isNotEmpty) {
        body.writeln('- commit: ${cp.trunkRevision.substring(0, 9)}');
      }
    }
  }
  return 'https://github.com/flutter/$repoName/compare/'
      '$candidateBranch...$userName:$workingBranch?'
      'expand=1'
      '&title=${Uri.encodeQueryComponent(title)}'
      '&body=${Uri.encodeQueryComponent(body.toString())}';
}
