#!/usr/bin/env python

"""
Update the status of a GitHub commit.
"""

import sys
import requests
import json
from textwrap import dedent

# The Ansible script will fill in the GitHub OAuth token.
# That way, we can give the jenkins user on the worker
# execute-only access to this script, ensuring that
# the jenkins user cannot retrieve the token.
GITHUB_OAUTH_TOKEN = "{{ github_oauth_token }}"

USAGE = "Usage: {0} ORG REPO SHA STATUS TARGET_URL DESCRIPTION"

VALID_STATUS_LIST = ['pending', 'success', 'error', 'failure']


def parse_args(arg_list):
    """
    Parse the list of arguments, returning a dict.
    Prints an error message and exits if the arguments are invalid.
    """
    if len(arg_list) != 7:
        print USAGE.format(arg_list[0])
        exit(1)

    # Check that the build status is valid
    status = arg_list[4]
    if not status in VALID_STATUS_LIST:
        print "Invalid status: must be one of {0}".format(", ".join(VALID_STATUS_LIST))
        exit(1)

    return {
        'org': arg_list[1],
        'repo': arg_list[2],
        'sha': arg_list[3],
        'status': arg_list[4],
        'target_url': arg_list[5],
        'description': arg_list[6]
    }


def post_status(org, repo, sha, status, target_url, description):
    """
    Post a new status to GitHub.
    See http://developer.github.com/v3/repos/statuses/ for details.

    Prints an error message and exits if unsuccessful.
    """
    url = "https://api.github.com/repos/{0}/{1}/statuses/{2}?access_token={3}".format(
        org, repo, sha, GITHUB_OAUTH_TOKEN
    )

    params = {
        'state': status,
        'target_url': target_url,
        'description': description
    }

    response = requests.post(url, data=json.dumps(params))

    if response.status_code != 201:
        print dedent("""
            Could not post status:
            HTTP response code is {0}
            Content: {1}
        """).format(response.status_code, response.text).strip()
        exit(1)


def main():
    """
    Post the status to GitHub.
    """
    if not GITHUB_OAUTH_TOKEN:
        print "No GitHub Oauth token configured."
        exit(1)

    arg_dict = parse_args(sys.argv)
    post_status(
        arg_dict['org'], arg_dict['repo'],
        arg_dict['sha'], arg_dict['status'],
        arg_dict['target_url'], arg_dict['description']
    )


if __name__ == "__main__":
    main()
