// Copyright 2019 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 'dart:io';

import 'package:args/args.dart';
import 'package:pedantic/pedantic.dart';

const String cloudbuildDirectory = 'cloud_build';
const String workspaceDirectory = '../';

const String gcloudProjectIdFlag = 'project';
const String gcloudProjectIdAbbrFlag = 'p';

const String gcloudProjectVersionFlag = 'version';
const String gcloudProjectVersionAbbrFlag = 'v';

const String ignoreVersionFlag = 'ignore-version-check';
const String helpFlag = 'help';

String? _gcloudProjectId;
String? _gcloudProjectVersion;

late bool _ignoreVersion;

/// Check if [gcloudProjectIdFlag] and [gcloudProjectVersionFlag]
/// were passed as arguments. If they were, also set [_gcloudProjectId]
/// and [_gcloudProjectVersion] accordingly.
bool _getArgs(ArgParser argParser, List<String> arguments) {
  final ArgResults args = argParser.parse(arguments);

  final bool printHelpMessage = args[helpFlag] as bool;
  if (printHelpMessage) {
    return false;
  }

  _gcloudProjectId = args[gcloudProjectIdFlag] as String?;
  _gcloudProjectVersion = args[gcloudProjectVersionFlag] as String?;
  _ignoreVersion = args[ignoreVersionFlag] as bool;

  if (_gcloudProjectId == null) {
    stderr.write('--$gcloudProjectIdFlag must be defined\n');
    return false;
  }

  if (_gcloudProjectVersion == null) {
    stderr.write('--$gcloudProjectVersionFlag must be defined\n');
    return false;
  }

  return true;
}

/// Check the Flutter version installed and make sure it is a recent version
/// from the past 21 days.
///
/// Flutter tools handles the rest of the checks (e.g. Dart version) when
/// building the project.
Future<bool> _checkDependencies() async {
  if (_ignoreVersion) {
    return true;
  }

  stdout.writeln('Checking Flutter version via flutter --version');
  final ProcessResult result = await Process.run('flutter', <String>['--version']);
  final String flutterVersionOutput = result.stdout as String;

  // This makes an assumption that only the framework will have its version
  // printed out with the date in YYYY-MM-DD format.
  final RegExp dateRegExp = RegExp(r'([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))');
  final String flutterVersionDateRaw = dateRegExp.allMatches(flutterVersionOutput).first.group(0)!;

  final DateTime flutterVersionDate = DateTime.parse(flutterVersionDateRaw);
  final DateTime now = DateTime.now();
  final Duration lastUpdateToFlutter = now.difference(flutterVersionDate);

  return lastUpdateToFlutter.inDays < 21;
}

/// Run the Google Cloud CLI tool to deploy to [_gcloudProjectId] under
/// version [_gcloudProjectVersion].
Future<bool> _deployToAppEngine() async {
  stdout.writeln('Deploying to AppEngine');

  /// The Google Cloud deployment command is an interactive process. It will
  /// print out what it is about to do, and ask for confirmation (Y/n).
  final Process process = await Process.start(
    'gcloud',
    <String>[
      'app',
      'deploy',
      '--project',
      _gcloudProjectId!,
      '--version',
      _gcloudProjectVersion!,
      '--no-promote',
      '--no-stop-previous-version',
      '--quiet'
    ],
  );

  /// Let this user confirm the details before Google Cloud sends for deployment.
  unawaited(stdin.pipe(process.stdin));

  await process.stderr.pipe(stderr);
  await process.stdout.pipe(stdout);

  return await process.exitCode == 0;
}

/// Run [args] in bash shell and validate it finshes with exit code 0.
Future<void> shellCommand(List<String> args) async {
  final ProcessResult result = await Process.run(
    'bash',
    args,
    workingDirectory: workspaceDirectory,
  );

  if (result.exitCode != 0) {
    print('$args failed with exit code ${result.exitCode}');
    print('stdout: ${result.stdout}');
    print('stderr: ${result.stderr}');
    exit(1);
  }
}

Future<void> main(List<String> arguments) async {
  final ArgParser argParser = ArgParser()
    ..addOption(gcloudProjectIdFlag, abbr: gcloudProjectIdAbbrFlag)
    ..addOption(gcloudProjectVersionFlag, abbr: gcloudProjectVersionAbbrFlag)
    ..addFlag(ignoreVersionFlag)
    ..addFlag(helpFlag);

  if (!_getArgs(argParser, arguments)) {
    stdout.write('Required flags:\n'
        '--$gcloudProjectIdFlag gcp-id\n'
        '--$gcloudProjectVersionFlag version\n\n'
        'Optional flags:\n'
        '--$ignoreVersionFlag\tForce deploy with current Flutter version\n');
    exit(1);
  }

  if (!await _checkDependencies()) {
    stderr.writeln('Update Flutter to a version on master from the past 3 weeks to deploy Cocoon');
    exit(1);
  }

  await shellCommand(<String>['$cloudbuildDirectory/dashboard_build.sh']);
  await shellCommand(<String>['$cloudbuildDirectory/repo_dash_build.sh']);

  if (!await _deployToAppEngine()) {
    stderr.writeln('Failed to deploy to AppEngine');
    exit(1);
  }
}
