#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Runs a tryjob/tryjobs after updating the packages."""

from __future__ import print_function

import argparse
import datetime
import json
import os
import subprocess

import chroot
import failure_modes
import get_llvm_hash
import update_chromeos_llvm_hash

VALID_CQ_TRYBOTS = ['llvm', 'llvm-next', 'llvm-tot']


def GetCommandLineArgs():
  """Parses the command line for the command line arguments.

  Returns:
    The log level to use when retrieving the LLVM hash or google3 LLVM version,
    the chroot path to use for executing chroot commands,
    a list of a package or packages to update their LLVM next hash,
    and the LLVM version to use when retrieving the LLVM hash.
  """

  # Default path to the chroot if a path is not specified.
  cros_root = os.path.expanduser('~')
  cros_root = os.path.join(cros_root, 'chromiumos')

  # Create parser and add optional command-line arguments.
  parser = argparse.ArgumentParser(
      description='Update an LLVM hash of packages and run tests.')

  # Add argument for other change lists that want to run alongside the tryjob
  # which has a change list of updating a package's git hash.
  parser.add_argument(
      '--extra_change_lists',
      type=int,
      nargs='+',
      default=[],
      help='change lists that would like to be run alongside the change list '
      'of updating the packages')

  # Add argument for a specific chroot path.
  parser.add_argument('--chroot_path',
                      default=cros_root,
                      help='the path to the chroot (default: %(default)s)')

  # Add argument to choose between llvm and llvm-next.
  parser.add_argument(
      '--is_llvm_next',
      action='store_true',
      help='which llvm hash to update. Update LLVM_NEXT_HASH if specified. '
      'Otherwise, update LLVM_HASH')

  # Add argument for the absolute path to the file that contains information on
  # the previous tested svn version.
  parser.add_argument(
      '--last_tested',
      help='the absolute path to the file that contains the last tested '
      'arguments.')

  # Add argument for the LLVM version to use.
  parser.add_argument('--llvm_version',
                      type=get_llvm_hash.IsSvnOption,
                      required=True,
                      help='which git hash of LLVM to find '
                      '{google3, ToT, <svn_version>} '
                      '(default: finds the git hash of the google3 LLVM '
                      'version)')

  # Add argument to add reviewers for the created CL.
  parser.add_argument('--reviewers',
                      nargs='+',
                      default=[],
                      help='The reviewers for the package update changelist')

  # Add argument for whether to display command contents to `stdout`.
  parser.add_argument('--verbose',
                      action='store_true',
                      help='display contents of a command to the terminal '
                      '(default: %(default)s)')

  subparsers = parser.add_subparsers(dest='subparser_name')
  subparser_names = []
  # Testing with the tryjobs.
  tryjob_subparser = subparsers.add_parser('tryjobs')
  subparser_names.append('tryjobs')
  tryjob_subparser.add_argument('--builders',
                                required=True,
                                nargs='+',
                                default=[],
                                help='builders to use for the tryjob testing')

  # Add argument for custom options for the tryjob.
  tryjob_subparser.add_argument('--options',
                                required=False,
                                nargs='+',
                                default=[],
                                help='options to use for the tryjob testing')

  # Testing with the recipe builders
  recipe_subparser = subparsers.add_parser('recipe')
  subparser_names.append('recipe')
  recipe_subparser.add_argument('--options',
                                required=False,
                                nargs='+',
                                default=[],
                                help='options passed to the recipe builders')

  recipe_subparser.add_argument('--builders',
                                required=True,
                                nargs='+',
                                default=[],
                                help='recipe builders to launch')

  # Testing with CQ.
  cq_subparser = subparsers.add_parser('cq')
  subparser_names.append('cq')

  # Add argument for specify a cq trybot to test along with other cq builders
  # e.g. llvm, llvm-next or llvm-tot
  cq_subparser.add_argument(
      '--cq_trybot',
      choices=VALID_CQ_TRYBOTS,
      help='include the trybot to test together with other cq builders '
      'available: %(choices)s')

  args_output = parser.parse_args()

  if args_output.subparser_name not in subparser_names:
    parser.error('one of %s must be specified' % subparser_names)

  return args_output


def UnchangedSinceLastRun(last_tested_file, arg_dict):
  """Gets the arguments used for last run

  Args:
    last_tested_file: The absolute path to the file that contains the
    arguments for the last run.
    arg_dict: The arguments used for this run.

  Returns:
    Return true if the arguments used for last run exist and are the
    same as the arguments used for this run. Otherwise return false.
  """

  if not last_tested_file:
    return False

  # Get the last tested svn version if the file exists.
  last_arg_dict = None
  try:
    with open(last_tested_file) as f:
      last_arg_dict = json.load(f)

  except (IOError, ValueError):
    return False

  return arg_dict == last_arg_dict


def AddReviewers(cl, reviewers, chroot_path):
  """Add reviewers for the created CL."""

  gerrit_abs_path = os.path.join(chroot_path, 'chromite/bin/gerrit')
  for reviewer in reviewers:
    cmd = [gerrit_abs_path, 'reviewers', str(cl), reviewer]

    subprocess.check_output(cmd)


def AddLinksToCL(tests, cl, chroot_path):
  """Adds the test link(s) to the CL as a comment."""

  # NOTE: Invoking `cros_sdk` does not make each tryjob link appear on its own
  # line, so invoking the `gerrit` command directly instead of using `cros_sdk`
  # to do it for us.
  #
  # FIXME: Need to figure out why `cros_sdk` does not add each tryjob link as a
  # newline.
  gerrit_abs_path = os.path.join(chroot_path, 'chromite/bin/gerrit')

  links = ['Started the following tests:']
  links.extend(test['link'] for test in tests)

  add_message_cmd = [gerrit_abs_path, 'message', str(cl), '\n'.join(links)]

  subprocess.check_output(add_message_cmd)


# Testing with tryjobs
def GetCurrentTimeInUTC():
  """Returns the current time via `datetime.datetime.utcnow()`."""
  return datetime.datetime.utcnow()


def GetTryJobCommand(change_list, extra_change_lists, options, builder):
  """Constructs the 'tryjob' command.

  Args:
    change_list: The CL obtained from updating the packages.
    extra_change_lists: Extra change lists that would like to be run alongside
    the change list of updating the packages.
    options: Options to be passed into the tryjob command.
    builder: The builder to be passed into the tryjob command.

  Returns:
    The 'tryjob' command with the change list of updating the packages and
    any extra information that was passed into the command line.
  """

  tryjob_cmd = ['cros', 'tryjob', '--yes', '--json', '-g', '%d' % change_list]

  if extra_change_lists:
    for extra_cl in extra_change_lists:
      tryjob_cmd.extend(['-g', '%d' % extra_cl])

  if options:
    tryjob_cmd.extend('--%s' % option for option in options)

  tryjob_cmd.append(builder)

  return tryjob_cmd


def RunTryJobs(cl_number, extra_change_lists, options, builders, chroot_path):
  """Runs a tryjob/tryjobs.

  Args:
    cl_number: The CL created by updating the packages.
    extra_change_lists: Any extra change lists that would run alongside the CL
    that was created by updating the packages ('cl_number').
    options: Any options to be passed into the 'tryjob' command.
    builders: All the builders to run the 'tryjob' with.
    chroot_path: The absolute path to the chroot.

  Returns:
    A list that contains stdout contents of each tryjob, where stdout is
    information (a hashmap) about the tryjob. The hashmap also contains stderr
    if there was an error when running a tryjob.

  Raises:
    ValueError: Failed to submit a tryjob.
  """

  # Contains the results of each builder.
  tests = []

  # Run tryjobs with the change list number obtained from updating the
  # packages and append additional changes lists and options obtained from the
  # command line.
  for builder in builders:
    cmd = GetTryJobCommand(cl_number, extra_change_lists, options, builder)

    out = subprocess.check_output(cmd, cwd=chroot_path, encoding='utf-8')

    test_output = json.loads(out)

    buildbucket_id = int(test_output[0]['id'])

    tests.append({
        'launch_time': str(GetCurrentTimeInUTC()),
        'link': 'http://ci.chromium.org/b/%s' % buildbucket_id,
        'buildbucket_id': buildbucket_id,
        'extra_cls': extra_change_lists,
        'options': options,
        'builder': [builder]
    })

  AddLinksToCL(tests, cl_number, chroot_path)

  return tests


def StartRecipeBuilders(cl_number, extra_change_lists, options, builders,
                        chroot_path):
  """Launch recipe builders.

  Args:
    cl_number: The CL created by updating the packages.
    extra_change_lists: Any extra change lists that would run alongside the CL
    that was created by updating the packages ('cl_number').
    options: Any options to be passed into the 'tryjob' command.
    builders: All the builders to run the 'tryjob' with.
    chroot_path: The absolute path to the chroot.

  Returns:
    A list that contains stdout contents of each builder, where stdout is
    information (a hashmap) about the tryjob. The hashmap also contains stderr
    if there was an error when running a tryjob.

  Raises:
    ValueError: Failed to start a builder.
  """

  # Contains the results of each builder.
  tests = []

  # Launch a builders with the change list number obtained from updating the
  # packages and append additional changes lists and options obtained from the
  # command line.
  for builder in builders:
    cmd = ['bb', 'add', '-json']

    if cl_number:
      cmd.extend(['-cl', 'crrev.com/c/%d' % cl_number])

    if extra_change_lists:
      for cl in extra_change_lists:
        cmd.extend(['-cl', 'crrev.com/c/%d' % cl])

    if options:
      cmd.extend(options)

    cmd.append(builder)

    out = subprocess.check_output(cmd, cwd=chroot_path, encoding='utf-8')

    test_output = json.loads(out)

    tests.append({
        'launch_time': test_output['createTime'],
        'link': 'http://ci.chromium.org/b/%s' % test_output['id'],
        'buildbucket_id': test_output['id'],
        'extra_cls': extra_change_lists,
        'options': options,
        'builder': [builder]
    })

  AddLinksToCL(tests, cl_number, chroot_path)

  return tests


# Testing with CQ
def GetCQDependString(dependent_cls):
  """Get CQ dependency string e.g. `Cq-Depend: chromium:MM, chromium:NN`."""

  if not dependent_cls:
    return None

  # Cq-Depend must start a new paragraph prefixed with "Cq-Depend".
  return '\nCq-Depend: ' + ', '.join(
      ('chromium:%s' % i) for i in dependent_cls)


def GetCQIncludeTrybotsString(trybot):
  """Get Cq-Include-Trybots string, for more llvm testings"""

  if not trybot:
    return None

  if trybot not in VALID_CQ_TRYBOTS:
    raise ValueError('%s is not a valid llvm trybot' % trybot)

  # Cq-Include-Trybots must start a new paragraph prefixed
  # with "Cq-Include-Trybots".
  return '\nCq-Include-Trybots:chromeos/cq:cq-%s-orchestrator' % trybot


def StartCQDryRun(cl, dependent_cls, chroot_path):
  """Start CQ dry run for the changelist and dependencies."""

  gerrit_abs_path = os.path.join(chroot_path, 'chromite/bin/gerrit')

  cl_list = [cl]
  cl_list.extend(dependent_cls)

  for changes in cl_list:
    cq_dry_run_cmd = [gerrit_abs_path, 'label-cq', str(changes), '1']

    subprocess.check_output(cq_dry_run_cmd)


def main():
  """Updates the packages' LLVM hash and run tests.

  Raises:
    AssertionError: The script was run inside the chroot.
  """

  chroot.VerifyOutsideChroot()

  args_output = GetCommandLineArgs()

  patch_metadata_file = 'PATCHES.json'

  svn_option = args_output.llvm_version

  git_hash, svn_version = get_llvm_hash.GetLLVMHashAndVersionFromSVNOption(
      svn_option)

  # There is no need to run tryjobs when all the key parameters remain unchanged
  # from last time.

  # If --last_tested is specified, check if the current run has the same
  # arguments last time --last_tested is used.
  if args_output.last_tested:
    chroot_file_paths = chroot.GetChrootEbuildPaths(
        args_output.chroot_path, update_chromeos_llvm_hash.DEFAULT_PACKAGES)
    arg_dict = {
        'svn_version': svn_version,
        'ebuilds': chroot_file_paths,
        'extra_cls': args_output.extra_change_lists,
    }
    if args_output.subparser_name in ('tryjobs', 'recipe'):
      arg_dict['builders'] = args_output.builders
      arg_dict['tryjob_options'] = args_output.options
    if UnchangedSinceLastRun(args_output.last_tested, arg_dict):
      print('svn version (%d) matches the last tested svn version in %s' %
            (svn_version, args_output.last_tested))
      return

  llvm_variant = update_chromeos_llvm_hash.LLVMVariant.current
  if args_output.is_llvm_next:
    llvm_variant = update_chromeos_llvm_hash.LLVMVariant.next
  update_chromeos_llvm_hash.verbose = args_output.verbose
  extra_commit_msg = None
  if args_output.subparser_name == 'cq':
    cq_depend_msg = GetCQDependString(args_output.extra_change_lists)
    if cq_depend_msg:
      extra_commit_msg = cq_depend_msg
    cq_trybot_msg = GetCQIncludeTrybotsString(args_output.cq_trybot)
    if cq_trybot_msg:
      extra_commit_msg += cq_trybot_msg

  change_list = update_chromeos_llvm_hash.UpdatePackages(
      update_chromeos_llvm_hash.DEFAULT_PACKAGES,
      llvm_variant,
      git_hash,
      svn_version,
      args_output.chroot_path,
      patch_metadata_file,
      failure_modes.FailureModes.DISABLE_PATCHES,
      svn_option,
      extra_commit_msg=extra_commit_msg)

  AddReviewers(change_list.cl_number, args_output.reviewers,
               args_output.chroot_path)

  print('Successfully updated packages to %d' % svn_version)
  print('Gerrit URL: %s' % change_list.url)
  print('Change list number: %d' % change_list.cl_number)

  if args_output.subparser_name == 'tryjobs':
    tests = RunTryJobs(change_list.cl_number, args_output.extra_change_lists,
                       args_output.options, args_output.builders,
                       args_output.chroot_path)
    print('Tests:')
    for test in tests:
      print(test)
  elif args_output.subparser_name == 'recipe':
    tests = StartRecipeBuilders(change_list.cl_number,
                                args_output.extra_change_lists,
                                args_output.options, args_output.builders,
                                args_output.chroot_path)
    print('Tests:')
    for test in tests:
      print(test)

  else:
    StartCQDryRun(change_list.cl_number, args_output.extra_change_lists,
                  args_output.chroot_path)

  # If --last_tested is specified, record the arguments used
  if args_output.last_tested:
    with open(args_output.last_tested, 'w') as f:
      json.dump(arg_dict, f, indent=2)


if __name__ == '__main__':
  main()
