#!/usr/bin/env python

# Copyright 2017 Google Inc.
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


"""Submit one or more try jobs."""


import argparse
import json
import os
import re
import subprocess
import sys
import tempfile


BUCKET_SKIA_PRIMARY = 'skia.primary'
BUCKET_SKIA_INTERNAL = 'skia.internal'
CHECKOUT_ROOT = os.path.realpath(os.path.join(
    os.path.dirname(os.path.abspath(__file__)), os.pardir))
INFRA_BOTS = os.path.join(CHECKOUT_ROOT, 'infra', 'bots')
JOBS_JSON = os.path.join(INFRA_BOTS, 'jobs.json')
REPO_INTERNAL = 'https://skia.googlesource.com/internal_test.git'
TMP_DIR = os.path.join(tempfile.gettempdir(), 'sktry')

sys.path.insert(0, INFRA_BOTS)

import update_meta_config
import utils


def get_jobs(repo):
  """Obtain the list of jobs from the given repo."""
  # Maintain a copy of the repo in the temp dir.
  if not os.path.isdir(TMP_DIR):
    os.mkdir(TMP_DIR)
  with utils.chdir(TMP_DIR):
    dirname = repo.split('/')[-1]
    if not os.path.isdir(dirname):
      subprocess.check_call([
          utils.GIT, 'clone', '--mirror', repo, dirname])
    with utils.chdir(dirname):
      subprocess.check_call([utils.GIT, 'remote', 'update'])
      jobs = json.loads(subprocess.check_output([
          utils.GIT, 'show', 'master:infra/bots/jobs.json']))
      return (BUCKET_SKIA_INTERNAL, jobs)


def main():
  # Parse arguments.
  d = 'Helper script for triggering try jobs defined in %s.' % JOBS_JSON
  parser = argparse.ArgumentParser(description=d)
  parser.add_argument('--list', action='store_true', default=False,
                      help='Just list the jobs; do not trigger anything.')
  parser.add_argument('--internal', action='store_true', default=False,
                      help=('If set, include internal jobs. You must have '
                            'permission to view internal repos.'))
  parser.add_argument('job', nargs='?', default=None,
                      help='Job name or regular expression to match job names.')
  args = parser.parse_args()

  # Load and filter the list of jobs.
  jobs = []
  with open(JOBS_JSON) as f:
    jobs.append((BUCKET_SKIA_PRIMARY, json.load(f)))
  if args.internal:
    jobs.append(get_jobs(REPO_INTERNAL))
  jobs.extend(update_meta_config.CQ_INCLUDE_CHROMIUM_TRYBOTS)
  if args.job:
    filtered_jobs = []
    for bucket, job_list in jobs:
      filtered = [j for j in job_list if re.search(args.job, j)]
      if len(filtered) > 0:
        filtered_jobs.append((bucket, filtered))
    jobs = filtered_jobs

  # Display the list of jobs.
  if len(jobs) == 0:
    print 'Found no jobs matching "%s"' % repr(args.job)
    sys.exit(1)
  count = 0
  for bucket, job_list in jobs:
    count += len(job_list)
  print 'Found %d jobs:' % count
  for bucket, job_list in jobs:
    print '  %s:' % bucket
    for j in job_list:
      print '    %s' % j
  if args.list:
    return

  # Prompt before triggering jobs.
  resp = raw_input('\nDo you want to trigger these jobs? (y/n or i for '
                   'interactive): ')
  print ''
  if resp != 'y' and resp != 'i':
    sys.exit(1)
  if resp == 'i':
    filtered_jobs = []
    for bucket, job_list in jobs:
      new_job_list = []
      for j in job_list:
        incl = raw_input(('Trigger %s? (y/n): ' % j))
        if incl == 'y':
          new_job_list.append(j)
      if len(new_job_list) > 0:
        filtered_jobs.append((bucket, new_job_list))
    jobs = filtered_jobs

  # Trigger the try jobs.
  for bucket, job_list in jobs:
    cmd = ['git', 'cl', 'try', '-B', bucket]
    for j in job_list:
      cmd.extend(['-b', j])
    try:
      subprocess.check_call(cmd)
    except subprocess.CalledProcessError:
      # Output from the command will fall through, so just exit here rather than
      # printing a stack trace.
      sys.exit(1)


if __name__ == '__main__':
  main()
