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

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


def parse_options():
    parser = argparse.ArgumentParser(description='Release r8')
    parser.add_argument('--branch',
                        metavar=('<branch>'),
                        help='Branch 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('hashes',
                        metavar='<hash>',
                        nargs='+',
                        help='Hashed to merge')
    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')
    return parser.parse_args()


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

    bugs = set()

    count = 1
    for hash in args.hashes:
        branch = 'cherry-%s-%d' % (args.branch, count)
        print('Cherry-picking %s in %s' % (hash, branch))
        if count == 1:
            subprocess.run([
                'git', 'new-branch', branch, '--upstream',
                '%s/%s' % (args.remote, args.branch)
            ])
        else:
            subprocess.run(['git', 'new-branch', branch, '--upstream-current'])

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

    branch = 'cherry-%s-%d' % (args.branch, count)
    subprocess.run(['git', 'new-branch', branch, '--upstream-current'])

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

    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)])
        subprocess.run([
            'sed', '-i',
            's/%s/%s/' % (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 = ("Version %s\n\n" % new_version)
    for bug in sorted(bugs):
        message += 'Bug: b/%s\n' % bug

    subprocess.run(['git', 'commit', '-a', '-m', 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(branch, 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)' % (branch, os.getcwd()))

      while True:
          try:
              answer = input(question + ' [yes/abort]? ')
              if answer == 'yes':
                 break
              if answer == 'abort':
                  print('Aborting new branch for %s' % branch)
                  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())

    if not args.no_upload:
        cmd = ['git', 'cl', 'upload', '--bypass-hooks']
        if (args.yes):
            cmd.append('-f')
        subprocess.run(cmd)


def main():
    args = parse_options()

    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)
    else:
        # Run in current directory.
        print("Performing cherry-picking in %s" % os.getcwd())
        subprocess.check_output(['git', 'fetch', 'origin'])
        run(args)


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