#!/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://gitbox.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()
