#!/usr/bin/python
#
# Copyright (c) 2005-2006 rPath, Inc.
#
# All rights reserved.
#

import os, sys, time
import traceback
import xmlrpclib

from conary import versions
from conary.lib import options

class UnknownException(Exception):
    def __str__(self):
        return "%s %s" % (self.eName, self.eArgs)

    def __init__(self, eName, eArgs):
        self.eName = eName
        self.eArgs = eArgs

def usage(exitcode=1):
    sys.stderr.write("\n".join((
     "Usage: commitaction [commitaction args] ",
     "         --module '/path/to/statsaction --user <user>' --url <xmlrpc url>",
     ""
    )))
    return exitcode

class _Method(xmlrpclib._Method):
    def __repr__(self):
        return "<rBuilderAction._Method(%s, %r)>" %(self._Method__send, self._Method__name)

    def __str__(self):
        return self.__repr__()

    def __call__(self, *args):
        return self.doCall(*args)

    def doCall(self, *args):
        isException, result = self.__send(self.__name, args)
        if not isException:
            return result
        else:
            self.handleError(result)

    def handleError(self, result):
        exceptionName = result[0]
        exceptionArgs = result[1:]

        if exceptionName == "CommitError":
            raise Exception(result)
        else:
            raise UnknownException(exceptionName, exceptionArgs)

class ServerProxy(xmlrpclib.ServerProxy):
    def __getattr__(self, name):
        return _Method(self.__request, name)

def process(repos, cfg, commitList, srcMap, pkgMap, grpMap, argv, otherArgs):
    if not len(argv) and not len(otherArgs):
        return usage()
    
    argDef = {
        'url' : options.ONE_PARAM,
        'user': options.ONE_PARAM,
        'hostname': options.ONE_PARAM,
    }

    # create an argv[0] for processArgs to ignore
    argv[0:0] = ['']
    argSet, someArgs = options.processArgs(argDef, {}, cfg, usage, argv=argv)
    # and now remove argv[0] again
    argv.pop(0)
    if len(someArgs):
        someArgs.pop(0)
    otherArgs.extend(someArgs)

    pid = os.fork()
    if not pid:
        #child
        #Double fork we want the parent to return immediately so that there's no delay
        pid2 = os.fork()
        if not pid2:
            #child2
            user = argSet['user']
            url  = argSet['url']

            overrideHostname = None
            if 'hostname' in argSet:
                overrideHostname = argSet['hostname']

            for commit in commitList:
                t, vStr, f = commit

                v = versions.VersionFromString(vStr)

                if overrideHostname:
                    hostname = overrideHostname
                else:
                    hostname = v.getHost()

                rBuilderServer = ServerProxy(url)

                try:
                    rBuilderServer.registerCommit(hostname, user, t, vStr)
                except Exception, e:
                    traceback.print_exc(file = sys.stderr)
                    sys.exit(1)
            sys.exit(0)
        else:
            #parent 2
            pid2, status = os.waitpid(pid2, 0)
            if status:
                sys.stderr.write("rBuilderAction failed with code %d" % status)
            sys.exit(0)


    #parent 1
    #drive on oblivious

    return 0

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

@@ -2977,24 +2977,25 @@
         sys.
+_
 exit(1)%0A    
@@ -2998,32 +2998,33 @@
             sys.
+_
 exit(0)%0A        
@@ -3213,24 +3213,25 @@
         sys.
+_
 exit(0)%0A%0A%0A  

use _exit in fork() contexts