#!/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('--delete', '-d',
                    help='Delete closed branches',
                    choices=['y', 'n', 'ask'],
                    default='ask')
  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_master', '--skip-master',
                    help='Disable syncing for master',
                    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 current_branch.upstream == None:
      print('Nothing to sync')
      return

    stack = []
    while current_branch:
      stack.append(current_branch)
      if current_branch.upstream is None:
        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 == 'master':
        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 master'
                  % branch.name)
          set_upstream_for_current_branch_to_master()

      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 pull_for_current_branch(branch, options):
  if branch.name == 'master' and options.skip_master:
    return
  rebase_args = ['--rebase'] if options.rebase else []
  utils.RunCmd(['git', 'pull'] + rebase_args, quiet=True)


def set_upstream_for_current_branch_to_master():
  utils.RunCmd(['git', 'cl', 'upstream', 'master'], 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 [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 '[' 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:]))
