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