#!/usr/bin/env python3
# Copyright (c) 2022, 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 os
import subprocess
import sys

import git_utils
import utils

VERSION_FILE = 'src/main/java/com/android/tools/r8/Version.java'
VERSION_PREFIX = 'String LABEL = "'


def sed(old, new, file):
    subprocess.run(['sed', '-i', 's/%s/%s/' % (old, new), file])


def git_new_branch(name, upstream=None):
    cmd = ['git', 'new-branch', name]
    if upstream:
        cmd += ['--upstream', upstream]
    else:
        cmd += ['--upstream-current']
    subprocess.run(cmd)


def git_commit(message):
    git_utils.GitCommit(message)


def parse_options():
    parser = argparse.ArgumentParser(description='Release r8')
    parser.add_argument('--branch',
                        metavar=('<branch>'),
                        default=[],
                        action='append',
                        help='Branch(es) to cherry-pick to')
    parser.add_argument('--current-checkout',
                        '--current_checkout',
                        default=False,
                        action='store_true',
                        help='Perform cherry picks into the current checkout')
    parser.add_argument('--no-upload',
                        '--no_upload',
                        default=False,
                        action='store_true',
                        help='Do not upload to Gerrit')
    parser.add_argument('--remote',
                        default='origin',
                        help='The remote name (defaults to "origin")')
    parser.add_argument('--yes',
                        default=False,
                        action='store_true',
                        help='Answer "yes" to all questions')
    parser.add_argument('--reviewer',
                        metavar=('<reviewer(s)>'),
                        default=[],
                        action='append',
                        help='Rewiever(s) for the cherry-pick(s) '
                        '(adds @google.com if missing)')
    parser.add_argument('--send-mail',
                        '--send_mail',
                        default=False,
                        action='store_true',
                        help='Send Gerrit review request right away')
    exclusive = parser.add_mutually_exclusive_group(required=True)
    exclusive.add_argument('hashes',
                           default=[],
                           metavar='<hash>',
                           nargs='*',
                           help='Hashes to merge')
    exclusive.add_argument('--promote-dev',
                           '--promote_dev',
                           default=False,
                           action='store_true',
                           help='Promote a -dev branch to stable')
    return parser.parse_args()


def version_from_version_file():
    for line in open(VERSION_FILE, 'r'):
        index = line.find(VERSION_PREFIX)
        if index > 0:
            index += len(VERSION_PREFIX)
            subline = line[index:]
            return subline[:subline.index('"')]
    return "unknown"


def run(args, branch):
    if args.current_checkout:
        for i in range(len(args.hashes) + 1):
            local_branch_name = 'cherry-%s-%d' % (branch, i + 1)
            print('Deleting branch %s' % local_branch_name)
            subprocess.run(
                ['git', 'branch', '--delete', '--force', local_branch_name])

    bugs = set()

    count = 1
    for hash in args.hashes:
        local_branch_name = 'cherry-%s-%d' % (branch, count)
        print('Cherry-picking %s in %s' % (hash, local_branch_name))
        if count == 1:
            git_new_branch(local_branch_name, '%s/%s' % (args.remote, branch))
        else:
            git_new_branch(local_branch_name)

        subprocess.run(['git', 'cherry-pick', hash])
        confirm_and_upload(local_branch_name, args, bugs)
        count = count + 1

    local_branch_name = 'cherry-%s-%d' % (branch, count)
    git_new_branch(local_branch_name)

    old_version = version_from_version_file()
    new_version = 'unknown'
    if old_version.find('.') > 0 and old_version.find('-') == -1:
        split_version = old_version.split('.')
        new_version = '.'.join(split_version[:-1] +
                               [str(int(split_version[-1]) + 1)])
        sed(old_version, new_version, VERSION_FILE)
    else:
        editor = os.environ.get('VISUAL')
        if not editor:
            editor = os.environ.get('EDITOR')
        if not editor:
            editor = 'vi'
        input("\nCannot automatically determine the new version.\n" +
              "Press [enter] to edit %s for version update with editor '%s'." %
              (VERSION_FILE, editor))
        subprocess.run([editor, VERSION_FILE])
        new_version = input(
            'Please enter the new version for the commit message: ')

    message = git_utils.VersionCommitMessage(new_version, bugs=bugs)
    git_commit(message)
    confirm_and_upload(branch, args, None)
    if not args.current_checkout and not args.yes:
        while True:
            try:
                answer = input(
                    "Type 'delete' to finish and delete checkout in %s: " %
                    os.getcwd())
                if answer == 'delete':
                    break
            except KeyboardInterrupt:
                pass


def confirm_and_upload(local_branch_name, args, bugs):
    if not args.yes:
        question = ('Ready to continue (cwd %s, will not upload to Gerrit)' %
                    os.getcwd()
                    if args.no_upload else 'Ready to upload %s (cwd %s)' %
                    (local_branch_name, os.getcwd()))

        while True:
            try:
                answer = input(question + ' [yes/abort]? ')
                if answer == 'yes':
                    break
                if answer == 'abort':
                    print('Aborting new branch for %s' % local_branch_name)
                    sys.exit(1)
            except KeyboardInterrupt:
                pass

    # Compute the set of bug refs from the commit message after confirmation.
    # If done before a conflicting cherry-pick status will potentially include
    # references that are orthogonal to the pick.
    if bugs != None:
        commit_message = subprocess.check_output(
            ['git', 'log', '--format=%B', '-n', '1', 'HEAD'])
        commit_lines = [
            l.strip() for l in commit_message.decode('UTF-8').split('\n')
        ]
        for line in commit_lines:
            bug = None
            if line.startswith('Bug: '):
                bug = line.replace('Bug: ', '')
            elif line.startswith('Fixed: '):
                bug = line.replace('Fixed: ', '')
            elif line.startswith('Fixes: '):
                bug = line.replace('Fixes: ', '')
            if bug:
                bugs.add(bug.replace('b/', '').strip())

    cmd = ['git', 'cl', 'upload', '--bypass-hooks']
    if args.yes:
        cmd.append('-f')
    git_utils.GitClAppendReviewers(cmd, args.reviewer, args.send_mail)
    if not args.no_upload:
        subprocess.run(cmd)
    else:
        print('Not uploading, upload command was "%s"' % cmd)


def promote_dev(args):
    if len(args.branch) > 1:
        print("Only one branch can be specified for --promote-dev.")
        sys.exit(1)
    branch = args.branch[0]

    if args.current_checkout:
        print("--current-checkout not supported for --promote-dev.")
        sys.exit(1)

    with utils.TempDir() as temp:
        print("Performing promote dev in %s" % temp)
        subprocess.check_call(['git', 'clone', utils.REPO_SOURCE, temp])
        with utils.ChangedWorkingDirectory(temp):
            local_branch_name = 'promote-dev-%s' % branch
            subprocess.run(
                ['git', 'branch', '--delete', '--force', local_branch_name])
            git_new_branch(local_branch_name, '%s/%s' % (args.remote, branch))

            dev_version = version_from_version_file()
            print(dev_version)
            if not dev_version.endswith('-dev'):
                print("Not a -dev version branch")
                sys.exit(1)
            version = dev_version[0:len(dev_version) - 4]

            print("Promoting %s to %s" % (dev_version, version))
            sed(dev_version, version, VERSION_FILE)

            message = git_utils.VersionCommitMessage(
                version,
                description=('Promoting version %s to version %s' %
                             (dev_version, version)))

            git_commit(message)
            confirm_and_upload(branch, args, None)


def main():
    args = parse_options()

    if len(args.branch) == 0:
        print("No branches specified.")
        sys.exit(1)

    if args.promote_dev:
        promote_dev(args)
        sys.exit(0)

    # At least one hash even though it is optional, as it is in an exclusive group
    # with --promote-dev which is checked above.
    assert len(args.hashes) > 0
    branches = args.branch
    args.branch = None
    for branch in branches:
        print("Performing cherry-picking to %s" % branch)
        if not args.current_checkout:
            with utils.TempDir() as temp:
                print("Performing cherry-picking in %s" % temp)
                subprocess.check_call(['git', 'clone', utils.REPO_SOURCE, temp])
                with utils.ChangedWorkingDirectory(temp):
                    run(args, branch)
        else:
            # Run in current directory.
            print("Performing cherry-picking in %s" % os.getcwd())
            subprocess.check_output(['git', 'fetch', 'origin'])
            run(args, branch)


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