#!/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.

import argparse
import datetime
import os.path
import re
import shutil
import stat
import subprocess
import sys
import urllib.request
import xml.etree.ElementTree
import zipfile

import git_utils
import utils

R8_DEV_BRANCH = '9.4'
R8_VERSION_FILE = os.path.join('src', 'main', 'java', 'com', 'android', 'tools',
                               'r8', 'Version.java')
THIS_FILE_RELATIVE = os.path.join('tools', 'r8_release.py')
GMAVEN_PUBLISHER = '/google/bin/releases/android-devtools/gmaven/publisher/gmaven-publisher'

DESUGAR_JDK_LIBS = 'desugar_jdk_libs'
DESUGAR_JDK_LIBS_CONFIGURATION = DESUGAR_JDK_LIBS + '_configuration'
ANDROID_TOOLS_PACKAGE = 'com.android.tools'

GITHUB_DESUGAR_JDK_LIBS = 'https://github.com/google/desugar_jdk_libs'


def install_gerrit_change_id_hook(checkout_dir):
    with utils.ChangedWorkingDirectory(checkout_dir):
        # Fancy way of getting the string ".git".
        git_dir = subprocess.check_output(['git', 'rev-parse', '--git-dir'
                                          ]).decode('utf-8').strip()
        commit_msg_hooks = '%s/hooks/commit-msg' % git_dir
        if not os.path.exists(os.path.dirname(commit_msg_hooks)):
            os.mkdir(os.path.dirname(commit_msg_hooks))
        # Install commit hook to generate Gerrit 'Change-Id:'.
        urllib.request.urlretrieve(
            'https://gerrit-review.googlesource.com/tools/hooks/commit-msg',
            commit_msg_hooks)
        st = os.stat(commit_msg_hooks)
        os.chmod(commit_msg_hooks,
                 st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)


def checkout_r8(temp, branch):
    subprocess.check_call(['git', 'clone', utils.REPO_SOURCE, temp])
    with utils.ChangedWorkingDirectory(temp):
        subprocess.check_call([
            'git', 'new-branch', '--upstream',
            'origin/%s' % branch, 'dev-release'
        ])
    install_gerrit_change_id_hook(temp)
    return temp


def prepare_release(args):
    if args.version:
        print("Cannot manually specify version when making a dev release.")
        sys.exit(1)

    def make_release(args):
        commithash = args.dev_release

        with utils.TempDir() as temp:
            with utils.ChangedWorkingDirectory(checkout_r8(temp,
                                                           R8_DEV_BRANCH)):
                # Compute the current and new version on the branch.
                result = None
                for line in open(R8_VERSION_FILE, 'r'):
                    result = re.match(
                        r'.*LABEL = "%s\.(\d+)\-dev";' % R8_DEV_BRANCH, line)
                    if result:
                        break
                if not result or not result.group(1):
                    print(r'Failed to find version label matching %s(\d+)-dev'\
                          % R8_DEV_BRANCH)
                    sys.exit(1)
                try:
                    patch_version = int(result.group(1))
                except ValueError:
                    print('Failed to convert version to integer: %s' %
                          result.group(1))

                old_version = '%s.%s-dev' % (R8_DEV_BRANCH, patch_version)
                version = '%s.%s-dev' % (R8_DEV_BRANCH, patch_version + 1)

                # Verify that the merge point from main is not empty.
                merge_diff_output = subprocess.check_output(
                    ['git', 'diff', 'HEAD..%s' % commithash]).decode('utf-8')
                other_diff = version_change_diff(merge_diff_output, old_version,
                                                 "main")
                if not other_diff:
                    print('Merge point from main (%s)' % commithash, \
                      'is the same as exiting release (%s).' % old_version)
                    sys.exit(1)

                if args.dev_pre_cherry_pick:
                    for pre_commit in args.dev_pre_cherry_pick:
                        subprocess.check_call(
                            ['git', 'cherry-pick', '--no-edit', pre_commit])

                # Merge the desired commit from main on to the branch.
                subprocess.check_call(
                    ['git', 'merge', '--no-ff', '--no-edit', commithash])

                # Rewrite the version, commit and validate.
                sed(old_version, version, R8_VERSION_FILE)

                subprocess.check_call(
                    ['git', 'commit', '-a', '-m',
                     'Version %s' % version])

                version_diff_output = subprocess.check_output(
                    ['git', 'diff', '%s..HEAD' % commithash]).decode('utf-8')

                validate_version_change_diff(version_diff_output, "main",
                                             version)

                cmd = ['git', 'cl', 'upload', '--no-squash', '--bypass-hooks']
                git_utils.GitClAppendReviewers(cmd, args.reviewer,
                                               args.send_mail)

                maybe_check_call(args, cmd)

                if args.dry_run:
                    input(
                        'DryRun: check %s for content of version %s [enter to continue]:'
                        % (temp, version))

                return "%s dev version %s from hash %s for review" % (
                    'DryRun: omitted upload of' if args.dry_run else 'Uploaded',
                    version, commithash)

    return make_release


def maybe_tag(args, version):
    maybe_check_call(args,
                     ['git', 'tag', '-a', version, '-m',
                      '"%s"' % version])
    maybe_check_call(args, ['git', 'push', 'origin', 'refs/tags/%s' % version])


def version_change_diff(diff, old_version, new_version):
    invalid_line = None
    for line in str(diff).splitlines():
        if line.startswith('-  ') and \
            line != '-  public static final String LABEL = "%s";' % old_version:
            invalid_line = line
        elif line.startswith('+  ') and \
            line != '+  public static final String LABEL = "%s";' % new_version:
            invalid_line = line
    return invalid_line


def validate_version_change_diff(version_diff_output, old_version, new_version):
    invalid = version_change_diff(version_diff_output, old_version, new_version)
    if invalid:
        print("Unexpected diff:")
        print("=" * 80)
        print(version_diff_output)
        print("=" * 80)
        accept_string = 'THE DIFF IS OK!'
        answer = input("Accept the additonal diff as part of the release? "
                       "Type '%s' to accept: " % accept_string)
        if answer != accept_string:
            print("You did not type '%s'" % accept_string)
            print('Aborting dev release for %s' % version)
            sys.exit(1)


def maybe_check_call(args, cmd):
    if args.dry_run:
        print('DryRun:', ' '.join(cmd))
    else:
        print(' '.join(cmd))
        return subprocess.check_call(cmd)


def update_prebuilds(r8_checkout, version, checkout, keepanno=False):
    path = os.path.join(r8_checkout, 'tools', 'update_prebuilds_in_android.py')
    commit_arg = '--commit_hash=' if len(version) == 40 else '--version='
    cmd = [path, '--targets=lib', '--maps', commit_arg + version, checkout]
    if keepanno:
        cmd.append("--keepanno")
    subprocess.check_call(cmd)


def prepare_maven(args):
    assert args.version

    def release_maven(options):
        gfiles = []
        for version in args.version:
            gfiles.append('/bigstore/r8-releases/raw/%s/r8lib.zip' % version)

        release_id = gmaven_publisher_stage(options, gfiles)

        print("Staged Release ID " + release_id + ".\n")
        gmaven_publisher_stage_redir_test_info(
            release_id, "com.android.tools:r8:%s" % args.version[0],
            "r8lib.jar")

        print
        answer = input("Continue with publishing [y/N]:")

        if answer != 'y':
            print('Aborting release to Google maven')
            sys.exit(1)

        gmaven_publisher_publish(args, release_id)

        print("")
        print("Published. Use the email workflow for approval.")

    return release_maven


def bug_fmt(bug):
    return "b/%s" % bug


def g4_cp(old, new, file):
    subprocess.check_call('g4 cp {%s,%s}/%s' % (old, new, file), shell=True)


def g4_open(file):
    if not os.access(file, os.W_OK):
        subprocess.check_call('g4 open %s' % file, shell=True)


def g4_change(version, commit_info):
    message = f'Update R8 to {version}'
    if version == 'main':
        message = f'DO NOT SUBMIT: {message}'
    if commit_info:
        message += f'\n\n{commit_info}'
    message = message.replace("'", r"\'")
    return subprocess.check_output(f"g4 change --desc $'{message}\n'",
                                   shell=True).decode('utf-8')


def get_cl_id(c4_change_output):
    startIndex = c4_change_output.find('Change ') + len('Change ')
    endIndex = c4_change_output.find(' ', startIndex)
    cl = c4_change_output[startIndex:endIndex]
    assert cl.isdigit()
    return cl


def sed(pattern, replace, path):
    with open(path, "r") as sources:
        lines = sources.readlines()
    with open(path, "w") as sources:
        for line in lines:
            sources.write(re.sub(pattern, replace, line))


def download_file(version, file, dst):
    if version == 'main':
        src = os.path.join(utils.LIBS, file)
        if os.path.exists(src):
            shutil.copyfile(src, dst)
        else:
            print(f"WARNING: no file found for {src}. Skipping.")
        return
    dir = 'raw' if len(version) != 40 else 'raw/main'
    urllib.request.urlretrieve(
        ('https://storage.googleapis.com/r8-releases/%s/%s/%s' %
         (dir, version, file)), dst)


def download_gfile(gfile, dst):
    if not gfile.startswith('/bigstore/r8-releases'):
        print('Unexpected gfile prefix for %s' % gfile)
        sys.exit(1)

    urllib.request.urlretrieve(
        'https://storage.googleapis.com/%s' % gfile[len('/bigstore/'):], dst)


def blaze_run(target):
    return subprocess.check_output('blaze run %s' % target,
                                   shell=True,
                                   stderr=subprocess.STDOUT).decode('utf-8')


def find_r8_version_hash(branch, version):
    if not branch.startswith('origin/'):
        print('Expected branch to start with origin/')
        return 1
    output = subprocess.check_output([
        'git', 'log', '--pretty=format:%H\t%s', '--grep',
        r'^Version [[:digit:]]\+.[[:digit:]]\+.[[:digit:]]\+\(\|-dev\)$', branch
    ]).decode('utf-8')
    for l in output.split('\n'):
        (hash, subject) = l.split('\t')
        m = re.search('Version (.+)', subject)
        if not m:
            print('Unable to find a version for line: %s' % l)
            continue
        if (m.group(1) == version):
            return hash
    print(f'ERROR: Did not find commit for {version} on branch {branch}')


def find_2nd(string, substring):
    return string.find(substring, string.find(substring) + 1)


def branch_from_version(version):
    return version[0:find_2nd(version, '.')]


def prepare_google3(args):
    assert len(args.version) == 1

    # Check if an existing client exists.
    if not args.use_existing_work_branch:
        check_no_google3_client(args, args.p4_client)

    def release_google3(options):
        assert len(options.version) == 1
        version = options.version[0]
        print("Releasing for Google 3")
        if options.dry_run:
            return 'DryRun: omitting g3 release for %s' % version

        google3_base = subprocess.check_output(
            ['p4', 'g4d', '-f', args.p4_client]).decode('utf-8').rstrip()
        third_party_r8 = os.path.join(google3_base, 'third_party', 'java', 'r8')
        today = datetime.date.today()
        commit_info = 'No info on changes merged.'
        with utils.ChangedWorkingDirectory(third_party_r8):
            # download files
            g4_open('full.jar')
            g4_open('src.jar')
            g4_open('lib.jar')
            g4_open('lib.jar.map')
            g4_open('desugar_jdk_libs_configuration.jar')
            g4_open('threading-module-blocking.jar')
            g4_open('threading-module-single-threaded.jar')
            g4_open('proto/keepradius.proto')
            g4_open('proto/keepradiussummary.proto')
            g4_open('proto/libraryanalyzerresult.proto')
            download_file(version, 'r8-full-exclude-deps.jar', 'full.jar')
            download_file(version, 'r8-src.jar', 'src.jar')
            download_file(version, 'r8lib-exclude-deps.jar', 'lib.jar')
            download_file(version, 'r8lib-exclude-deps.jar.map', 'lib.jar.map')
            download_file(version, 'desugar_jdk_libs_configuration.jar',
                          'desugar_jdk_libs_configuration.jar')
            download_file(version, 'threading-module-blocking.jar',
                          'threading-module-blocking.jar')
            download_file(version, 'threading-module-single-threaded.jar',
                          'threading-module-single-threaded.jar')
            download_file(version, 'keepradius.proto', 'proto/keepradius.proto')
            download_file(version, 'keepradiussummary.proto',
                          'proto/keepradiussummary.proto')
            download_file(version, 'libraryanalyzerresult.proto',
                          'proto/libraryanalyzerresult.proto')
            if version != 'main':
                g4_open('METADATA')
                metadata_path = os.path.join(third_party_r8, 'METADATA')
                match_count = 0
                match_count_expected = 10
                match_value = None
                version_match_regexp = r'([1-9]\.[0-9]{1,2}\.[0-9]{1,3}-dev)'
                for line in open(metadata_path, 'r'):
                    result = re.search(version_match_regexp, line)
                    if result:
                        match_count = match_count + 1
                        if not match_value:
                            match_value = result.group(1)
                        else:
                            if match_value != result.group(1):
                                print(f"""ERROR:
                                Multiple -dev release strings ({match_value} and
                                {result.group(0)}) found in METADATA. Please update
                                {metadata_path} manually and run again with options
                                --google3 --use-existing-work-branch.
                                """)
                                sys.exit(1)
                if match_count != match_count_expected:
                    print(f"""ERROR:
                    Could not find the previous -dev release string to replace in METADATA.
                    Expected to find it mentioned {match_count_expected} times, but found
                    {match_count} occurrences. Please update {metadata_path} manually and
                    run again with options --google3 --use-existing-work-branch.
                    """)
                    sys.exit(1)
                sed(version_match_regexp, version, metadata_path)
                sed(
                    r'\{ year.*\}',
                    f'{{ year: {today.year} month: {today.month} day: {today.day} }}',
                    metadata_path)
            subprocess.check_output('chmod u+w *', shell=True)
            previous_version = match_value
            if not version.endswith('-dev') or not previous_version.endswith(
                    '-dev'):
                print(
                    f'ERROR: At least one of {version} (new version) ' +
                    f'and {previous_version} (previous version) is not a -dev version. '
                    + 'Expected both to be.')
                sys.exit(1)
            print(f'Previous version was: {previous_version}')
            with utils.TempDir() as temp:
                subprocess.check_call(['git', 'clone', utils.REPO_SOURCE, temp])
                with utils.ChangedWorkingDirectory(temp):
                    current_version_hash = find_r8_version_hash(
                        'origin/' + branch_from_version(previous_version),
                        previous_version)
                    new_version_hash = find_r8_version_hash(
                        'origin/' + branch_from_version(version), version)
                    if not current_version_hash or not new_version_hash:
                        print(
                            'ERROR: Failed to generate merged commits log, missing version'
                        )
                        sys.exit(1)
                    commits_merged = subprocess.check_output([
                        'git', 'log', '--oneline',
                        f"{current_version_hash}..{new_version_hash}"
                    ]).decode('utf-8')
                    if len(commits_merged) == 0:
                        print(
                            'ERROR: Failed to generate merged commits log, commit log is empty'
                        )
                        sys.exit(1)
                    commit_info = (
                        f'Commits merged (since {previous_version}):\n' +
                        f'{commits_merged}\n' +
                        f'See https://r8.googlesource.com/r8/+log/{new_version_hash}'
                    )

        with utils.ChangedWorkingDirectory(google3_base):
            blaze_result = blaze_run('//third_party/java/r8:d8 -- --version')

            assert version in blaze_result

            if not options.no_upload:
                change_result = g4_change(version, commit_info)
                change_result += 'Run \'(g4d ' + args.p4_client \
                                 + ' && tap_presubmit -p all --train -c ' \
                                 + get_cl_id(change_result) + ')\' for running TAP global' \
                                 + ' presubmit using the train.\n' \
                                 + 'Run \'(g4d ' + args.p4_client \
                                 + ' && tap_presubmit -p all --notrain --detach --email' \
                                 + ' --skip_flaky_targets --skip_already_failing -c ' \
                                 + get_cl_id(change_result) + ')\' for running an isolated' \
                                 + ' TAP global presubmit.'
                return change_result

    return release_google3


def update_desugar_library_in_studio(args):
    assert os.path.exists(args.studio), ("Could not find STUDIO path %s" %
                                         args.studio)

    def make_release(args):
        library_version = args.update_desugar_library_in_studio[0]
        configuration_version = args.update_desugar_library_in_studio[1]
        change_name = 'update-desugar-library-dependencies'

        with utils.ChangedWorkingDirectory(args.studio):
            if not args.use_existing_work_branch:
                subprocess.call(['repo', 'abandon', change_name])
            if not args.no_sync:
                subprocess.check_call(['repo', 'sync', '-cq', '-j', '16'])

            cmd = [
                'tools/base/bazel/bazel', 'run',
                '//tools/base/bazel:add_dependency', '--',
                '--repo=https://maven.google.com com.android.tools:desugar_jdk_libs:%s'
                % library_version
            ]
            utils.PrintCmd(cmd)
            subprocess.check_call(" ".join(cmd), shell=True)
            cmd = ['tools/base/bazel/bazel', 'shutdown']
            utils.PrintCmd(cmd)
            subprocess.check_call(cmd)

        prebuilts_tools = os.path.join(args.studio, 'prebuilts', 'tools')
        with utils.ChangedWorkingDirectory(prebuilts_tools):
            if not args.use_existing_work_branch:
                with utils.ChangedWorkingDirectory(prebuilts_tools):
                    subprocess.check_call(['repo', 'start', change_name])
            m2_dir = os.path.join('common', 'm2', 'repository', 'com',
                                  'android', 'tools')
            subprocess.check_call([
                'git', 'add',
                os.path.join(m2_dir, DESUGAR_JDK_LIBS, library_version)
            ])
            subprocess.check_call([
                'git', 'add',
                os.path.join(m2_dir, DESUGAR_JDK_LIBS_CONFIGURATION,
                             configuration_version)
            ])

            git_message = ("""Update library desugaring dependencies

  com.android.tools:desugar_jdk_libs:%s
  com.android.tools:desugar_jdk_libs_configuration:%s

Bug: %s
Test: L8ToolTest, L8DexDesugarTest""" %
                           (library_version, configuration_version,
                            '\nBug: '.join(map(bug_fmt, args.bug))))

            if not args.use_existing_work_branch:
                subprocess.check_call(
                    ['git', 'commit', '-a', '-m', git_message])
            else:
                print('Not committing when --use-existing-work-branch. ' +
                      'Commit message should be:\n\n' + git_message + '\n')
            # Don't upload if requested not to, or if changes are not committed due
            # to --use-existing-work-branch
            if not args.no_upload and not args.use_existing_work_branch:
                process = subprocess.Popen(['repo', 'upload', '.', '--verify'],
                                           stdin=subprocess.PIPE)
                return process.communicate(input='y\n')[0]

    return make_release


def prepare_desugar_library(args):

    def make_release(args):
        library_version = args.desugar_library[0]
        configuration_version = args.desugar_library[1]

        # TODO(b/237636871): Cleanup and generalize.
        if (not (library_version.startswith('1.1') or
                 library_version.startswith('1.2') or
                 library_version.startswith('2.0') or
                 library_version.startswith('2.1'))):
            print(
                "Release script does not support desugared library version %s" %
                library_version)
            sys.exit(1)

        postfixes = ['']
        if library_version.startswith('1.2'):
            postfixes = ['_legacy']
        if library_version.startswith('2.0') or library_version.startswith(
                '2.1'):
            postfixes = ['_minimal', '', '_nio']

        with utils.TempDir() as temp:
            with utils.ChangedWorkingDirectory(temp):
                artifacts = []
                for postfix in postfixes:
                    group_postfix = ('' if postfix == '_legacy' else postfix)
                    archive_postfix = (postfix
                                       if library_version.startswith('1.1') else
                                       '_jdk11' + postfix)
                    library_jar = DESUGAR_JDK_LIBS + postfix + '.jar'
                    library_archive = DESUGAR_JDK_LIBS + archive_postfix + '.zip'
                    configuration_archive = DESUGAR_JDK_LIBS_CONFIGURATION + archive_postfix + '.zip'
                    library_gfile = ('/bigstore/r8-releases/raw/%s/%s/%s' %
                                     (DESUGAR_JDK_LIBS + group_postfix,
                                      library_version, library_archive))
                    configuration_gfile = (
                        '/bigstore/r8-releases/raw/main/%s/%s' %
                        (configuration_version, configuration_archive))

                    download_gfile(library_gfile, library_archive)
                    download_gfile(configuration_gfile, configuration_archive)
                    check_configuration(configuration_archive, group_postfix)
                    artifacts.append(library_gfile)
                    artifacts.append(configuration_gfile)

                release_id = gmaven_publisher_stage(args, artifacts)

                print("Staged Release ID " + release_id + ".\n")
                library_artifact_id = \
                    '%s:%s:%s' % (ANDROID_TOOLS_PACKAGE, DESUGAR_JDK_LIBS, library_version)
                gmaven_publisher_stage_redir_test_info(release_id,
                                                       library_artifact_id,
                                                       library_jar)

                print("")
                answer = input("Continue with publishing [y/N]:")

                if answer != 'y':
                    print('Aborting release to Google maven')
                    sys.exit(1)

                gmaven_publisher_publish(args, release_id)

                print("")
                print("Published. Use the email workflow for approval.")

    return make_release


def check_configuration(configuration_archive, postfix):
    zip = zipfile.ZipFile(configuration_archive)
    zip.extractall()
    dirs = os.listdir(
        os.path.join('com', 'android', 'tools',
                     DESUGAR_JDK_LIBS_CONFIGURATION + postfix))
    if len(dirs) != 1:
        print('Unexpected archive content, %s' + dirs)
        sys.exit(1)

    version = dirs[0]
    pom_file = os.path.join(
        'com', 'android', 'tools', DESUGAR_JDK_LIBS_CONFIGURATION + postfix,
        version,
        '%s-%s.pom' % (DESUGAR_JDK_LIBS_CONFIGURATION + postfix, version))
    version_from_pom = extract_version_from_pom(pom_file)
    if version != version_from_pom:
        print('Version mismatch, %s != %s' % (version, version_from_pom))
        sys.exit(1)


def check_no_google3_client(args, client_name):
    if not args.use_existing_work_branch:
        clients = subprocess.check_output('g4 myclients',
                                          shell=True).decode('utf-8')
        if ':%s:' % client_name in clients:
            if args.delete_work_branch:
                subprocess.check_call('g4 citc -d -f %s' % client_name,
                                      shell=True)
            else:
                print(("Remove the existing '%s' client before continuing " +
                       "(force delete: 'g4 citc -d -f %s'), " +
                       "or use either --use-existing-work-branch or " +
                       "--delete-work-branch.") % (client_name, client_name))
                sys.exit(1)


def extract_version_from_pom(pom_file):
    ns = "http://maven.apache.org/POM/4.0.0"
    xml.etree.ElementTree.register_namespace('', ns)
    tree = xml.etree.ElementTree.ElementTree()
    tree.parse(pom_file)
    return tree.getroot().find("{%s}version" % ns).text


GMAVEN_PUBLISH_STAGE_RELEASE_ID_PATTERN = re.compile(
    r'Release ID = ([0-9a-f\-]+)')


def gmaven_publisher_stage(args, gfiles):
    if args.dry_run:
        print('Dry-run, would have staged %s' % gfiles)
        return 'dry-run-release-id'

    print("Staging: %s" % ', '.join(gfiles))
    print("")

    cmd = [
        GMAVEN_PUBLISHER, 'stage', '--ack_deprecated', '--gfile',
        ','.join(gfiles)
    ]
    output = subprocess.check_output(cmd)

    # Expect output to contain:
    # [INFO] 06/19/2020 09:35:12 CEST: >>>>>>>>>> Staged
    # [INFO] 06/19/2020 09:35:12 CEST: Release ID = 9171d015-18f6-4a90-9984-1c362589dc1b
    # [INFO] 06/19/2020 09:35:12 CEST: Stage Path = /bigstore/studio_staging/maven2/sgjesse/9171d015-18f6-4a90-9984-1c362589dc1b

    matches = GMAVEN_PUBLISH_STAGE_RELEASE_ID_PATTERN.findall(
        output.decode("utf-8"))
    if matches == None or len(matches) > 1:
        print("Could not determine the release ID from the gmaven_publisher " +
              "output. Expected a line with 'Release ID = <release id>'.")
        print("Output was:")
        print(output)
        sys.exit(1)

    print(output)

    release_id = matches[0]
    return release_id


def gmaven_publisher_stage_redir_test_info(release_id, artifact, dst):

    redir_command = ("/google/data/ro/teams/android-devtools-infra/tools/redir "
                     + "--alsologtostderr " +
                     "--gcs_bucket_path=/bigstore/gmaven-staging/${USER}/%s " +
                     "--port=1480") % release_id

    get_command = (
        "mvn org.apache.maven.plugins:maven-dependency-plugin:2.4:get " +
        "-Dmaven.repo.local=/tmp/maven_repo_local " +
        "-DremoteRepositories=http://localhost:1480 " + "-Dartifact=%s " +
        "-Ddest=%s") % (artifact, dst)

    print("""To test the staged content with 'redir' run:

%s

Then add the following repository to settings.gradle.kts (Kotlin Script) to
search the 'redir' repository:

dependencyResolutionManagement {
  repositories {
    maven {
      url = uri("http://localhost:1480")
      isAllowInsecureProtocol = true
    }
  }
}

or the following to settings.gradle (Groovy);

dependencyResolutionManagement {
  repositories {
    maven {
      url 'http://localhost:1480'
      allowInsecureProtocol true
    }
  }
}

and add the following repository to gradle.build.kts (Kotlin Script) for the
staged version:

coreLibraryDesugaring("%s") {
  isChanging = true
}

or the following to settings.gradle (Groovy);

dependencies {
  coreLibraryDesugaring('%s') {
    changing = true
  }
}

Use this commands to get artifact from 'redir':

rm -rf /tmp/maven_repo_local
%s
""" % (redir_command, artifact, artifact, get_command))


def gmaven_publisher_publish(args, release_id):
    if args.dry_run:
        print('Dry-run, would have published %s' % release_id)
        return

    cmd = [GMAVEN_PUBLISHER, 'publish', release_id]
    output = subprocess.check_output(cmd)


def branch_change_diff(diff, old_version, new_version):
    invalid_line = None
    for line in str(diff).splitlines():
        if line.startswith('-R8') and \
            line != "-R8_DEV_BRANCH = '%s'" % old_version:
            print(line)
            invalid_line = line
        elif line.startswith('+R8') and \
            line != "+R8_DEV_BRANCH = '%s'" % new_version:
            print(line)
            invalid_line = line
    return invalid_line


def validate_branch_change_diff(version_diff_output, old_version, new_version):
    invalid = branch_change_diff(version_diff_output, old_version, new_version)
    if invalid:
        print("")
        print(
            "The diff for the branch change in tools/release.py is not as expected:"
        )
        print("")
        print("=" * 80)
        print(version_diff_output)
        print("=" * 80)
        print("")
        print("Validate the uploaded CL before landing.")
        print("")


def prepare_branch(args):
    if (len(args.new_dev_branch) < 1 or len(args.new_dev_branch) > 2):
        print("One or two arguments required for --new-dev-branch")
        sys.exit(1)
    branch_version = args.new_dev_branch[0]

    current_semver = utils.check_basic_semver_version(
        R8_DEV_BRANCH, ", current release branch version should be x.y", 2)
    semver = utils.check_basic_semver_version(
        branch_version, ", release branch version should be x.y", 2)
    if not semver.larger_than(current_semver):
        print('New branch version "' + branch_version +
              '" must be strictly larger than the current "' + R8_DEV_BRANCH +
              '"')
        sys.exit(1)

    def make_branch(options):
        with utils.TempDir() as temp:
            subprocess.check_call(['git', 'clone', utils.REPO_SOURCE, temp])
            with utils.ChangedWorkingDirectory(temp):
                if len(options.new_dev_branch) == 1:
                    # Calculate the usual branch hash.
                    subprocess.check_call(
                        ['git', 'fetch', 'origin', R8_DEV_BRANCH])
                    hashes = subprocess.check_output([
                        'git', 'show', '-s', '--pretty=%P',
                        'origin/%s~1' % R8_DEV_BRANCH
                    ]).decode('utf-8').strip()
                    if (len(hashes.split()) != 2):
                        print(
                            'Expected two parent hashes for commit origin/%s~1'
                            % R8_DEV_BRANCH)
                        sys.exit(0)
                    commithash = hashes.split()[1]
                    print()
                    print('Calculated branch hash: %s' % commithash)
                    print(
                        'Please double check that this is the correct branch hash. It'
                        ' is obtained as the second parent of origin/%s~1.' %
                        R8_DEV_BRANCH)
                    print(
                        'If not rerun the script passing an explicit hash to branch from.'
                    )
                else:
                    commithash = options.new_dev_branch[1]
                    print()
                    print('Using explicit branch hash %s' % commithash)
                print()
                print(
                    'Use the Gerrit admin UI at'
                    ' https://r8-review.googlesource.com/admin/repos/r8,branches'
                    ' to create the %s branch from %s.' %
                    (branch_version, commithash))
                answer = input("Branch created in Gerrit UI? [y/N]:")
                if answer != 'y':
                    print('Aborting preparing branch for %s' % branch_version)
                    sys.exit(1)

                # Fetch and checkout the new branch created through the Gerrit UI.
                subprocess.check_call(
                    ['git', 'fetch', 'origin', branch_version])
                subprocess.check_call(['git', 'checkout', branch_version])

                # Rewrite the version on the branch, commit and validate.
                old_version = 'main'
                full_version = branch_version + '.0-dev'
                version_prefix = 'public static final String LABEL = "'
                sed(version_prefix + old_version, version_prefix + full_version,
                    R8_VERSION_FILE)

                subprocess.check_call(
                    ['git', 'commit', '-a', '-m',
                     'Version %s' % full_version])

                version_diff_output = subprocess.check_output(
                    ['git', 'diff', '%s..HEAD' % commithash])

                validate_version_change_diff(version_diff_output, old_version,
                                             full_version)

                if options.dry_run:
                    input(
                        'DryRun: check %s for content of version %s [enter to continue]:'
                        % (temp, branch_version))

                # Double check that we want to create a new release branch.
                if not options.dry_run:
                    answer = input('Continue with branch for %s [y/N]:' %
                                   branch_version)
                    if answer != 'y':
                        print('Aborting preparing branch for %s' %
                              branch_version)
                        sys.exit(1)

                maybe_check_call(options,
                                 ['git', 'cl', 'upload', '--bypass-hooks'])

                print(
                    'Updating tools/r8_release.py to make new dev releases on %s'
                    % branch_version)

                subprocess.check_call(
                    ['git', 'new-branch', 'update-release-script'])

                # Check this file for the setting of the current dev branch.
                result = None
                for line in open(THIS_FILE_RELATIVE, 'r'):
                    result = re.match(r"^R8_DEV_BRANCH = '(\d+).(\d+)'", line)
                    if result:
                        break
                if not result or not result.group(1):
                    print('Failed to find version label in %s' %
                          THIS_FILE_RELATIVE)
                    sys.exit(1)

                # Update this file with the new dev branch.
                sed(
                    "R8_DEV_BRANCH = '%s.%s" %
                    (result.group(1), result.group(2)),
                    "R8_DEV_BRANCH = '%s.%s" %
                    (str(semver.major), str(semver.minor)), THIS_FILE_RELATIVE)

                message = \
                    'Prepare %s for branch %s' % (THIS_FILE_RELATIVE, branch_version)
                subprocess.check_call(['git', 'commit', '-a', '-m', message])

                branch_diff_output = subprocess.check_output(
                    ['git', 'diff', 'HEAD~'])

                validate_branch_change_diff(branch_diff_output, R8_DEV_BRANCH,
                                            branch_version)

                if options.dry_run:
                    input(
                        'DryRun: check %s for content of version main [enter to continue]:'
                        % temp)

                maybe_check_call(options,
                                 ['git', 'cl', 'upload', '-f', '-m', message])

                print('')
                print(
                    'Make sure to send out the two branch change CL for review'
                    ' (on %s and main).' % branch_version)
                print('')

    return make_branch


def parse_options():
    result = argparse.ArgumentParser(description='Release r8')
    group = result.add_mutually_exclusive_group()
    group.add_argument('--dev-release',
                       metavar=('<main hash>'),
                       help='The hash to use for the new dev version of R8')
    group.add_argument(
        '--version',
        metavar=('<version(s)>'),
        default=[],
        action='append',
        help=
        'The new version(s) of R8 (e.g., 1.4.51) to release to selected channels'
    )
    group.add_argument(
        '--desugar-library',
        nargs=2,
        metavar=('<version>', '<configuration hash>'),
        help='The new version of com.android.tools:desugar_jdk_libs')
    group.add_argument(
        '--update-desugar-library-in-studio',
        nargs=2,
        metavar=('<version>', '<configuration version>'),
        help='Update studio mirror of com.android.tools:desugar_jdk_libs')
    group.add_argument('--new-dev-branch',
                       nargs='+',
                       metavar=('<version>', '<branch hash>'),
                       help=('Prepare new branch for a version line (e.g. 8.0)'
                             ' Suggested branch hash is calculated '
                             ' if not explicitly specified'))
    result.add_argument('--reviewer',
                        metavar=('<reviewer(s)>'),
                        default=[],
                        action='append',
                        help='Rewiever(s) for the cherry-pick(s) '
                        '(adds @google.com if missing)')
    result.add_argument('--send-mail',
                        '--send_mail',
                        default=False,
                        action='store_true',
                        help='Send Gerrit review request right away')
    result.add_argument('--dev-pre-cherry-pick',
                        metavar=('<main hash(s)>'),
                        default=[],
                        action='append',
                        help='List of commits to cherry pick before doing full '
                        'merge, mostly used for reverting cherry picks')
    result.add_argument('--no-sync',
                        '--no_sync',
                        default=False,
                        action='store_true',
                        help='Do not sync repos before uploading')
    result.add_argument('--bug',
                        metavar=('<bug(s)>'),
                        default=[],
                        action='append',
                        help='List of bugs for release version')
    result.add_argument('--maven',
                        default=False,
                        action='store_true',
                        help='Release to Google Maven')
    result.add_argument('--google3',
                        default=False,
                        action='store_true',
                        help='Release for google 3')
    result.add_argument('--p4-client',
                        default='update-r8',
                        metavar=('<client name>'),
                        help='P4 client name for google 3')
    result.add_argument('--use-existing-work-branch',
                        '--use_existing_work_branch',
                        default=False,
                        action='store_true',
                        help='Use existing work CL in google3')
    result.add_argument('--delete-work-branch',
                        '--delete_work_branch',
                        default=False,
                        action='store_true',
                        help='Delete CL in google3')
    result.add_argument('--no-upload',
                        '--no_upload',
                        default=False,
                        action='store_true',
                        help="Don't upload for code review")
    result.add_argument(
        '--dry-run',
        default=False,
        action='store_true',
        help='Only perform non-commiting tasks and print others.')
    result.add_argument('--dry-run-output',
                        '--dry_run_output',
                        default=os.getcwd(),
                        metavar=('<path>'),
                        help='Location for dry run output.')
    args = result.parse_args()

    if args.google3:
        if len(args.version) != 1:
            print("ERROR: only one version supported for google 3")
            sys.exit(1)
        if not 'dev' in args.version[0]:
            print(
                "WARNING: You should not roll a release version into google 3")

    return args


def main():
    args = parse_options()
    targets_to_run = []

    if args.new_dev_branch:
        if args.google3 or args.maven:
            print('Cannot create a branch and roll at the same time.')
            sys.exit(1)
        targets_to_run.append(prepare_branch(args))

    if args.dev_release:
        if args.google3 or args.maven:
            print('Cannot create a dev release and roll at the same time.')
            sys.exit(1)
        targets_to_run.append(prepare_release(args))

    utils.check_gcert()

    if args.google3:
        targets_to_run.append(prepare_google3(args))
    if args.maven:
        targets_to_run.append(prepare_maven(args))

    if args.desugar_library:
        targets_to_run.append(prepare_desugar_library(args))

    if args.update_desugar_library_in_studio:
        if not args.studio:
            print("--studio required")
            sys.exit(1)
        if args.bug == []:
            print(
                "Update studio mirror of com.android.tools:desugar_jdk_libs " +
                "requires at least one bug by using '--bug'")
            sys.exit(1)
        targets_to_run.append(update_desugar_library_in_studio(args))

    final_results = []
    for target_closure in targets_to_run:
        final_results.append(target_closure(args))

    print('\n\n**************************************************************')
    print('PRINTING SUMMARY')
    print('**************************************************************\n\n')

    for result in final_results:
        if result is not None:
            print(result)


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