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

R8_DEV_BRANCH = '8.9'
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('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']
                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 release_studio_or_aosp(r8_checkout,
                           path,
                           options,
                           git_message,
                           keepanno=False):
    with utils.ChangedWorkingDirectory(path):
        if not options.use_existing_work_branch:
            subprocess.call(['repo', 'abandon', 'update-r8'])
        if not options.no_sync:
            subprocess.check_call(['repo', 'sync', '-cq', '-j', '16'])

        prebuilts_r8 = os.path.join(path, 'prebuilts', 'r8')

        if not options.use_existing_work_branch:
            with utils.ChangedWorkingDirectory(prebuilts_r8):
                subprocess.check_call(['repo', 'start', 'update-r8'])

        update_prebuilds(r8_checkout, options.version, path, keepanno)

        with utils.ChangedWorkingDirectory(prebuilts_r8):
            if not options.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 options.no_upload and not options.use_existing_work_branch:
                process = subprocess.Popen(
                    ['repo', 'upload', '.', '--verify', '--current-branch'],
                    stdin=subprocess.PIPE)
                return process.communicate(input=b'y\n')[0]


def prepare_aosp(args):
    assert args.version

    if (not args.legacy_release):
        print("Please use the new release process, see go/r8-release-prebuilts. "
            + "If for some reason the legacy release process is needed "
            + "pass --legacy-release")
        sys.exit(1)

    assert os.path.exists(args.aosp), "Could not find AOSP path %s" % args.aosp

    def release_aosp(options):
        print("Releasing for AOSP")
        if options.dry_run:
            return 'DryRun: omitting AOSP release for %s' % options.version

        git_message = ("""Update D8 and R8 to %s

Version: %s
This build IS NOT suitable for preview or public release.

Built here: go/r8-releases/raw/%s

Test: TARGET_PRODUCT=aosp_arm64 m -j core-oj""" %
                       (args.version, args.version, args.version))
        # Fixes to Android U branch is based of 8.2.2-dev where the keepanno library
        # is not built.
        keepanno = not args.version.startswith('8.2.2-udc')
        return release_studio_or_aosp(utils.REPO_ROOT,
                                      args.aosp,
                                      options,
                                      git_message,
                                      keepanno=keepanno)

    return release_aosp


def prepare_maven(args):
    assert args.version

    def release_maven(options):
        gfile = '/bigstore/r8-releases/raw/%s/r8lib.zip' % args.version
        release_id = gmaven_publisher_stage(options, [gfile])

        print("Staged Release ID " + release_id + ".\n")
        gmaven_publisher_stage_redir_test_info(
            release_id, "com.android.tools:r8:%s" % args.version, "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


# ------------------------------------------------------ column 70 --v
def git_message_dev(version, bugs):
    return """Update D8 R8 to %s

This is a development snapshot, it's fine to use for studio canary
build, but not for BETA or release, for those we would need a release
version of R8 binaries. This build IS suitable for preview release
but IS NOT suitable for public release.

Built here: go/r8-releases/raw/%s
Test: ./gradlew check
Bug: %s""" % (version, version, '\nBug: '.join(map(bug_fmt, bugs)))


def git_message_release(version, bugs):
    return """D8 R8 version %s

Built here: go/r8-releases/raw/%s/
Test: ./gradlew check

Bug: %s""" % (version, version, '\nBug: '.join(map(bug_fmt, bugs)))


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


def prepare_studio(args):
    assert args.version
    assert os.path.exists(args.studio), ("Could not find STUDIO path %s" %
                                         args.studio)
    if (not args.legacy_release):
        print("Please use the new release process, see go/r8-release-prebuilts. "
            + "If for some reason the legacy release process is needed "
            + "pass --legacy-release")
        sys.exit(1)

    def release_studio(options):
        print("Releasing for STUDIO")
        if options.dry_run:
            return 'DryRun: omitting studio release for %s' % options.version

        if 'dev' in options.version:
            git_message = git_message_dev(options.version, options.bug)
            r8_checkout = utils.REPO_ROOT
            return release_studio_or_aosp(r8_checkout, args.studio, options,
                                          git_message)
        else:
            with utils.TempDir() as temp:
                checkout_r8(temp,
                            options.version[0:options.version.rindex('.')])
                git_message = git_message_release(options.version, options.bug)
                return release_studio_or_aosp(temp, args.studio, options,
                                              git_message)

    return release_studio


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',
        '^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 args.version
    # 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):
        print("Releasing for Google 3")
        if options.dry_run:
            return 'DryRun: omitting g3 release for %s' % options.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')
            download_file(options.version,
                          'r8-full-exclude-deps.jar',
                          'full.jar')
            download_file(options.version,
                          'r8-src.jar',
                          'src.jar')
            download_file(options.version,
                          'r8lib-exclude-deps.jar',
                          'lib.jar')
            download_file(options.version,
                          'r8lib-exclude-deps.jar.map',
                          'lib.jar.map')
            download_file(options.version,
                          'desugar_jdk_libs_configuration.jar',
                          'desugar_jdk_libs_configuration.jar')
            download_file(options.version,
                          'threading-module-blocking.jar',
                          'threading-module-blocking.jar')
            download_file(options.version,
                          'threading-module-single-threaded.jar',
                          'threading-module-single-threaded.jar')
            if options.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, options.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 options.version.endswith('-dev') or not previous_version.endswith('-dev'):
                print(f'ERROR: At least one of {options.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(options.version), options.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 options.version in blaze_result

            if not options.no_upload:
                change_result = g4_change(options.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(
    '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', '--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>'),
        help=
        'The new version 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('--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('--no-bugs',
                        default=False,
                        action='store_true',
                        help='Allow Studio release without specifying any bugs')
    result.add_argument(
        '--studio',
        metavar=('<path>'),
        help='Release for studio by setting the path to a studio '
        'checkout')
    result.add_argument('--legacy-release',
                        default=False,
                        action='store_true',
                        help='Allow Studio/AOSP release using the legacy process')
    result.add_argument('--aosp',
                        metavar=('<path>'),
                        help='Release for aosp by setting the path to the '
                        'checkout')
    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 branch/CL in aosp/studio/google3')
    result.add_argument('--delete-work-branch',
                        '--delete_work_branch',
                        default=False,
                        action='store_true',
                        help='Delete CL in google3')
    result.add_argument('--bypass-hooks',
                        '--bypass_hooks',
                        default=False,
                        action='store_true',
                        help="Bypass hooks when uploading")
    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 (len(args.bug) > 0 and args.no_bugs):
        print("Use of '--bug' and '--no-bugs' are mutually exclusive")
        sys.exit(1)

    if (args.studio and args.version and not 'dev' in args.version and
            args.bug == [] and not args.no_bugs):
        print("When releasing a release version to Android Studio add the " +
              "list of bugs by using '--bug'")
        sys.exit(1)

    if args.version and not 'dev' in args.version and args.google3:
        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.studio or args.aosp:
            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.studio or args.aosp:
            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.studio and not args.update_desugar_library_in_studio:
        targets_to_run.append(prepare_studio(args))
    if args.aosp:
        targets_to_run.append(prepare_aosp(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())
