#!/usr/bin/env python

# The MIT License (MIT)
#
# Copyright (c) 2015 Jared Morrow (github.com/jaredmorrow)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

## Install info
##   $ virtualenv env
##   $ source env/bin/activate
##   $ pip install PyGithub
##
## Examples:
##   Find the differences from last tag to current
##   $ pr2relnotes.py alpha-6 HEAD

import argparse
import re
import os
import subprocess
from github import Github
from github import GithubException


def dprint(*args):
    if VERBOSE:
        print str(args)

def get_args():
    """
    Get command line arguments
    """
    parser = argparse.ArgumentParser(description="Find the PR's between two versions")
    parser.add_argument("old", help = "old version to use")
    parser.add_argument("new", help = "new version to use")
    parser.add_argument("-v", "--verbose", help="Enable debug output",
                        default=False,
                        action="store_true")
    parser.add_argument("-f", "--file",
                        help="Output file to store results (default: tagdiff.md)",
                        default="tagdiff.md")
    return parser.parse_args()

def search_prs(log):
    """
    Search lines of text for PR numbers
    """
    # Find all matches using regex iterator, using the PR # as the group match
    resultlist = [str(m.group(1)) for m in re.finditer(r"erge pull request #(\d+)", log)]
    return sorted(resultlist)

def get_env(env):
    return os.environ[env]

def get_formatted_issue(repo, issue, title, url):
    """
    Single place to adjust formatting output of PR data
    """
    # Newline support writelines() call which doesn't add newlines
    # on its own
    return("* {}/{}: [{}]({})\n".format(repo, issue, title, url))

def gh_get_issue_output(org, repo, issuenum):
    """
    Look up PR information using the GitHub api
    """
    # Attempt to look up the PR, and don't take down the whole
    # shebang if a API call fails
    # This will fail often on forks who don't have the
    # PRs numbers associated with the forked account
    # Return empty string on error
    try:
        repoObj = gh.get_repo(org + "/" + repo)
        issue = repoObj.get_issue(int(issuenum))
        title = issue.title
        html_url = issue.html_url
    except GithubException as e:
        print "Github error({0}): {1}".format(e.status, e.data)
        return ""
    except:
        print "Some github error"
        return ""

    return(get_formatted_issue(repo, issuenum, title, html_url))


def get_org(repourl):
    """
    Simple function to parse the organization out of a GitHub URL
    """
    dprint("Current repourl to search: " + repourl)
    # GitHub URLs can be:
    #    http[s]://www.github.com/org/repo
    # or           git@github.com:/org/repo
    pattern = re.compile(r"github.com[/:]+(\w+)/")
    m = re.search(pattern, repourl)
    # Fail fast if this is wrong so we can add a pattern to the search
    if m:
        return m.group(1)
    else:
        raise Exception("Incorrect regex pattern finding repo org")

def get_name(repourl):
    """
    Simple function to parse the repository name out of a GitHub URL
    """
    dprint("Current repourl to search: " + repourl)
    repo_pattern = re.compile(r"github.com[/:]\w+/(\w+)")
    m = re.search(repo_pattern, repourl)
    if m:
        return m.group(1)
    else:
        raise Exception("Incorrect rexex pattern finding repo url")

def get_repo_url_from_remote():
    """
    Function that gets the repository URL from the `git remote` listing
    """
    git_remote_bytes = subprocess.check_output(["git", "remote", "-v"])
    # check_output returns the command results in raw byte format
    remote_string = git_remote_bytes.decode('utf-8')

    pattern = re.compile(r"github.com[/:]\w+/\w+")
    m = re.search(pattern, remote_string)
    if m:
        return m.group(0)
    else:
        raise Exception("Incorrect rexex pattern finding repo url")

def process_log(gitlog, repo_url):
    """
    Handles the processing of the gitlog and returns a list
    of PRs already formatted for output
    """
    pr_list = search_prs(gitlog)
    repoorg = get_org(repo_url)
    reponame = get_name(repo_url)
    pr_buffer = []
    for issue in pr_list:
            pr_buffer.append(gh_get_issue_output(repoorg, reponame, issue))

    return pr_buffer

def fetch_log(old_ver, new_ver):
    """
    Function that processes the git log between the old and new versions
    """
    dprint("Current working directory", os.getcwd())
    gitlogbytes = subprocess.check_output(["git", "log",
                                           str(old_ver + ".." + new_ver)])
    return gitlogbytes.decode('utf-8')


def compare_versions(repo_url, old_ver, new_ver):
    # Formatted list of all PRs for all repos
    pr_out = []
    gitlog = fetch_log(old_ver, new_ver)
    pr_out.extend(process_log(gitlog, repo_url))
    return pr_out

def main():
    args = get_args()

    # Setup the GitHub object for later use
    global gh
    gh = Github(get_env("GHAUTH"))

    if gh == "":
        raise Exception("Env var GHAUTH must be set to a valid GitHub API key")

    if args.verbose:
        global VERBOSE
        VERBOSE=True

    dprint("Inspecting difference in between: ", args.old, " and ", args.new)

    # Find the github URL of the repo we are operating on
    repo_url = get_repo_url_from_remote()

    # Compare old and new versions
    pr_list = compare_versions(repo_url, args.old, args.new)

    # Writeout PR listing
    print "Writing output to file %s" % args.file
    with open(args.file, 'w') as output:
        output.writelines(pr_list)


if __name__ == "__main__":
    VERBOSE=False
    gh=None
    topdir=os.getcwd()
    main()
