#!/usr/bin/env python3
"""Open a PR from the current branch"""

import sys
import os
import argparse
import requests
import re
from subprocess import check_call, check_output
from os.path import expanduser

usage = """
Example usage:

Open PR against master, with the review label:

./dev-tools/open_pr --remote tsg

Open PR against the 6.0 branch, with the review and in progress labels:

./dev-tools/open_pr --remote tsg --branch 6.0 --wip

Open PR against the 6.0 branch, with the review and docs labels:

./dev-tools/open_pr --remote tsg --labels=review,docs

The title and message of the PR are taken from the _last_ commit in the
PR.
"""

def main():
    parser = argparse.ArgumentParser(
        description="Creates a PR against a given branch",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=usage)

    parser.add_argument("--remote", default="origin",
                        help="Your git remote to push the branch to.")
    parser.add_argument("--branch", default="master",
                        help="Remote branch to open PR against (e.g 5.0)")
    parser.add_argument("--wip", action="store_true",
                        help="Add the `in progress` label")
    parser.add_argument("--labels",
                        help="Extra labels to add (comma separated)")
    parser.add_argument("--yes", action="store_true",
                        help="Assume yes.")
    args = parser.parse_args()
    local_branch = check_output("git rev-parse --abbrev-ref HEAD", shell=True).strip()
    title = check_output("git show -q HEAD --format='%s'", shell=True).strip()
    msg = check_output("git show -q HEAD --format='%b'", shell=True).strip()

    labels = ["review"]
    if args.labels:
        labels.extend(args.labels.split(","))
    if args.wip:
        labels += "in progress"

    # get version and set a version label on the original PR
    version = get_version(os.getcwd())
    if version:
        labels.append("v" + version)

    print("Branch: {}".format(args.branch))
    print("Remote: {}".format(args.remote))
    print("Local branch: {}".format(local_branch))
    print("Title: {}".format(title))
    print("Message: {}".format(msg))
    print("Labels: {}".format(labels))

    if not args.yes and raw_input("Continue? [Y/n]: ") not in ["y", "Y", ""]:
        return 1

    # push branch
    check_call("git push --set-upstream {} {}"
               .format(args.remote, local_branch), shell=True)


    # open PR
    token = open(expanduser("~/.elastic/github.token"), "r").read().strip()
    base = "https://api.github.com/repos/elastic/beats"
    session = requests.Session()
    session.headers.update({"Authorization": "token " + token})

    remote_url = check_output("git remote get-url {}".format(args.remote),
                              shell=True)
    remote_user = re.search("github.com:(.+)/beats", remote_url).group(1)

    request = session.post(base + "/pulls", json=dict(
        title=title,
        head=remote_user + ":" + local_branch,
        base=args.branch,
        body=msg
    ))
    if request.status_code > 299:
        print("Creating PR failed: {}".format(request.json()))
        sys.exit(1)
    new_pr = request.json()

    # add labels
    session.post(
        base + "/issues/{}/labels".format(new_pr["number"]), json=labels)

    print("\nDone. PR created: {}".format(new_pr["html_url"]))
    print("Please go and review it for the message and labels.")


def get_version(beats_dir):
    pattern = re.compile(r'(const\s|)\w*(v|V)ersion\s=\s"(?P<version>.*)"')
    with open(os.path.join(beats_dir, "libbeat/version/version.go"), "r") as f:
        for line in f:
            match = pattern.match(line)
            if match:
                return match.group('version')


if __name__ == "__main__":
    sys.exit(main())
