#!/usr/bin/env python3
# Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

# Convenience script for triggering bots on specific commits.

import json
import git_utils
import optparse
import os
import re
import subprocess
import sys
import urllib
from urllib.request import urlopen
import utils

LUCI_SCHEDULE = os.path.join(utils.REPO_ROOT, 'infra', 'config', 'global',
                             'generated', 'luci-scheduler.cfg')
# Trigger lines have the format:
#   triggers: "BUILDER_NAME"
TRIGGERS_RE = r'^  triggers: "(\w.*)"'

DESUGAR_JDK11_BOT = 'lib_desugar-archive-jdk11'
DESUGAR_JDK8_BOT = 'lib_desugar-archive-jdk8'

def ParseOptions():
  result = optparse.OptionParser()
  result.add_option('--release',
                    help='Run on the release branch builders.',
                    default=False, action='store_true')
  result.add_option('--cl',
                    help='Run the specified cl on the bots. This should be '
                    'the full url, e.g., '
                    'https://r8-review.googlesource.com/c/r8/+/37420/1')
  result.add_option('--desugar-jdk11',
                    help='Run the jdk11 library desugar and archiving bot.',
                    default=False, action='store_true')
  result.add_option('--desugar-jdk8',
                    help='Run the jdk8 library desugar and archiving bot.',
                    default=False, action='store_true')

  result.add_option('--builder', help='Trigger specific builder')
  return result.parse_args()

def get_builders():

  is_release = False
  main_builders = []
  release_builders = []
  with open(LUCI_SCHEDULE, 'r') as fp:
    lines = fp.readlines()
    for line in lines:
      if 'branch-gitiles' in line:
        is_release = True
      if 'main-gitiles-trigger' in line:
        is_release = False
      match = re.match(TRIGGERS_RE, line)
      if match:
        builder = match.group(1)
        if is_release:
          assert 'release' in builder, builder
          release_builders.append(builder)
        else:
          assert 'release' not in builder, builder
          main_builders.append(builder)
  print('Desugar jdk11 builder:\n  ' + DESUGAR_JDK11_BOT)
  print('Desugar jdk8 builder:\n  ' + DESUGAR_JDK8_BOT)
  print('Main builders:\n  ' + '\n  '.join(main_builders))
  print('Release builders:\n  ' + '\n  '.join(release_builders))
  return (main_builders, release_builders)

def sanity_check_url(url):
  a = urlopen(url)
  if a.getcode() != 200:
    raise Exception('Url: %s \n returned %s' % (url, a.getcode()))

def trigger_builders(builders, commit):
  commit_url = 'https://r8.googlesource.com/r8/+/%s' % commit
  sanity_check_url(commit_url)
  for builder in builders:
    cmd = ['bb', 'add', 'r8/ci/%s' % builder , '-commit', commit_url]
    subprocess.check_call(cmd)

def trigger_cl(builders, cl_url):
  for builder in builders:
    cmd = ['bb', 'add', 'r8/ci/%s' % builder , '-cl', cl_url]
    subprocess.check_call(cmd)

def Main():
  (options, args) = ParseOptions()
  desugar = options.desugar_jdk11 or options.desugar_jdk8
  if len(args) != 1 and not options.cl and not desugar:
    print('Takes exactly one argument, the commit to run')
    return 1

  if options.cl and options.release:
    print('You can\'t run cls on the release bots')
    return 1

  if options.cl and desugar:
    print('You can\'t run cls on the desugar bot')
    return 1

  commit = None if (options.cl or desugar)  else args[0]
  (main_builders, release_builders) = get_builders()
  builders = release_builders if options.release else main_builders
  if options.builder:
    builder = options.builder
    assert builder in main_builders or builder in release_builders
    builders = [options.builder]
  if desugar:
    assert options.desugar_jdk8 or options.desugar_jdk11
    builders = [DESUGAR_JDK8_BOT if options.desugar_jdk8 else DESUGAR_JDK11_BOT]
    commit = git_utils.GetHeadRevision(utils.REPO_ROOT, use_main=True)
  if options.cl:
    trigger_cl(builders, options.cl)
  else:
    assert commit
    trigger_builders(builders, commit)

if __name__ == '__main__':
  sys.exit(Main())
