#!/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.
#

# Utility for creating well-formed pull request merges and pushing them to Apache. This script is a modified version
# of the one created by the Spark project (https://github.com/apache/spark/blob/master/dev/merge_spark_pr.py).
#
# Usage: ./bk-merge-pr.py (see config env vars below)
#
# This utility assumes you already have local a bookkeeper git folder and that you
# have added remotes corresponding to the github apache bookkeeper repo.

import json
import os
import re
import subprocess
import sys
from urllib.request import urlopen, Request
from urllib.error import HTTPError

PROJECT_NAME = "bookkeeper"

CAPITALIZED_PROJECT_NAME = PROJECT_NAME.upper()
GITHUB_ISSUES_NAME = "issue".upper()

# Location of the local git repository
REPO_HOME = os.environ.get("%s_HOME" % CAPITALIZED_PROJECT_NAME, os.getcwd())
# Remote name which points to the GitHub site
PR_REMOTE_NAME = os.environ.get("PR_REMOTE_NAME", "apache")
# Github API page size
GITHUB_PAGE_SIZE = os.environ.get("GH_PAGE_SIZE", "100")
# OAuth key used for issuing requests against the GitHub API. If this is not defined, then requests
# will be unauthenticated. You should only need to configure this if you find yourself regularly
# exceeding your IP's unauthenticated request rate limit. You can create an OAuth key at
# https://github.com/settings/tokens. This script only requires the "public_repo" scope.
GITHUB_OAUTH_KEY = os.environ.get("GITHUB_OAUTH_KEY")

GITHUB_USER = os.environ.get("GITHUB_USER", "apache")
GITHUB_BASE = "https://github.com/%s/%s/pull" % (GITHUB_USER, PROJECT_NAME)
GITHUB_API_URL  = "https://api.github.com"
GITHUB_API_BASE = "%s/repos/%s/%s" % (GITHUB_API_URL, GITHUB_USER, PROJECT_NAME)
# Prefix added to temporary branches
TEMP_BRANCH_PREFIX = "PR_TOOL"
RELEASE_BRANCH_PREFIX = "branch-"

DEFAULT_FIX_VERSION = os.environ.get("DEFAULT_FIX_VERSION", "0.9.1.0")

def get_json(url, preview_api = False):
    try:
        request = Request(url)
        if GITHUB_OAUTH_KEY:
            request.add_header('Authorization', 'token %s' % GITHUB_OAUTH_KEY)
        if preview_api:
            request.add_header('Accept', 'application/vnd.github.black-cat-preview+json')
        return json.loads(urlopen(request).read())
    except HTTPError as e:
        if "X-RateLimit-Remaining" in e.headers and e.headers["X-RateLimit-Remaining"] == '0':
            print("Exceeded the GitHub API rate limit; see the instructions in " + \
                  "bk-merge-pr.py to configure an OAuth token for making authenticated " + \
                  "GitHub requests.")
        else:
            print("Unable to fetch URL, exiting: %s" % url)
        sys.exit(-1)

def post_json(url, data):
    try:
        request = Request(url, data.encode(encoding='utf-8'), { 'Content-Type': 'application/json' })
        request.add_header('Authorization', 'token %s' % GITHUB_OAUTH_KEY)
        return json.loads(urlopen(request).read())
    except HTTPError as e:
        if "X-RateLimit-Remaining" in e.headers and e.headers["X-RateLimit-Remaining"] == '0':
            print("Exceeded the GitHub API rate limit; see the instructions in " + \
                  "bk-merge-pr.py to configure an OAuth token for making authenticated " + \
                  "GitHub requests.")
        else:
            print("Unable to fetch URL, exiting: %s - %s" % (url, e))
        sys.exit(-1)

def put_json(url, data):
    try:
        request = Request(url, data.encode(encoding='utf-8'), { 'Content-Type': 'application/json' })
        request.get_method = lambda: 'PUT'
        request.add_header('Authorization', 'token %s' % GITHUB_OAUTH_KEY)
        return json.loads(urlopen(request).read())
    except HTTPError as e:
        if "X-RateLimit-Remaining" in e.headers and e.headers["X-RateLimit-Remaining"] == '0':
            print("Exceeded the GitHub API rate limit; see the instructions in " + \
                  "bk-merge-pr.py to configure an OAuth token for making authenticated " + \
                  "GitHub requests.")
        else:
            print("Unable to fetch URL, exiting: %s - %s" % (url, e))
            print(e)
        sys.exit(-1)


def fail(msg):
    print(msg)
    clean_up()
    sys.exit(-1)


def run_cmd(cmd):
    print(cmd)
    if isinstance(cmd, list):
        return subprocess.check_output(cmd).decode(encoding='utf-8')
    else:
        return subprocess.check_output(cmd.split(" ")).decode(encoding='utf-8')


def continue_maybe(prompt):
    result = input("\n%s (y/n): " % prompt)
    if result.lower() != "y":
        fail("Okay, exiting")

def clean_up():
    if original_head != get_current_branch():
        print("Restoring head pointer to %s" % original_head)
        run_cmd("git checkout %s" % original_head)

    branches = run_cmd("git branch").replace(" ", "").split("\n")

    for branch in list(filter(lambda x: x.startswith(TEMP_BRANCH_PREFIX), branches)):
        print("Deleting local branch %s" % branch)
        run_cmd("git branch -D %s" % branch)

def get_current_branch():
    return run_cmd("git rev-parse --abbrev-ref HEAD").replace("\n", "")

def get_milestones():
    return get_json("https://api.github.com/repos/%s/%s/milestones?state=open&sort=due_on&direction=asc" % (GITHUB_USER, PROJECT_NAME))

def get_all_labels():
    result = get_json("https://api.github.com/repos/%s/%s/labels?per_page=%s" % (GITHUB_USER, PROJECT_NAME, GITHUB_PAGE_SIZE))
    return list(map(lambda x: x['name'], result))

# merge the requested PR and return the merge hash
def merge_pr(pr_num, target_ref, title, body, default_pr_reviewers, pr_repo_desc):
    pr_branch_name = "%s_MERGE_PR_%s" % (TEMP_BRANCH_PREFIX, pr_num)
    run_cmd("git fetch %s pull/%s/head:%s" % (PR_REMOTE_NAME, pr_num, pr_branch_name))

    reviewers = input("Enter reviewers [%s]: " % default_pr_reviewers).strip()
    if reviewers == '':
        reviewers = default_pr_reviewers

    commits = run_cmd(['git', 'log', 'HEAD..%s' % pr_branch_name,
                      '--pretty=format:%h [%an] %s']).split("\n")
    
    if len(commits) > 1:
        result = input("List pull request commits in squashed commit message? (y/n): ")
        if result.lower() == "y":
          should_list_commits = True
        else:
          should_list_commits = False
    else:
        should_list_commits = False

    merge_message_flags = []

    if body is not None:
        # We remove @ symbols from the body to avoid triggering e-mails
        # to people every time someone creates a public fork of the project.
        merge_message_flags += [body.replace("@", "")]

    if (reviewers != ""):
        merge_message_flags += ["Reviewers: %s" % reviewers]

    # The string "Closes #%s" string is required for GitHub to correctly close the PR
    close_line = "This closes #%s from %s" % (pr_num, pr_repo_desc)
    # Find the github issues to close
    github_issues = re.findall("#[0-9]{3,6}", title)

    if len(github_issues) != 0:
        for issue_id in github_issues:
            close_line += ", closes %s" % (issue_id)

    if should_list_commits:
        close_line += " and squashes the following commits:"
    merge_message_flags += [close_line]

    if should_list_commits:
        merge_message_flags += ["\n".join(commits)]

    pr_sha = run_cmd("git rev-parse %s" % pr_branch_name).rstrip()

    merge_url = get_github_issue_merge_url(pr_num)
    data = json.dumps({
        'commit_title': title,
        'commit_message': "\n\n".join(merge_message_flags),
        'sha': pr_sha,
        'merge_method': 'squash'
    }, indent = 4)

    continue_maybe("Merge Pull Request (%s) with following details:\n%s" % (
        pr_num, data))

    resp = put_json(merge_url, data)

    merge_hash = resp['sha']
    merge_log = title + '\n' + "\n\n".join(merge_message_flags)
    clean_up()
    print("Pull request #%s merged!" % pr_num)
    print("Merge hash: %s" % merge_hash)
    return merge_hash, merge_log

def ask_for_branch(default_branch):
    pick_ref = input("Enter a branch name [%s]: " % default_branch)
    if pick_ref == "":
        pick_ref = default_branch
    return pick_ref

def cherry_pick(pr_num, merge_hash, pick_ref):
    pick_branch_name = "%s_PICK_PR_%s_%s" % (TEMP_BRANCH_PREFIX, pr_num, pick_ref.upper())

    run_cmd("git fetch %s %s:%s" % (PR_REMOTE_NAME, pick_ref, pick_branch_name))
    run_cmd("git checkout %s" % pick_branch_name)

    try:
        run_cmd("git cherry-pick -sx %s" % merge_hash)
    except Exception as e:
        msg = "Error cherry-picking: %s\nWould you like to manually fix-up this merge?" % e
        continue_maybe(msg)
        msg = "Okay, please fix any conflicts and finish the cherry-pick. Finished?"
        continue_maybe(msg)

    continue_maybe("Pick complete (local ref %s). Push to %s?" % (
        pick_branch_name, PR_REMOTE_NAME))

    try:
        run_cmd('git push %s %s:%s' % (PR_REMOTE_NAME, pick_branch_name, pick_ref))
    except Exception as e:
        clean_up()
        fail("Exception while pushing: %s" % e)

    pick_hash = run_cmd("git rev-parse %s" % pick_branch_name)[:8]
    clean_up()

    print("Pull request #%s picked into %s!" % (pr_num, pick_ref))
    print("Pick hash: %s" % pick_hash)
    return pick_ref


def fix_version_from_branch(branch, versions, target_ref):
    # Note: Assumes this is a sorted (newest->oldest) list of un-released versions
    if branch == target_ref:
        versions = list(filter(lambda x: x == DEFAULT_FIX_VERSION, versions))
        if len(versions) > 0:
            return versions[0]
        else:
            return None
    else:
        versions = list(filter(lambda x: x.startswith(branch), versions))
        if len(versions) > 0:
            return versions[-1]
        else:
            return None

def standardize_issue_ref(text):
    """
    Standardize the github reference commit message prefix to "Issue #XXX: Issue"

    'ISSUE #376: Script for generating patch for reviews'
    """
    github_issue_refs = []
    github_issue_ids = []
    components = []

    # Extract Github Issue ref(s)
    pattern = re.compile(r'(%s[-\s]*([0-9]{3,6}))+' % GITHUB_ISSUES_NAME, re.IGNORECASE)
    for ref in pattern.findall(text):
        # Add brackets, replace spaces or a dash with ' #', & convert to uppercase
        github_issue_refs.append(re.sub(r'[-\s]+', ' #', ref[0].upper()))
        text = text.replace(ref[0], '')
        github_issue_ids.append(ref[1].upper())

    # Extract project name component(s):
    # Look for alphanumeric chars, spaces, dashes, periods, and/or commas
    pattern = re.compile(r'(\[[\w\s,-\.]+\])', re.IGNORECASE)
    for component in pattern.findall(text):
        components.append(component.upper())
        text = text.replace(component, '')

    # Cleanup any remaining symbols:
    pattern = re.compile(r'^\W+(.*)', re.IGNORECASE)
    if (pattern.search(text) is not None):
        text = pattern.search(text).groups()[0]

    # Assemble full text (github ref(s), module(s), remaining text)
    prefix = ''
    github_prefix = ' '.join(github_issue_refs).strip()
    if github_prefix:
        prefix = github_prefix + ": "
    clean_text = prefix + ' '.join(components).strip() + " " + text.strip()

    # Replace multiple spaces with a single space, e.g. if no  refs and/or components were included
    clean_text = re.sub(r'\s+', ' ', clean_text.strip())

    return clean_text, github_issue_ids

def get_reviewers(pr_num):
    """
    Get a candidate list of reviewers that have commented on the PR with '+1' or 'LGTM'
    """
    approval_msgs = ['+1', 'lgtm']

    pr_comments = get_json("%s/issues/%s/comments" % (GITHUB_API_BASE, pr_num))

    reviewers_ids = set()
    for comment in pr_comments:
        for approval_msg in approval_msgs:
            if approval_msg in comment['body'].lower():
                reviewers_ids.add(comment['user']['login'])

    approval_review_states = ['approved']
    pr_reviews = get_json('{0}/pulls/{1}/reviews?per_page=100'.format(GITHUB_API_BASE, pr_num), True)
    for review in pr_reviews:
        for approval_state in approval_review_states:
            if approval_state in review['state'].lower():
                reviewers_ids.add(review['user']['login'])

    if len(reviewers_ids) == 0:
        fail("No approvals found in this pull request")

    reviewers_emails = []
    for reviewer_id in reviewers_ids:
        username = None
        useremail = None
        user = get_json("%s/users/%s" % (GITHUB_API_URL, reviewer_id))
        if user['email']:
            useremail = user['email'].strip()
        if user['name']:
            username = user['name'].strip()
        if username is None:
            continue
        reviewers_emails.append('{0} <{1}>'.format(username, useremail))
    return ', '.join(reviewers_emails)

def check_ci_status(pr):
    ci_status = get_json("%s/commits/%s/status" % (GITHUB_API_BASE, pr["head"]["sha"]))
    state = ci_status["state"]
    if state != "success":
        comments = get_json(pr["comments_url"])
        ignore_ci_comments = [c for c in comments if c["body"].upper() == "IGNORE CI"]
        if len(ignore_ci_comments) > 0:
            print("\n\nWARNING: The PR has not passed CI (state is %s)" % (state) \
                + ", but this has been overridden by %s. \n" % (ignore_ci_comments[0]["user"]["login"]) \
                + "Proceed at your own peril!\n\n")
        else:
            check_individual_ci_status(ci_status, comments)

def is_check_passed(check):
    passed = check["state"] == "success"
    if (not passed) and is_jenkins_check(check):
        try:
            return is_jenkins_passed(check["target_url"])
        except:
            fail("failed to fetch the jenkins build status for check '%s'.\nPlease manually check its build status at %s" % (check["context"], check["target_url"]))
    return passed

def is_jenkins_check(check):
    return check["context"].startswith("Jenkins:")

def is_jenkins_passed(url):
    jenkins_status = get_json("%sapi/json?tree=result" % (url))
    return "SUCCESS" == jenkins_status['result'] 

def is_integration_test_check(check):
    return check["context"] == u"Jenkins: Integration Tests"

def check_individual_ci_status(ci_status, comments):
    ci_failures = []
    ci_integration_test_failures = []
    for status in ci_status["statuses"]:
        is_passed = is_check_passed(status) 
        is_integration_test = is_integration_test_check(status)

        if is_integration_test and (not is_passed):
            ci_integration_test_failures.append(status)
        else:
            if not is_passed:
                ci_failures.append(status)

    if len(ci_integration_test_failures) != 0 and len(ci_failures) == 0:
        # all ci passed except integration tests
        ignore_it_ci_comments = [c for c in comments if c["body"].upper() == "IGNORE IT CI"]
        if len(ignore_it_ci_comments) > 0:
            print("\n\nWARNING: The PR has not passed integration tests CI" \
                + ", but this has been overridden by %s. \n" % (ignore_it_ci_comments[0]["user"]["login"]) \
                + "Proceed at your own peril!\n\n")
        else:
            fail("The PR has not passed integration tests CI")
    elif len(ci_failures) != 0 or len(ci_integration_test_failures) != 0:
        fail_msg = "The PR has not passed CI:\n"
        print("")
        for status in ci_failures:
            fail_msg += "\t %s = %s\n" % (status["context"], status["state"])
        for status in ci_integration_test_failures:
            fail_msg += "\t %s = %s\n" % (status["context"], status["state"])
        fail(fail_msg)

def ask_release_for_github_issues(branch, labels):
    print("=== Add release to github issues ===")
    while True:
        fix_releases = ask_for_labels("release/%s" % branch, labels, [])
        if len(fix_releases) != 1:
            print("Please choose only one release to add for branch '%s'." % branch)
            continue

        print("=== Apply following releases to github issues ==")
        print("Fix Releases: %s" % ', '.join(fix_releases))
        print("")

        if input("Would you like to add these releases to github issues? (y/n): ") == "y":
            break
    return fix_releases

def ask_updates_for_github_issues(milestones, labels, issue_labels, milestone_required):
    while True:
        fix_milestone, fix_milestone_number, fix_areas, fix_types = \
            get_updates_for_github_issues(milestones, labels, issue_labels, milestone_required)

        print("=== Apply following milestone, area, type to github issues ==")
        print("Fix Types: %s" % ', '.join(fix_types))
        print("Fix Areas: %s" % ', '.join(fix_areas))
        if milestone_required:
            print("Fix Milestone: %s" % fix_milestone)
        print("")

        if input("Would you like to update github issues with these labels? (y/n): ") == "y":
            break

    return fix_milestone, fix_milestone_number, fix_areas, fix_types

def get_updates_for_github_issues(milestones, labels, issue_labels, milestone_required):
    # get milestone
    fix_milestone = ""
    fix_milestone_number = ""
    if milestone_required:
        default_milestone_name = milestones[0]['title']
        milestone_list = list(map(lambda x: x['title'], milestones))
        milestone_map = dict((milestone['title'], milestone['number']) for milestone in milestones)
        while True:
            fix_milestone = input("Choose fix milestone : options are [%s] - default: [%s]: " % (', '.join(milestone_list).strip(), default_milestone_name))
            fix_milestone = fix_milestone.strip()
            if fix_milestone == "":
                fix_milestone = default_milestone_name
                break
            elif fix_milestone in milestone_map:
                break
            else:
                print("Invalid milestone: %s." % fix_milestone)
        fix_milestone_number = milestone_map[fix_milestone]

    # get area
    fix_areas = ask_for_labels("area/", labels, issue_labels)
    
    # get types
    fix_types = ask_for_labels("type/", labels, issue_labels) 

    return fix_milestone, fix_milestone_number, fix_areas, fix_types

def ask_for_labels(prefix, labels, issue_labels):
    issue_filtered_labels = list(map(lambda l: l.split('/')[1], filter(lambda x: x.startswith(prefix), issue_labels)))
    filtered_labels = list(map(lambda l: l.split('/')[1], filter(lambda x: x.startswith(prefix), labels)))
    while True:
        fix_labels = input("Choose label '%s' - options are: [%s] - default: [%s] (comma separated): "
            % (prefix, ', '.join(filtered_labels).strip(), ', '.join(issue_filtered_labels).strip()))
        if fix_labels == "":
            if not issue_filtered_labels:
                print("Please specify a '%s' label to close the issue!" % prefix)
                continue
            else:
                fix_labels = issue_filtered_labels
                break
        fix_labels = fix_labels.replace(" ", "").split(",")
        if not fix_labels:
            print("Please specify a '%s' label to close the issue!" % prefix)
            continue
        invalid_label = False
        for label in fix_labels:
            if label not in filtered_labels:
                print("Invalid '%s' label: %s." % (prefix, label))
                invalid_label = True
                break
        if invalid_label:
            continue
        else:
            break
    return fix_labels

def get_github_issue_url(github_issue_id):
    return "https://api.github.com/repos/%s/%s/issues/%s" % (GITHUB_USER, PROJECT_NAME, github_issue_id) 

def get_github_issue_merge_url(github_issue_id):
    return "https://api.github.com/repos/%s/%s/pulls/%s/merge" % (GITHUB_USER, PROJECT_NAME, github_issue_id) 

def get_assignees_url(github_issue_id):
    return "https://api.github.com/repos/%s/%s/issues/%s/assignees" % (GITHUB_USER, PROJECT_NAME, github_issue_id) 

def get_github_issue_labels(github_issue_id):
    url = "https://api.github.com/repos/%s/%s/issues/%s/labels" % (GITHUB_USER, PROJECT_NAME, github_issue_id) 
    result = get_json(url)
    return list(map(lambda x: x["name"], result))

def add_release_to_github_issues(github_issue_ids, labels, fix_release):
    for github_issue_id in github_issue_ids:
        labels = add_release_to_github_issue(github_issue_id, labels, fix_release)
    return labels

def add_release_to_github_issue(github_issue_id, labels, fix_release):
    url = get_github_issue_url(github_issue_id)
    labels = ["release/%s" % fix_release] + labels
    data = json.dumps({
        'labels': labels
    })
    post_json(url, data)
    return labels

def update_github_issue(github_issue_id, fix_milestone_number, fix_milestone, fix_areas, fix_types, other_labels):
    url = get_github_issue_url(github_issue_id)
    labels = other_labels + list(map(lambda x: ("area/%s" % x), fix_areas))
    labels = labels + list(map(lambda x: ("type/%s" % x), fix_types))
    if fix_milestone_number == '':
        data = json.dumps({
            'labels': labels,
        })
    else:
        labels.append("release/%s" % fix_milestone)
        data = json.dumps({
            'milestone': int(fix_milestone_number),
            'labels': labels,
        })

    post_json(url, data)
    return labels

def update_github_issues(github_issue_ids, fix_milestone_number, fix_milestone, fix_areas, fix_types, other_labels):
    for github_issue_id in github_issue_ids:
        labels = update_github_issue(github_issue_id, fix_milestone_number, fix_milestone, fix_areas, fix_types, other_labels)
    return labels

def add_assignees_to_github_issues(github_issue_ids, assignees):
    for github_issue_id in github_issue_ids:
        add_assignees_to_github_issue(github_issue_id, assignees)

def add_assignees_to_github_issue(github_issue_id, assignees):
    url = get_assignees_url(github_issue_id)
    data = json.dumps({
        "assignees": assignees
    })
    post_json(url, data)

def main():
    global original_head

    if not GITHUB_OAUTH_KEY:
        print("OAuth key is needed for merging bookkeeper pull requests.")
        print("If environment variable 'GITHUB_OAUTH_KEY' is not defined,")
        print("then requests will be unauthenticated.")
        print("You can create an OAuth key at https://github.com/settings/tokens")
        print("and set it to the environment variable 'GITHUB_OAUTH_KEY'.")
        print("(This token only needs the 'public_repo' scope permissions)")
        exit(-1)

    # 0. get the current state so we can go back
    original_head = get_current_branch()

    # 1. retrieve milestones, labels, branches
    milestones = get_milestones()
    labels = get_all_labels()
    branches = get_json("%s/branches" % GITHUB_API_BASE)
    branch_names = list(filter(lambda x: x.startswith(RELEASE_BRANCH_PREFIX), [x['name'] for x in branches]))
    # Assumes branch names can be sorted lexicographically
    latest_branch = sorted(branch_names, reverse=True)[0]

    # 2. retrieve the details for a given pull request
    pr_num = input("Which pull request would you like to merge? (e.g. 34): ")
    pr = get_json("%s/pulls/%s" % (GITHUB_API_BASE, pr_num))
    pr_events = get_json("%s/issues/%s/events" % (GITHUB_API_BASE, pr_num))
    pr_reviewers = get_reviewers(pr_num)
    check_ci_status(pr)

    url = pr["url"]

    # 3. repair the title for commit message
    pr_title = pr["title"]
    commit_title = input("Commit title [%s]: " % pr_title)
    if commit_title == "":
        commit_title = pr_title

    # Decide whether to use the modified title or not
    modified_title, github_issue_ids = standardize_issue_ref(commit_title)
    if modified_title != commit_title:
        print("I've re-written the title as follows to match the standard format:")
        print("Original: %s" % commit_title)
        print("Modified: %s" % modified_title)
        result = input("Would you like to use the modified title? (y/n): ")
        if result.lower() == "y":
            commit_title = modified_title
            print("Using modified title:")
        else:
            print("Using original title:")
        print(commit_title)

    body = pr["body"]
    modified_body = ""
    for line in body.split('\n'):
        if line.startswith('>'):
            continue
        modified_body = modified_body + line + "\n"
    modified_body = modified_body[:-1]
    if modified_body != body:
        print("I've re-written the body as follows to match the standard formats:")
        print("Original: ")
        print(body)
        print("Modified: ")
        print(modified_body)
        result = input("Would you like to use the modified body? (y/n): ")
        if result.lower() == "y":
            body = modified_body
            print("Using modified body.")
        else:
            print("Using original body.")

    target_ref = pr["base"]["ref"]
    user_login = pr["user"]["login"]
    base_ref = pr["head"]["ref"]
    pr_repo_desc = "%s/%s" % (user_login, base_ref)

    # append pr num to the github issues - we need to attach label and milestone to them
    github_issue_ids.append(pr_num)

    #
    # 4. attach milestone, area, type and release to github issues
    #

    # get issue labels
    issue_labels = get_github_issue_labels(pr_num)
    # ask for fix milestone, area and type
    fix_milestone, fix_milestone_number, fix_areas, fix_types = \
        ask_updates_for_github_issues(milestones, labels, issue_labels, target_ref == "master")
    # update issues with fix milestone, are and type
    other_labels = list(filter(lambda x: not x.startswith("area"), issue_labels))
    all_issue_labels = update_github_issues( \
        github_issue_ids, \
        fix_milestone_number, \
        fix_milestone, \
        fix_areas, \
        fix_types, \
        other_labels)
    # add the pr author to the assignees
    add_assignees_to_github_issues(github_issue_ids, [ user_login ])

    if target_ref != "master":
        branch_version = target_ref.split('-')[1]
        # add releases
        fix_releases = ask_release_for_github_issues(branch_version, labels)
        if len(fix_releases) > 0:
            all_issue_labels = add_release_to_github_issues(github_issue_ids, all_issue_labels, fix_releases[0])

    #
    # 5. Process the merge
    #

    # Merged pull requests don't appear as merged in the GitHub API;
    # Instead, they're closed by asfgit.
    merge_commits = \
        [e for e in pr_events if e["actor"]["login"] == "asfgit" and e["event"] == "closed"]

    if merge_commits:
        merge_hash = merge_commits[0]["commit_id"]
        message = get_json("%s/commits/%s" % (GITHUB_API_BASE, merge_hash))["commit"]["message"]

        print("Pull request %s has already been merged, assuming you want to backport" % pr_num)
        commit_is_downloaded = run_cmd(['git', 'rev-parse', '--quiet', '--verify',
                                    "%s^{commit}" % merge_hash]).strip() != ""
        if not commit_is_downloaded:
            fail("Couldn't find any merge commit for #%s, you may need to update HEAD." % pr_num)

        print("Found commit %s:\n%s" % (merge_hash, message))
        
        cherry_pick(pr_num, merge_hash, ask_for_branch(latest_branch))
        sys.exit(0)

    if not bool(pr["mergeable"]):
        msg = "Pull request %s is not mergeable in its current form.\n" % pr_num + \
            "You may need to rebase the PR."
        fail(msg)

    print("\n=== Pull Request #%s ===" % pr_num)
    print("PR title\t%s\nCommit title\t%s\nSource\t\t%s\nTarget\t\t%s\nURL\t\t%s" % (
        pr_title, commit_title, pr_repo_desc, target_ref, url))
    continue_maybe("Proceed with merging pull request #%s?" % pr_num)

    merged_refs = [target_ref]
    # proceed with the merge
    merge_hash, merge_commit_log = merge_pr(pr_num, target_ref, commit_title, body, pr_reviewers, pr_repo_desc)

    # once the pr is merged, refresh the local repo
    run_cmd("git fetch %s" % PR_REMOTE_NAME)

    pick_prompt = "Would you like to pick %s into another branch?" % merge_hash
    while input("\n%s (y/n): " % pick_prompt).lower() == "y":
        pick_ref = ask_for_branch(latest_branch) 
        branch_version = pick_ref.split('-')[1]
        # add releases
        fix_releases = ask_release_for_github_issues(branch_version, labels)
        if len(fix_releases) > 0:
            all_issue_labels = add_release_to_github_issues(github_issue_ids, all_issue_labels, fix_releases[0])
        merged_refs = merged_refs + [cherry_pick(pr_num, merge_hash, pick_ref)]

if __name__ == "__main__":
    import doctest
    (failure_count, test_count) = doctest.testmod()
    if (failure_count):
        exit(-1)

    main()
