#!/usr/bin/python

"""Validate and add a new item to the Invirt build queue.

This script, intended to be invoked by remctl, first validates the
build submitted parameters, and then adds a new item to the
Invirtibuilder build queue, triggering the Invirtibuilder to start the
build.

The expected arguments are

  pocket package commit

This script will also automatically extract the Kerberos principal
used to submit the job, and include that in the queue file for records
keeping.
"""


import datetime
import optparse
import os
import sys
import tempfile
import uuid

from invirt.config import structs as config
import invirt.common as c
import invirt.builder as b


def main():
    parser = optparse.OptionParser('Usage: %prog pocket package commit')
    opts, args = parser.parse_args()
    if len(args) != 3:
        parser.print_help()
        return 1
    pocket, package, commit = args
    principal = os.environ['REMOTE_USER']
    request_time = datetime.datetime.utcnow()
    q_path = os.path.join(b._QUEUE_DIR,
                          '%s_%s' % (request_time.strftime('%Y%m%d%H%M%S'),
                                     uuid.uuid4()))

    try:
        # TODO: clean up this interface.
        b.ensureValidPackage(package)
        if config.build.get('mirror'):
            c.captureOutput(['git', 'fetch'], cwd=b.getRepo(package))
        commit = b.canonicalize_commit(package, commit)
        b.validateBuild(pocket, package, commit)
    except b.InvalidBuild, e:
        msg = "E: %s" % e
        print >>sys.stderr, msg
        # Prevent an attack by submitting excessively long arguments
        args = [arg[:min(len(arg), 80)] for arg in (pocket, package, commit)]
        b.runHook('failed-submit', args + [principal], stdin_str=msg)
        sys.exit(1)

    # To keep from triggering the Invirtibuilder before we've actually
    # written the file out, first write the queue entry to a temporary
    # file, and then move it into the queue directory.
    q_fd, q_name = tempfile.mkstemp()
    q = os.fdopen(q_fd, 'r+')
    print >>q, "%s %s %s %s" % (pocket, package, commit, principal)
    q.close()
    os.rename(q_name, q_path)
    short_commit = b.canonicalize_commit(package, commit, shorten=True)
    b.runHook('post-submit', [pocket, package, short_commit, principal])
    print '%s, your job to build %s for %s:%s has been submitted!' % (principal, short_commit, package, pocket)


if __name__ == '__main__':
    main()