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