#!/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_JDK11_LEGACY_BOT = 'lib_desugar-archive-jdk11-legacy'
DESUGAR_JDK8_BOT = 'lib_desugar-archive-jdk8'
SMALI_BOT = 'smali'


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',
                      metavar=('<url>'),
                      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, '
                      'or the CL and patch number, e.g., 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-jdk11-legacy',
        help='Run the jdk11 legacy 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('--smali',
                      metavar=('<version>'),
                      help='Build smali version <version>.')
    result.add_option('--builder', help='Trigger specific builder')
    (options, args) = result.parse_args()
    if not options.cl.startswith('http'):
        [cl_number, patch_number] = [int(x) for x in options.cl.split('/')]
        options.cl = 'https://r8-review.googlesource.com/c/r8/+/%s/%s' % (
            cl_number, patch_number)
    return (options, 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 jdk11 legacy builder:\n  ' + DESUGAR_JDK11_LEGACY_BOT)
    print('Desugar jdk8 builder:\n  ' + DESUGAR_JDK8_BOT)
    print('Smali builder:\n  ' + SMALI_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_smali_builder(version):
    utils.check_basic_semver_version(
        version,
        'use semantic version of the smali version to built (pre-releases are not supported)',
        allowPrerelease=False)
    print(
        "Check that tag %s is created and pushed to the remote (e.g by running"
        % version)
    print()
    print("  git ls-remote origin refs/tags/%s in a smali checkout)" % version)
    print()
    print("in a smali checkout)")
    print()
    answer = input("Is tag %s present? [y/N]:" % version)
    if answer != 'y':
        print('Aborting smali release build')
        sys.exit(1)
    cmd = [
        'bb', 'add',
        'r8/ci/%s' % SMALI_BOT, '-p',
        'test_options=["--version", "%s"]' % version
    ]
    subprocess.check_call(cmd)


def trigger_cl(builders, cl_url):
    # Fixup internal urls to make bb happy.
    fixed_url = cl_url.replace('r8-review.git.corp.google.com',
                               'r8-review.googlesource.com')
    for builder in builders:
        cmd = ['bb', 'add', 'r8/ci/%s' % builder, '-cl', fixed_url]
        subprocess.check_call(cmd)


def Main():
    (options, args) = ParseOptions()
    desugar = options.desugar_jdk11 or options.desugar_jdk11_legacy or options.desugar_jdk8
    requires_commit = not options.cl and not desugar and not options.smali
    if len(args) != 1 and requires_commit:
        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

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

    if options.smali:
        if not options.release:
            print('Only release versions of smali can be built')
            return 1

        trigger_smali_builder(options.smali)
        return

    commit = None if not requires_commit 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_jdk11 or options.desugar_jdk11_legacy or options.desugar_jdk8
        if options.desugar_jdk11:
            builders = [DESUGAR_JDK11_BOT]
        elif options.desugar_jdk11_legacy:
            builders = [DESUGAR_JDK11_LEGACY_BOT]
        else:
            builders = [DESUGAR_JDK8_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())
