#!/usr/bin/python -u
# Copyright 2019 The Dart project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# This script automates the steps required to fully roll a recent version of the
# Dart SDK into the Flutter engine (and can easily be extended to roll into the
# Flutter framework as well).
#
# The following steps are completed as part of the roll:
#   - The Dart buildbots are queried to determine which SDK revision should be
#     used. Only revisions which have finished all VM and Flutter builds will be
#     considered, and revisions with < 90% of the VM bots green are ignored. See
#     dart_buildbot_helper.py for more details.
#   - dart_roll_helper.py is run with the chosen revision. This performs all the
#     interesting parts of the roll including running tests. If the steps all
#     complete successfully, dart_roll_helper.py exits with code 0. Other
#     possible statuses are listed in dart_roll_utils.py, and will cause this
#     script to exit with a non-zero exit code. dart_roll_helper.py can also be
#     run manually to perform a Dart SDK roll with specific parameters.
#   - The commit created by dart_roll_helper.py is pushed to a branch in
#     flutter/engine and a pull request is created. Once all PR checks are
#     complete, the PR is either merged or closed and all state created by this
#     script is cleaned up.
#
# In order for this script to work, the following environment variables much be
# set:
#   - GITHUB_API_KEY: A GitHub personal access token for the GitHub account to
#     be used for uploading the SDK roll changes (see
#     https://github.com/settings/tokens)
#   - FLUTTER_HOME: the absolute path to the 'flutter' directory
#   - ENGINE_HOME: the absolute path to the 'engine/src' directory
#   - DART_SDK_HOME: the absolute path to the root of a Dart SDK project
#   - ENGINE_FORK: the name of the GitHub fork to use (e.g., bkonyi/engine or
#     flutter/engine)
#
# Finally, the following pip commands need to be run:
#   - `pip install gitpython` for GitPython (git)
#   - `pip install PyGithub` for PyGithub (github)

from dart_buildbot_helper import get_most_recent_green_build
from dart_roll_utils import *
from git import Repo
from github import Github, GithubException
import argparse
import atexit
import datetime
import os
import signal
import shutil
import subprocess
import sys
import time

GITHUB_STATUS_FAILURE = 'failure'
GITHUB_STATUS_PENDING = 'pending'
GITHUB_STATUS_SUCCESS = 'success'

PULL_REQUEST_DESCRIPTION = (
  'This is an automated pull request which will automatically merge once '
  'checks pass.'
)

FLAG_skip_wait_for_artifacts = False

CURRENT_SUBPROCESS = None
CURRENT_PR = None
GITHUB_ENGINE_REPO = None
GITHUB_ENGINE_FORK = None

def run_dart_roll_helper(most_recent_commit, extra_args):
  global CURRENT_SUBPROCESS
  os.environ["PYTHONUNBUFFERED"] = "1"
  args = ['python',
          os.path.join(os.path.dirname(__file__), 'dart_roll_helper.py'),
          '--no-hot-reload',
          most_recent_commit] + extra_args
  CURRENT_SUBPROCESS = subprocess.Popen(args)
  result = CURRENT_SUBPROCESS.wait()
  CURRENT_SUBPROCESS = None
  return result


# TODO(bkonyi): uncomment if we decide to roll into the framework.
# def get_engine_version_path(flutter_repo_path):
#  return os.path.join(flutter_repo_path,
#                      'bin',
#                      'internal',
#                      'engine.version')
#
#
# def get_current_engine_version(flutter_repo_path):
#   with open(get_engine_version_path(flutter_repo_path), 'r') as f:
#     return f.readline().strip()
#
#
# def update_engine_version(flutter_repo_path, sha):
#   with open(get_engine_version_path(flutter_repo_path), 'w') as f:
#     f.write(sha)
#
#
# def run_engine_roll_helper(engine_local_repo,
#                           flutter_repo_path,
#                           flutter_local_repo,
#                           flutter_github_repo):
#  clean_and_update_repo(engine_local_repo)
#  engine_commits  = list(engine_local_repo.iter_commits())[:2]
#  pre_roll_commit = engine_commits[1].hexsha
#  roll_commit     = engine_commits[0].hexsha
#  current_engine_version = get_current_engine_version(flutter_repo_path)
#
#  # Run `flutter doctor` until artifacts are uploaded to cloud.
#  wait_for_engine_artifacts(flutter_repo_path, roll_commit)
#
#  # Update the engine repo again to get any changes that may have gone in while
#  # waiting for the artifacts to build.
#  clean_and_update_repo(engine_local_repo)
#
#  if not is_ancestor_commit(current_engine_version,
#                            roll_commit,
#                            engine_flutter_path()):
#    print_status(('Existing revision {} already contains the Dart SDK roll. '
#                  'No more work to do!').format(current_engine_version))
#    sys.exit(ERROR_ROLL_SUCCESS)
#
#  current_date = datetime.datetime.today().strftime('%Y-%m-%d')
#  branch_name = 'dart-sdk-roll-{}'.format(current_date)
#  engine_version_path = get_engine_version_path(flutter_repo_path)
#  pr_name = 'Dart SDK roll for {}'.format(current_date)
#
#  if pre_roll_commit != current_engine_version:
#    # Update the engine version to the commit before the Dart SDK roll.
#    # This ensures that the Dart SDK version bump is the only change in
#    # the engine roll.
#    update_engine_version(flutter_repo_path, pre_roll_commit)
#    create_commit(flutter_local_repo,
#                  branch_name,
#                  'Roll engine ahead of Dart SDK roll',
#                  [engine_version_path])
#
#  # Actually update the engine version to include the Dart SDK version bump.
#  update_engine_version(flutter_repo_path, roll_commit)
#  create_commit(flutter_local_repo,
#                branch_name,
#                'Roll engine with Dart SDK roll',
#                [engine_version_path])
#
#  pull_request = create_pull_request(flutter_github_repo,
#                                     flutter_local_repo,
#                                     pr_name,
#                                     branch_name)
#
#  merge_on_success(flutter_github_repo, pull_request)
#
#
# def wait_for_engine_artifacts(flutter_repo_path, engine_revision):
#  if FLAG_skip_wait_for_artifacts:
#    print_warning('Skipping wait for Flutter engine artifacts.')
#    return
#
#  flutter_tools = os.path.join(flutter_repo_path, 'bin', 'flutter')
#  cache_path    = os.path.join(flutter_repo_path, 'bin', 'cache')
#
#  # Run `flutter doctor` until it can successfully find the engine artifacts
#  args = [flutter_tools,
#          'doctor',
#          '--check-for-remote-artifacts',
#          engine_revision]
#  while True:
#    result = subprocess.Popen(args, stdout=subprocess.DEVNULL).wait()
#    if result == 0:
#      break
#    time.sleep(15)
#
#
# def create_commit(local_repo, branch, message, files):
#  local_repo.create_head(branch)
#  local_repo.git.checkout(branch)
#  index = local_repo.index
#  index.add(files)
#  index.commit(message)


def clean_and_update_repo(local_repo):
  local_repo.git.checkout('.')
  local_repo.git.clean('-xdf')
  local_repo.git.checkout('master')
  local_repo.git.pull()

def clean_and_update_forked_repo(local_repo):
  local_repo.git.checkout('.')
  local_repo.git.clean('-xdf')
  local_repo.git.fetch('upstream')
  local_repo.git.checkout('master')
  local_repo.git.merge('upstream/master')

def clean_build_outputs():
  print_status('Cleaning build directory...')
  args = ['rm', '-rf',
          os.path.join(ENGINE_HOME, 'out')]
  CURRENT_SUBPROCESS = subprocess.Popen(args)
  CURRENT_SUBPROCESS.wait()
  CURRENT_SUBPROCESS = None

def delete_local_branch(local_repo, branch):
  print_status('Deleting local branch {} in: {}'.format(
      branch,
      local_repo.working_tree_dir))
  local_repo.git.checkout('master')
  local_repo.delete_head(branch, '-D')


def delete_remote_branch(github_repo, branch):
  print_status('Deleting remote branch on {}: {}'.format(github_repo.full_name,
                                                         branch))
  github_repo.get_git_ref('heads/{}'.format(branch)).delete()


def get_most_recent_commit(local_repo):
  commits = list(local_repo.iter_commits())[:1]
  return commits[0]


def get_pr_title(local_repo):
  commit = get_most_recent_commit(local_repo)
  return commit.message.splitlines()[0].rstrip()


def create_pull_request(github_repo, local_repo, title, branch):
  local_repo.create_head(branch)
  local_repo.git.checkout(branch)
  local_repo.git.push('origin', branch)
  commit = get_most_recent_commit(local_repo)
  description = PULL_REQUEST_DESCRIPTION + '\n\n' + commit.message
  try:
    return github_repo.create_pull(title, description,
                                   'master', '{}:{}'.format('bkonyi', branch))
  except GithubException as e:
    delete_remote_branch(GITHUB_ENGINE_FORK, branch)
    raise DartAutorollerException(e.data['errors'][0]['message'])
  finally:
    print_status('Cleaning up local branch: {}'.format(branch))
    delete_local_branch(local_repo, branch)
    # Remove the commit from the local master branch.
    local_repo.git.reset('--hard','origin/master')


def cleanup_pr(github_repo, pull_request, reason):
  msg = '{}, abandoning roll.'.format(reason)
  pull_request.create_issue_comment(msg)
  pull_request.edit(state='closed')
  print_error(msg)
  delete_remote_branch(GITHUB_ENGINE_FORK, pull_request.head.ref)


def merge_on_success(github_repo, local_repo, pull_request):
  sha = pull_request.head.sha
  commit = github_repo.get_commit(sha=sha)

  # TODO(bkonyi): Handle case where Flutter tree is red and we're trying to
  # merge into flutter/flutter.
  should_merge = wait_for_status(pull_request, commit)
  if should_merge:
    if not pull_request.is_merged():
      pull_request.create_issue_comment('Checks successful, automatically merging.')
      merge_status = pull_request.merge(merge_method='squash').merged
      if not merge_status:
        print_error('Merge failed! Aborting roll.')
        sys.exit(1)
      print_status('Merge was successful!')
    else:
      print_status('Manual merge was performed.')
  else:
    cleanup_pr(github_repo, pull_request, 'Checks failed')
    sys.exit(1)
  delete_remote_branch(GITHUB_ENGINE_FORK, pull_request.head.ref)


# TODO(bkonyi): Check to see if the Flutter build is green for flutter/flutter
# if we decide to roll the engine into the framework.
# def flutter_build_passing(commit):
#   FLUTTER_BUILD = 'flutter-build'
#   statuses = commit.get_statuses()
#   for status in statuses:
#     if status.context == FLUTTER_BUILD:
#       return (status.state == GITHUB_STATUS_SUCCESS)
# If flutter-build isn't a valid status, the PR checks don't require the
# Flutter framework to be green to submit.
#   return True

# Determines if any failures are actual failures from the PR or are just
# failures from the engine builders.
def is_only_engine_build_failing(commit):
  BUILD = '-build'
  LUCI_ENGINE = 'luci-engine'
  statuses = commit.get_statuses()
  for status in statuses:
    if (not ((BUILD in status.context) or
             (LUCI_ENGINE == status.context)) and
            (status.state == GITHUB_STATUS_FAILURE)):
        return False
  print_status("An engine builder is still failing...")
  return True


def wait_for_status(pull_request, commit):
  if FLAG_skip_wait_for_artifacts:
    return True

  print_status('Sleeping for 120 seconds to allow for Cirrus to start...')

  # Give Cirrus a chance to start. The GitHub statuses posted by Cirrus go
  # through some weird states when the PR is created and can be marked as
  # failing temporarily, causing this check to return False if we don't wait.
  time.sleep(120)

  print_status('Starting PR status checks (this may take awhile).')

  # Ensure all checks pass.
  while True:
    # Check to see if the PR was manually merged.
    if pull_request.is_merged():
      break
    status = commit.get_combined_status().state
    if status == GITHUB_STATUS_SUCCESS:
      break
    # If the only the engine builders are red, keep trying.
    elif ((status == GITHUB_STATUS_FAILURE) and
          (not is_only_engine_build_failing(commit))):
      return False
    time.sleep(5)

  # TODO(bkonyi): Re-enable this check if we decide to roll the engine into the
  # framework.
  # Once all checks are passing, wait for the Flutter build to be green.
  # while not flutter_build_passing(commit):
  #   print_status('Waiting for Flutter build to pass...')
  #   time.sleep(60)
  # print_status('Flutter build passing!')
  return True


def sys_exit(signal, frame):
  sys.exit()


def cleanup_children():
  print_error('Roll canceled! Shutting down dart_autoroller.py.')
  if CURRENT_SUBPROCESS != None:
    CURRENT_SUBPROCESS.terminate()
  if CURRENT_PR != None:
    cleanup_pr(GITHUB_ENGINE_REPO, CURRENT_PR, 'Canceled by roller')


def main():
  global CURRENT_PR
  global FLAG_skip_wait_for_artifacts
  global GITHUB_ENGINE_REPO
  global GITHUB_ENGINE_FORK

  parser = argparse.ArgumentParser(description='Dart SDK autoroller for Flutter.')
  parser.add_argument('--dart-sdk-revision',
                      help='Provide a Dart SDK revision to roll instead of '
                        'choosing one automatically')
  parser.add_argument('--no-update-repos',
                      help='Skip cleaning and updating local repositories',
                      action='store_true')
  parser.add_argument('--skip-roll',
                      help='Skip running dart_roll_helper.py',
                      action='store_true')
  parser.add_argument('--skip-tests',
                      help='Skip running Flutter tests',
                      action='store_true')
  parser.add_argument('--skip-build',
                      help='Skip building all configurations',
                      action='store_true')
  parser.add_argument('--skip-update-deps',
                      help='Skip updating the Dart SDK dependencies',
                      action='store_true')
  parser.add_argument('--skip-wait-for-artifacts',
                      help="Don't wait for PR statuses to pass or for engine" +
                      " artifacts to be uploaded to the cloud",
                      action='store_true', default=False)
  parser.add_argument('--skip-update-licenses',
                      help='Skip updating the licenses for the Flutter engine',
                      action='store_true')
  parser.add_argument('--skip-pull-request',
                      help="Skip creating a pull request and don't commit",
                      action='store_true')

  args = parser.parse_args()
  FLAG_skip_wait_for_artifacts = args.skip_wait_for_artifacts
  github_api_key = os.getenv('GITHUB_API_KEY')
  dart_sdk_path  = os.getenv('DART_SDK_HOME')
  flutter_path   = os.getenv('FLUTTER_HOME')
  engine_path    = os.getenv('ENGINE_HOME')
  engine_fork    = os.getenv('ENGINE_FORK')
  local_dart_sdk_repo       = Repo(dart_sdk_path)
  local_flutter_repo        = Repo(flutter_path)
  local_engine_flutter_repo = Repo(os.path.join(engine_path, 'flutter'))
  assert(not local_dart_sdk_repo.bare)
  assert(not local_flutter_repo.bare)
  assert(not local_engine_flutter_repo.bare)

  github = Github(github_api_key)
  GITHUB_ENGINE_REPO  = github.get_repo('flutter/engine')
  GITHUB_ENGINE_FORK  = github.get_repo(engine_fork)
  github_flutter_repo = github.get_repo('flutter/flutter')

  atexit.register(cleanup_children)
  signal.signal(signal.SIGTERM, sys_exit)

  if not args.no_update_repos:
    print_status('Cleaning and updating local trees...')
    clean_build_outputs()
    clean_and_update_repo(local_dart_sdk_repo)
    clean_and_update_repo(local_flutter_repo)
    clean_and_update_forked_repo(local_engine_flutter_repo)
  else:
    print_warning('Skipping cleaning and updating of local trees')

  # Use the most recent Dart SDK commit for the roll.
  if not args.skip_roll:
    print_status('Starting Dart roll helper')
    most_recent_commit = ''
    dart_roll_helper_args = []
    if args.skip_update_deps:
      dart_roll_helper_args.append('--no-update-deps')
    elif args.dart_sdk_revision != None:
      most_recent_commit = args.dart_sdk_revision
    else:
      # Get the most recent commit that is a reasonable candidate.
      most_recent_commit = get_most_recent_green_build()
    if args.skip_tests:
      dart_roll_helper_args.append('--no-test')
    if args.skip_build:
      dart_roll_helper_args.append('--no-build')
    if args.skip_update_licenses:
      dart_roll_helper_args.append('--no-update-licenses')
    if not args.skip_pull_request:
      dart_roll_helper_args.append('--create-commit')


    # Will exit with code ERROR_OLD_COMMIT_PROVIDED if `most_recent_commit` is
    # older than the current revision of the SDK used by Flutter.
    result = run_dart_roll_helper(most_recent_commit, dart_roll_helper_args)
    if result != 0:
      sys.exit(result)
  else:
    print_warning('Skipping roll step!')

  if not args.skip_pull_request:
    # If the local roll was successful, try to merge into the engine.
    print_status('Creating flutter/engine pull request')
    current_date = datetime.datetime.today().strftime('%Y-%m-%d')

    try:
      CURRENT_PR = create_pull_request(GITHUB_ENGINE_REPO,
                                       local_engine_flutter_repo,
                                       get_pr_title(local_engine_flutter_repo),
                                       'dart-sdk-roll-{}'.format(current_date))
    except DartAutorollerException as e:
      print_error(('Error while creating flutter/engine pull request: {}.'
                   ' Aborting roll.').format(e))
      sys.exit(1)

    print_status('Waiting for PR checks to complete...')
    merge_on_success(GITHUB_ENGINE_REPO, local_engine_flutter_repo, CURRENT_PR)
    print_status('PR checks complete!')
    CURRENT_PR = None
  else:
    print_warning('Not creating flutter/engine PR!')

  # TODO(bkonyi): uncomment if we decide to roll the engine into the framework.
  # print_status('Starting roll of flutter/engine into flutter/flutter')
  # If the roll into the engine succeeded, prep the roll into the framework.
  # run_engine_roll_helper(local_engine_flutter_repo,
  #                        flutter_path,
  #                        local_flutter_repo,
  #                        github_flutter_repo)

  # Status code should be 0 anyway, but let's make sure our exit status is
  # consistent throughout the tool on a successful roll.
  sys.exit(ERROR_ROLL_SUCCESS)

if __name__ == '__main__':
  main()
