#!/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 [master: ...] ...
#     master           xxxxxxxxx [origin/master] ...
#
# 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('--message', '-m', help='Message for patchset')
  result.add_option('--rebase',
                    help='To use `git pull --rebase` instead of `git pull`',
                    action='store_true')
  (options, args) = result.parse_args(argv)
  print(options)
  assert options.message, 'A message for the patchset is required.'
  assert len(args) == 0
  return options

def main(argv):
  options = ParseOptions(argv)
  rebase_args = ['--rebase'] if options.rebase else []
  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 current_branch.upstream == None:
      print('Nothing to sync')
      return

    stack = []
    while current_branch:
      stack.append(current_branch)
      if current_branch.upstream is None or current_branch.upstream == 'master':
        break
      current_branch = get_branch_with_name(current_branch.upstream, branches)

    while len(stack) > 0:
      branch = stack.pop()
      print('Syncing ' + branch.name)
      utils.RunCmd(['git', 'checkout', branch.name], quiet=True)
      utils.RunCmd(['git', 'pull'] + rebase_args, quiet=True)
      utils.RunCmd(['git', 'cl', 'upload', '-m', options.message], quiet=True)

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

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

# 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 [master: ...] ...
#     master           xxxxxxxxx [origin/master] ...
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 ('[') not in line or ':' not in line:
    return Repo(name, is_current, None)

  upstream_start_index = line.index('[')
  line = line[upstream_start_index+1:]
  upstream_end_index = line.index(':')
  upstream = line[:upstream_end_index]

  return Repo(name, is_current, upstream)

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