from Queue import Queue

# Actions are represented as (name, args, kwargs)

class Action(object):
    
    name = "ActionNoName"

    def __init__(self, *args, **kwargs):
        """The __init__ function should be overridden.  You must call
           Action.__init__() in your Action class's __init__().

           This function accepts all the args and kwargs passed in
           when this Action was envoked by the calling StateObject.
        """

        pass
        

    def _run(self):
        """Check return codes to make things a little easier.  You
           should not override this function."""

        ret = self.run()
        
        if ret == None:
            # Assume success
            return (0, {})
        elif type(ret) == type(1):
            return (ret, {})
        elif type(ret) == type(()) or type(ret) == type([]):
            return ret
        
        # Don't understand what was returned
        return (-1, {'error':"Action returned unknown values."})
        
    
    def run(self):
        """Override this function to perform a specific Action.  This
           will be run directly on the client.  An Action is a very
           generic, and simplistic state change such as moving a file
           or running one command.
           
           Actions should return a tuple of (return_code, data_dict).
           The return_code must be an integer where 0 means the Action
           ran successfully.  Values > 0 are error codes.  Values
           < 0 are reserved for SE.  The data_dict must be a python
           dict containing arbitrary data used by the calling StateObject.
        """
        
        return (-2, {'error':"run() method not overridden."})


class State(object):

    name = "StateNoName"

    def __init__(r):
        r.__actionQueue = Queue()
        r.__actionRetVal = {}
        
        print "Setting up Recipe: %s" % r.name
        

    def setup(r):
        # This is what the subclasses override to make their own recipe
        
        pass
        
        
    def runAction(r, name, *args, **kwargs):
        # Queue up an Action to be run on the client ??
        # subclasses call runAction()
        
        r.__actionQueue.put((name, args, kwargs))


    def actionReturn(r, name, retVal):
        # called for each action when return value is submitted
        # retval should be a tuple (return_code, message)
        r.__actionRetVal[name] = retVal
  
    
    def getErrors(r):
        # After all actions have been returned was there an error?
        # None means Recipe was successful
        
        ret = []
        for (name, retval) in r.__actionRetVal.items():
            if retval[0] == 42:
                ret.append("Action $s returned: %s" % (name, retval[1]))
                
        return ret
        
    
    def getQueue(r):
        
        return r.__actionQueue
        
        
