#!/usr/bin/python

# Copyright (c) 2012, the Dart 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 optparse
import os
import platform
import subprocess
import sys

"""A script used to revert one or a sequence of consecutive CLs, for svn and
git-svn users.
"""

def parse_args():
  parser = optparse.OptionParser()
  parser.add_option('--revisions', '-r', dest='rev_range', action='store',
                    default=None, help='The revision number(s) of the commits '
                    'you wish to undo. An individual number, or a range (8-10, '
                    '8..10, or 8:10).')
  args, _ = parser.parse_args()
  revision_range = args.rev_range
  if revision_range == None:
    maybe_fail('You must specify at least one revision number to revert.')
  if revision_range.find('-') > -1 or revision_range.find(':') > -1 or \
      revision_range.find('..') > -1:
    # We have a range of commits to revert.
    split = revision_range.split('-')
    if len(split) == 1:
      split = revision_range.split(':')
    if len(split) == 1:
      split = revision_range.split('..')
    start = int(split[0])
    end = int(split[1])
    if start > end:
      temp = start
      start = end
      end = temp
    if start != end:
      maybe_fail('Warning: Are you sure you want to revert a range of '
                 'revisions? If you just want to revert one CL, only specify '
                 'one revision number.', user_input=True)
  else:
    start = end = int(revision_range)
  return start, end

def maybe_fail(msg, user_input=False):
  """Determine if we have encountered a condition upon which our script cannot
  continue, and abort if so.
  Args:
    - msg: The error or user prompt message to print.
    - user_input: True if we require user confirmation to continue. We assume
                  that the user must enter y to proceed.
  """
  if user_input:
    force = raw_input(msg + ' (y/N) ')
    if force != 'y':
      sys.exit(0)
  else:
    print msg
    sys.exit(1)

def has_new_code(is_git):
  """Tests if there are any newer versions of files on the server.
  Args:
    - is_git: True if we are working in a git repository.
  """
  os.chdir(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  if not is_git:
    results, _ = run_cmd(['svn', 'st'])
  else:
    results, _ = run_cmd(['git', 'status'])
  for line in results.split('\n'):
    if not is_git and (not line.strip().startswith('?') and line != ''):
      return True
    elif is_git and ('Changes to be committed' in line or 
        'Changes not staged for commit:' in line):
      return True
  if is_git:
    p = subprocess.Popen(['git', 'log', '-1'], stdout=subprocess.PIPE,
                         shell=(platform.system()=='Windows'))
    output, _ = p.communicate()
    if find_git_info(output) == None:
      return True
  return False

def run_cmd(cmd_list, suppress_output=False, std_in=''):
  """Run the specified command and print out any output to stdout."""
  print ' '.join(cmd_list)
  p = subprocess.Popen(cmd_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                       stdin=subprocess.PIPE,
                       shell=(platform.system()=='Windows'))
  output, stderr = p.communicate(std_in)
  if output and not suppress_output:
    print output
  if stderr and not suppress_output:
    print stderr
  return (output, stderr)

def runs_git():
  """Returns True if we're standing in an svn-git repository."""
  p = subprocess.Popen(['svn', 'info'], stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE,
                       shell=(platform.system()=='Windows'))
  output, err = p.communicate()
  if err != None and 'is not a working copy' in err:
    p = subprocess.Popen(['git', 'status'], stdout=subprocess.PIPE,
                         shell=(platform.system()=='Windows'))
    output, _ = p.communicate()
    if 'fatal: Not a git repository' in output:
      maybe_fail('Error: not running git or svn.')
    else:
      return True
  return False

def find_git_info(git_log, rev_num=None):
  """Determine the latest svn revision number if rev_num = None, or find the 
  git commit_id that corresponds to a particular svn revision number.
  """
  for line in git_log.split('\n'):
    tokens = line.split()
    if len(tokens) == 2 and tokens[0] == 'commit':
      current_commit_id = tokens[1]
    elif len(tokens) > 0 and tokens[0] == 'git-svn-id:':
      revision_number = int(tokens[1].split('@')[1])
      if revision_number == rev_num:
        return current_commit_id
      if rev_num == None:
        return revision_number

def revert(start, end, is_git):
  """Revert the sequence of CLs.
  Args:
    - start: The first CL to revert.
    - end: The last CL to revert.
    - is_git: True if we are in a git-svn checkout.
  """
  if not is_git:
    _, err = run_cmd(['svn', 'merge', '-r', '%d:%d' % (end, start-1), '.'],
                     std_in='p')
    if 'Conflict discovered' in err:
      maybe_fail('Please fix the above conflicts before submitting. Then create'
             ' a CL and submit your changes to complete the revert.')

  else:
    # If we're running git, we have to use the log feature to find the commit
    # id(s) that correspond to the particular revision number(s).
    output, _ = run_cmd(['git', 'log', '-1'], suppress_output=True)
    current_revision = find_git_info(output)
    distance = (current_revision-start) + 1
    output, _ = run_cmd(['git', 'log', '-%d' % distance], suppress_output=True)
    reverts = [start]
    commit_msg = '"Reverting %d"' % start
    if end != start:
      reverts = range(start, end + 1)
      reverts.reverse()
      commit_msg = '%s-%d"' % (commit_msg[:-1], end)
    for revert in reverts:
      git_commit_id = find_git_info(output, revert)
      if git_commit_id == None:
        maybe_fail('Error: Revision number not found. Is this earlier than your'
                   ' git checkout history?')
      _, err = run_cmd(['git', 'revert', '-n', git_commit_id])
      if 'error: could not revert' in err or 'unmerged' in err:
        command_sequence = ''
        for revert in reverts:
          git_commit_id = find_git_info(output, revert)
          command_sequence += 'git revert -n %s\n' % git_commit_id
        maybe_fail('There are conflicts while reverting. Please resolve these '
                   'after manually running:\n' + command_sequence + 'and then '
                   'create a CL and submit to complete the revert.')
    run_cmd(['git', 'commit', '-m', commit_msg])

def main():
  revisions = parse_args()
  git_user = runs_git()
  if has_new_code(git_user):
    maybe_fail('WARNING: This checkout has local modifications!! This could '
         'result in a CL that is not just a revert and/or you could lose your'
         ' local changes! Are you **SURE** you want to continue? ',
       user_input=True)
  if git_user:
    run_cmd(['git', 'cl', 'rebase'])
  run_cmd(['gclient', 'sync'])
  revert(revisions[0], revisions[1], git_user)
  print ('Now, create a CL and submit! The buildbots and your teammates thank '
         'you!')

if __name__ == '__main__':
  main()
