#!/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."""


from __future__ import print_function
import argparse
import json
import os
import re
import subprocess
import sys
import tempfile
import urllib2


BUCKET_SKIA_PRIMARY = 'skia/skia.primary'
BUCKET_SKIA_INTERNAL = 'skia-internal/skia.internal'
INFRA_BOTS = os.path.join('infra', 'bots')
TASKS_JSON = os.path.join(INFRA_BOTS, 'tasks.json')
REPO_INTERNAL = 'https://skia.googlesource.com/internal_test.git'
TMP_DIR = os.path.join(tempfile.gettempdir(), 'sktry')

SKIA_ROOT = os.path.realpath(os.path.join(
    os.path.dirname(os.path.abspath(__file__)), os.pardir))
SKIA_INFRA_BOTS = os.path.join(SKIA_ROOT, INFRA_BOTS)
sys.path.insert(0, SKIA_INFRA_BOTS)

import utils


def find_repo_root():
  """Find the root directory of the current repository."""
  cwd = os.getcwd()
  while True:
    if os.path.isdir(os.path.join(cwd, '.git')):
      return cwd
    next_cwd = os.path.dirname(cwd)
    if next_cwd == cwd:
      raise Exception('Failed to find repo root!')
    cwd = next_cwd


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', 'main:%s' % JOBS_JSON]))
      return (BUCKET_SKIA_INTERNAL, jobs)


def main():
  # Parse arguments.
  d = 'Helper script for triggering try jobs.'
  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()

  # First, find the Gerrit issue number. If the change was uploaded using Depot
  # Tools, this configuration will be present in the git config.
  branch = subprocess.check_output(['git', 'branch', '--show-current']).rstrip()
  if not branch:
    print('Not on any branch; cannot trigger try jobs.')
    sys.exit(1)
  branch_issue_config = 'branch.%s.gerritissue' % branch
  try:
    issue = subprocess.check_output([
        'git', 'config', '--local', branch_issue_config])
  except subprocess.CalledProcessError:
    # Not using Depot Tools. Find the Change-Id line in the most recent commit
    # and obtain the issue number using that.
    print('"git cl issue" not set; searching for Change-Id footer.')
    msg = subprocess.check_output(['git', 'log', '-n1', branch])
    m = re.search('Change-Id: (I[a-f0-9]+)', msg)
    if not m:
      print('No gerrit issue found in `git config --local %s` and no Change-Id'
            ' found in most recent commit message.')
      sys.exit(1)
    url = 'https://skia-review.googlesource.com/changes/%s' % m.groups()[0]
    resp = urllib2.urlopen(url).read()
    issue = str(json.loads('\n'.join(resp.splitlines()[1:]))['_number'])
    print('Setting "git cl issue %s"' % issue)
    subprocess.check_call(['git', 'cl', 'issue', issue])
  # Load and filter the list of jobs.
  jobs = []
  tasks_json = os.path.join(find_repo_root(), TASKS_JSON)
  with open(tasks_json) as f:
    tasks_cfg = json.load(f)
  skia_primary_jobs = []
  for k, v in tasks_cfg['jobs'].iteritems():
    skia_primary_jobs.append(k)
  skia_primary_jobs.sort()

  # TODO(borenet): This assumes that the current repo is associated with the
  # skia.primary bucket. This will work for most repos but it would be better to
  # look up the correct bucket to use.
  jobs.append((BUCKET_SKIA_PRIMARY, skia_primary_jobs))
  if args.internal:
    jobs.append(get_jobs(REPO_INTERNAL))
  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

  if count > 1:
    # 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()
