'''
   @file pipeline.py
   @author Douglas Applegate
   @date 9/26/07

   Provides a framework for autorecovery, and rerunning, of parts of the 
   pipeline
'''

__cvs_id__ = "$Id: pipeline.py,v 1.1 2008-01-17 19:12:38 dapple Exp $"

################

import logging
from decorator import decorator

log = logging.getLogger('shearpipeline.pipeline')


#################################################################

class Pipeline(object):

    def __init__(self):
        self.storage = None
        self.resume = None

    #########################

    def __getitem__(self,key):
        return self.storage[key]

    ##########################

    def __setitem__(self,key,value):
        self.storage[key] = value

    ##########################

    def run(self, storage = None, resume = None,
                    *args, **keywords):

        if storage is not None:
            self.storage = storage
        elif self.storage is None:
            self.storage = {}
        self.resume = resume
        return self._run(*args, **keywords)


#########################################

@decorator
def branchingsavepoint(f, *args, **kw):
    
    self = args[0]
    f_name = f.__name__
    if self.resume == f_name:
        self.resume = None

    log.log(20, 'Entering %s...' % f_name)

    isTrue = f(*args,**kw)
    
    log.log(20, 'Returning %s' % str(isTrue))
    
    return isTrue
    

#########################################

@decorator
def savepoint(f, *args, **kw):
    '''To be applied to instance methods of a class.'''

    self = args[0]
    f_name = f.__name__
    if self.resume is None or \
            self.resume == f_name:
        self.resume = None

        log.log(20, 'Entering %s...' % f_name)
        
        f(*args,**kw)
            
        log.log(20,'Done.')

    else:
        log.log(20, '%s already complete. Skipping.' % f_name)


#########################################
        

def runPipeline(pipeline, storage = None, resume = None, method = 'run',
                **keywords):

    storage.update(keywords)

    pipeline.storage = storage
    pipeline.resume = resume
    
    getattr(pipeline, method)()

    
###############################################################
##############################################################
#TESTING
#################



import unittest