#!/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
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', 'master:%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()
