#!/usr/bin/env python

import argparse
import sys

sys.dont_write_bytecode = True

import testinfra

def main():
    parser = argparse.ArgumentParser(description='Manually trigger CI Robots')
    parser.add_argument('-f', '--force', action="store_true",
                        help='Force setting the status even if the program logic thinks it shouldn''t be done')
    parser.add_argument('pull', help='The pull request to trigger')
    parser.add_argument('context', nargs='?', help='The github task context to trigger')
    opts = parser.parse_args()

    github = testinfra.GitHub()

    pull = github.get("pulls/" + opts.pull)

    # triggering is manual, so don't prevent triggering a user that isn't on the whitelist
    # but issue a warning in case of an oversight
    login = pull["head"]["user"]["login"]
    if login not in github.whitelist:
        sys.stderr.write("warning: pull request author '{0}' isn't in github-whitelist.\n".format(login))

    revision = pull['head']['sha']
    statuses = github.statuses(revision)
    if opts.context:
        contexts = [ opts.context ]
        all = False
    else:
        contexts = list(set(statuses.keys()) & set(testinfra.DEFAULT_VERIFY.keys()))
        all = True

    ret = 0
    for context in contexts:
        status = statuses.get(context, { })
        if status.get("state", all and "unknown" or "empty") not in ["empty", "error", "failure"]:
            if not opts.force:
                if not all:
                    sys.stderr.write("{0}: isn't in triggerable state: {1}\n".format(context, status["state"]))
                    ret = 1
                continue
        sys.stderr.write("{0}: triggering on pull request {1}\n".format(context, opts.pull))
        changes = { "state": "pending", "description": testinfra.NOT_TESTED, "context": context }
        github.post("statuses/" + revision, changes)

    return ret

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