#!/usr/bin/env python

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

# This script fetches branches from the Gerrit repository and
# allows ASF committers to propagate commits from gerrit into the
# official ASF repository.
#
# Current ASF policy is that this mirroring cannot be automatic
# and should be driven by a committer who inspects and signs off
# on the commits being made into the ASF. Additionally, the ASF
# prefers that in most cases, the committer according to source
# control should be the same person to push the commit to a git
# repository.
#
# This script provides the committer the opportunity to review the
# changes to be pushed, warns them if they are pushing code for
# which they weren't the committer, and performs the actual push.
#
# TODO: Improve console output: replace 'print' with format strings
#       and use sys.stderr/sys.stdout.

import logging
import optparse
import os
import re
import subprocess
import sys

APACHE_REPO = "https://git-wip-us.apache.org/repos/asf/impala.git"
GERRIT_URL_RE = re.compile(r"ssh://.+@gerrit.cloudera.org:29418/Impala-ASF")

# Parsed options, filled in by main().
OPTIONS = None

class Colors(object):
  """ ANSI color codes. """

  def __on_tty(x):
    if not os.isatty(sys.stdout.fileno()):
      return ""
    return x

  RED = __on_tty("\x1b[31m")
  GREEN = __on_tty("\x1b[32m")
  YELLOW = __on_tty("\x1b[33m")
  RESET = __on_tty("\x1b[m")


def check_output(*popenargs, **kwargs):
  r"""Run command with arguments and return its output as a byte string.
  Backported from Python 2.7 as it's implemented as pure python on stdlib.
  >>> check_output(['/usr/bin/python', '--version'])
  Python 2.6.2
  """
  process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
  output, unused_err = process.communicate()
  retcode = process.poll()
  if retcode:
    cmd = kwargs.get("args")
    if cmd is None:
      cmd = popenargs[0]
    error = subprocess.CalledProcessError(retcode, cmd)
    error.output = output
    raise error
  return output


def confirm_prompt(prompt):
  """
  Issue the given prompt, and ask the user to confirm yes/no. Returns true
  if the user confirms.
  """
  while True:
    print prompt, "[Y/n]:",

    if not os.isatty(sys.stdout.fileno()):
      print "Not running interactively. Assuming 'N'."
      return False

    r = raw_input().strip().lower()
    if r in ['y', 'yes', '']:
      return True
    elif r in ['n', 'no']:
      return False


def get_my_email():
  """ Return the email address in the user's git config. """
  return check_output(['git', 'config', '--get', 'user.email']).strip()


def check_apache_remote():
  """
  Checks that there is a remote named <OPTIONS.apache_remote> set up correctly.
  Otherwise, exits with an error message.
  """
  try:
    url = check_output(\
        ['git', 'config', '--local', '--get',
            'remote.' + OPTIONS.apache_remote + '.url']).strip()
  except subprocess.CalledProcessError:
    print >>sys.stderr, "No remote named " + OPTIONS.apache_remote + \
        ". Please set one up, for example with: "
    print >>sys.stderr, "  git remote add apache", APACHE_REPO
    sys.exit(1)
  if url != APACHE_REPO:
    print >>sys.stderr, "Unexpected URL for remote " + OPTIONS.apache_remote + "."
    print >>sys.stderr, "  Got:     ", url
    print >>sys.stderr, "  Expected:", APACHE_REPO
    sys.exit(1)


def check_gerrit_remote():
  """
  Checks that there is a remote named <OPTIONS.gerrit_remote> set up correctly.
  Otherwise, exits with an error message.
  """
  try:
    url = check_output(['git', 'config', '--local', '--get',
                        'remote.' + OPTIONS.gerrit_remote + '.url']).strip()
  except subprocess.CalledProcessError:
    print >>sys.stderr, "No remote named " + OPTIONS.gerrit_remote + \
        ". Please set one up following "
    print >>sys.stderr, "the contributor guide."
    sys.exit(1)

  if not GERRIT_URL_RE.match(url):
    print >>sys.stderr, "Unexpected URL for remote " + OPTIONS.gerrit_remote
    print >>sys.stderr, "  Got:     ", url
    print >>sys.stderr, "  Expected to find host '%s' in the URL" % GERRIT_HOST
    sys.exit(1)


def fetch(remote):
  """Run git fetch for the given remote, including some logging."""
  logging.info("Fetching from remote '%s'..." % remote)
  subprocess.check_call(['git', 'fetch', remote])
  logging.info("done")


def get_branches(remote):
  """ Fetch a dictionary mapping branch name to SHA1 hash from the given remote. """
  out = check_output(["git", "ls-remote", remote, "refs/heads/*"])
  ret = {}
  for l in out.splitlines():
    sha, ref = l.split("\t")
    branch = ref.replace("refs/heads/", "", 1)
    ret[branch] = sha
  return ret


def rev_parse(rev):
  """Run git rev-parse, returning the sha1, or None if not found"""
  try:
    return check_output(['git', 'rev-parse', rev], stderr=subprocess.STDOUT).strip()
  except subprocess.CalledProcessError:
    return None


def rev_list(arg):
  """Run git rev-list, returning an array of SHA1 commit hashes."""
  return check_output(['git', 'rev-list', arg]).splitlines()


def describe_commit(rev):
  """ Return a one-line description of a commit. """
  return subprocess.check_output(
      ['git', 'log', '--color', '-n1', '--oneline', rev]).strip()


def is_fast_forward(ancestor, child):
  """
  Return True if 'child' is a descendent of 'ancestor' and thus
  could be fast-forward merged.
  """
  try:
    merge_base = check_output(['git', 'merge-base', ancestor, child]).strip()
  except:
    # If either of the commits is unknown, count this as a non-fast-forward.
    return False
  return merge_base == rev_parse(ancestor)


def get_committer_email(rev):
  """ Return the email address of the committer of the given revision. """
  return check_output(['git', 'log', '-n1', '--pretty=format:%ce', rev]).strip()


def do_update(branch, gerrit_sha, apache_sha):
  """
  Displays and performs a proposed update of the Apache repository
  for branch 'branch' from 'apache_sha' to 'gerrit_sha'.
  """
  # First, verify that the update is fast-forward. If it's not, then something
  # must have gotten committed to Apache outside of gerrit, and we'd need some
  # manual intervention.
  if not is_fast_forward(apache_sha, gerrit_sha):
    print >>sys.stderr, "Cannot update branch '%s' from gerrit:" % branch
    print >>sys.stderr, "Apache revision %s is not an ancestor of gerrit revision %s" % (
      apache_sha[:8], gerrit_sha[:8])
    print >>sys.stderr,\
        "Something must have been committed to Apache and bypassed gerrit."
    print >>sys.stderr, "Manual intervention is required."
    sys.exit(1)

  # List the commits that are going to be pushed to the ASF, so that the committer
  # can verify and "sign off".
  commits = rev_list("%s..%s" % (apache_sha, gerrit_sha))
  commits.reverse()  # Display from oldest to newest.
  print "-" * 60
  print Colors.GREEN + ("%d commit(s) need to be pushed from Gerrit to ASF:" %\
      len(commits)) + Colors.RESET
  push_sha = None
  for sha in commits:
    oneline = describe_commit(sha)
    print "  ", oneline
    committer = get_committer_email(sha)
    if committer != get_my_email():
      print Colors.RED + "   !!! Committed by someone else (%s) !!!" %\
          committer, Colors.RESET
      if not confirm_prompt(Colors.RED +\
          "   !!! Are you sure you want to push on behalf of another committer?" +\
          Colors.RESET):
        # Even if they don't want to push this commit, we could still push any
        # earlier commits that the user _did_ author.
        if push_sha is not None:
          print "... will still update to prior commit %s..." % push_sha
        break
    push_sha = sha
  if push_sha is None:
    print "Nothing to push"
    return

  # Everything has been confirmed. Do the actual push
  cmd = ['git', 'push', OPTIONS.apache_remote]
  if OPTIONS.dry_run:
    cmd.append('--dry-run')
  cmd.append('%s:refs/heads/%s' % (push_sha, branch))
  print Colors.GREEN + "Running: " + Colors.RESET + " ".join(cmd)
  subprocess.check_call(cmd)
  print Colors.GREEN + "Successfully updated %s to %s" % (branch, gerrit_sha) +\
      Colors.RESET
  print


def main():
  global OPTIONS
  p = optparse.OptionParser(
    epilog=("See the top of the source code for more information on the purpose of "
            "this script."))
  p.add_option("-n", "--dry-run", action="store_true",
               help="Perform git pushes with --dry-run")
  p.add_option(
      "-g",
      "--gerrit_remote",
      dest="gerrit_remote",
      help="Name of the git remote that corresponds to gerrit",
      default="asf-gerrit")
  p.add_option(
      "-a",
      "--apache_remote",
      dest="apache_remote",
      help="Name of the git remote that corresponds to apache",
      default="apache")
  OPTIONS, args = p.parse_args()
  if args:
    p.error("no arguments expected")
    sys.exit(1)

  # Pre-flight checks.
  check_apache_remote()
  check_gerrit_remote()

  # Ensure we have the latest state of gerrit.
  fetch(OPTIONS.gerrit_remote)

  # Check the current state of branches on Apache.
  # For each branch, we try to update it if the revisions don't match.
  apache_branches = get_branches(OPTIONS.apache_remote)
  for branch, apache_sha in sorted(apache_branches.iteritems()):
    gerrit_sha = rev_parse("remotes/" + OPTIONS.gerrit_remote + "/" + branch)
    print "Branch '%s':\t" % branch,
    if gerrit_sha is None:
      print Colors.YELLOW, "found on Apache but not in gerrit", Colors.RESET
      continue
    if gerrit_sha == apache_sha:
      print Colors.GREEN, "up to date", Colors.RESET
      continue
    print Colors.YELLOW, "needs update", Colors.RESET
    do_update(branch, gerrit_sha, apache_sha)


if __name__ == "__main__":
  logging.basicConfig(level=logging.INFO)
  main()
