#!/usr/bin/env python
# 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:]))
