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

# Script that automatically pulls and uploads all upstream direct and indirect
# branches into the current branch.
#
# Example:
#
#   $ git branch -vv
#   * feature_final    xxxxxxxxx [feature_prereq_c: ...] ...
#     feature_prereq_c xxxxxxxxx [feature_prereq_b: ...] ...
#     feature_prereq_b xxxxxxxxx [feature_prereq_a: ...] ...
#     feature_prereq_a xxxxxxxxx [main: ...] ...
#     main             xxxxxxxxx [origin/main] ...
#
# Executing `git_sync_cl_chain.py -m <message>` causes the following chain of
# commands to be executed:
#
#   $ git checkout feature_prereq_a; git pull; git cl upload -m <message>
#   $ git checkout feature_prereq_b; git pull; git cl upload -m <message>
#   $ git checkout feature_prereq_c; git pull; git cl upload -m <message>
#   $ git checkout feature_final;    git pull; git cl upload -m <message>

import optparse
import os
import sys

import defines
import utils

REPO_ROOT = defines.REPO_ROOT

class Repo(object):
  def __init__(self, name, is_current, upstream):
    self.name = name
    self.is_current = is_current
    self.upstream = upstream

def ParseOptions(argv):
  result = optparse.OptionParser()
  result.add_option('--delete', '-d',
                    help='Delete closed branches',
                    choices=['y', 'n', 'ask'],
                    default='ask')
  result.add_option('--from_branch', '-f',
                    help='Uppermost upstream to sync from',
                    default='main')
  result.add_option('--leave_upstream', '--leave-upstream',
                    help='To not update the upstream of the first open branch',
                    action='store_true')
  result.add_option('--message', '-m',
                    help='Message for patchset', default='Sync')
  result.add_option('--rebase',
                    help='To use `git pull --rebase` instead of `git pull`',
                    action='store_true')
  result.add_option('--no_upload', '--no-upload',
                    help='Disable uploading to Gerrit', action='store_true')
  result.add_option('--skip_main', '--skip-main',
                    help='Disable syncing for main',
                    action='store_true')
  (options, args) = result.parse_args(argv)
  options.upload = not options.no_upload
  assert options.delete != 'y' or not options.leave_upstream, (
      'Inconsistent options: cannot leave the upstream of the first open ' +
      'branch (--leave_upstream) and delete the closed branches at the same ' +
      'time (--delete).')
  assert options.message, 'A message for the patchset is required.'
  assert len(args) == 0
  return options

def main(argv):
  options = ParseOptions(argv)
  with utils.ChangedWorkingDirectory(REPO_ROOT, quiet=True):
    branches = [
        parse(line)
        for line in utils.RunCmd(['git', 'branch', '-vv'], quiet=True)]

    current_branch = None
    for branch in branches:
      if branch.is_current:
        current_branch = branch
        break
    assert current_branch is not None

    if is_root_branch(current_branch, options):
      print('Nothing to sync')
      return

    stack = []
    while current_branch:
      stack.append(current_branch)
      if is_root_branch(current_branch, options):
        break
      current_branch = get_branch_with_name(current_branch.upstream, branches)

    closed_branches = []
    has_seen_local_branch = False # A branch that is not uploaded.
    has_seen_open_branch = False # A branch that is not closed.
    while len(stack) > 0:
      branch = stack.pop()

      utils.RunCmd(['git', 'checkout', branch.name], quiet=True)

      status = get_status_for_current_branch()
      print('Syncing %s (status: %s)' % (branch.name, status))

      pull_for_current_branch(branch, options)

      if branch.name == 'main':
        continue

      if status == 'closed':
        assert not has_seen_local_branch, (
            'Unexpected closed branch %s after new branch' % branch.name)
        assert not has_seen_open_branch, (
            'Unexpected closed branch %s after open branch' % branch.name)
        closed_branches.append(branch.name)
        continue

      if not options.leave_upstream:
        if not has_seen_open_branch and len(closed_branches) > 0:
          print(
              'Setting upstream for first open branch %s to main'
                  % branch.name)
          set_upstream_for_current_branch_to_main()

      has_seen_open_branch = True
      has_seen_local_branch = has_seen_local_branch or (status == 'None')

      if options.upload and status != 'closed':
        if has_seen_local_branch:
          print(
              'Cannot upload branch %s since it comes after a local branch'
                  % branch.name)
        else:
          utils.RunCmd(
              ['git', 'cl', 'upload', '-m', options.message], quiet=True)

    if get_delete_branches_option(closed_branches, options):
      delete_branches(closed_branches)

    utils.RunCmd(['git', 'cl', 'issue'])

def delete_branches(branches):
  assert len(branches) > 0
  cmd = ['git', 'branch', '-D']
  cmd.extend(branches)
  utils.RunCmd(cmd, quiet=True)

def get_branch_with_name(name, branches):
  for branch in branches:
    if branch.name == name:
      return branch
  return None

def get_delete_branches_option(closed_branches, options):
  if len(closed_branches) == 0:
    return False
  if options.leave_upstream:
    return False
  if options.delete == 'y':
    return True
  if options.delete == 'n':
    return False
  assert options.delete == 'ask'
  print('Delete closed branches: %s (Y/N)?' % ", ".join(closed_branches))
  answer = sys.stdin.read(1)
  return answer.lower() == 'y'

def get_status_for_current_branch():
  return utils.RunCmd(['git', 'cl', 'status', '--field', 'status'], quiet=True)[0].strip()

def is_root_branch(branch, options):
  return branch == options.from_branch or branch.upstream is None

def pull_for_current_branch(branch, options):
  if branch.name == 'main' and options.skip_main:
    return
  rebase_args = ['--rebase'] if options.rebase else []
  utils.RunCmd(['git', 'pull'] + rebase_args, quiet=True)


def set_upstream_for_current_branch_to_main():
  utils.RunCmd(['git', 'cl', 'upstream', 'main'], quiet=True)

# Parses a line from the output of `git branch -vv`.
#
# Example output ('*' denotes the current branch):
#
#   $ git branch -vv
#   * feature_final    xxxxxxxxx [feature_prereq_c: ...] ...
#     feature_prereq_c xxxxxxxxx [feature_prereq_b: ...] ...
#     feature_prereq_b xxxxxxxxx [feature_prereq_a: ...] ...
#     feature_prereq_a xxxxxxxxx [main: ...] ...
#     main             xxxxxxxxx [origin/main] ...
def parse(line):
  is_current = False
  if line.startswith('*'):
    is_current = True
    line = line[1:].lstrip()
  else:
    line = line.lstrip()

  name_end_index = line.index(' ')
  name = line[:name_end_index]
  line = line[name_end_index:].lstrip()

  if '[' in line:
    line = line[line.index('[')+1:]

    if ':' in line:
      upstream = line[:line.index(':')]
      return Repo(name, is_current, upstream)

    if ']' in line:
      upstream = line[:line.index(']')]
      return Repo(name, is_current, upstream)

  return Repo(name, is_current, None)

if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
