'''
    A 'Hello World' qube jobytype python backend
'''
#======================================
#  $Revision: #1 $
#  $Change: 9976 $
#======================================

import sys
import os.path
import inspect
import traceback as tb
import pprint

import qb


def jobSetup():
    ''' get the subjob object from the supervisor ''' 
    subjob = qb.jobobj()

    if bool(subjob['package'].get('dev')):
        pp = pprint.PrettyPrinter(indent=2, width=1)
        print "JOB:"
        pp.pprint(subjob)

    return subjob


def executeWork(subjob):
    subjob_status = 0

    if bool(subjob['package'].get('dev')):
        pp = pprint.PrettyPrinter(indent=2, width=1)
    else:
        pp = None

    while True:
        work_status = 1

        print 'Requesting work'
        work = qb.requestwork()

        if pp:
            print "WORK:"
            pp.pprint(work)
        
        # Deal with the minimal set of work statuses
        if work['status'] == 'complete':
            work_status = 0
            break
        elif work['status'] == 'pending':
            # preempted -- bail out
            print 'DEBUG: job %s has been preempted' % subjob['id']
            work_status = 0
            qb.reportjob('pending')
            break
        elif work['status'] == 'blocked':
            # blocked -- perhaps part of a dependency chain
            print 'job %s has been blocked' % subjob['id']
            work_status = 0
            qb.reportjob('blocked')
            break
        elif work['status'] == 'waiting':
            # waiting -- rare, come back in QB_WAITING_TIMEOUT seconds
            print 'job %s will be back in %s seconds' % (subjob['id'], self.QB_WAITING_TIMEOUT)
            time.sleep(self.QB_WAITING_TIMEOUT)
            continue

        if not work['package']:
            work['package'] = {}

        #============================================================
        #   Do the actual work 
        #============================================================
        print 'Processing work: %s' % work['name']

        testString = subjob['package']['testString']

        print '%s' % (80*'=',)
        cmd = 'echo Hello World: user %s says %s at frame %s' % (subjob['user'], testString, work['name'])
	print 'CMD: %s' % cmd
        retCode = os.system(cmd)
        print '%s%s' % (80*'=', '\n')

        if retCode > 0:
            print 'ERROR: Proccesing work failed\n'
        
        sys.stdout.flush()

        work_status = retCode

        # set the work status, then report it back to the supervisor so that it can update the server-side agenda
        if work_status == 0:
            # mark the work as complete
            work['status'] = 'complete'
        else:
            # either the work or the subjob itself has failed
            work['status'] = 'failed'
            subjob_status += 1

        # report the work status back to the supervisor
        print 'Reporting work as %(status)s: %(name)s ' % work

        qb.reportwork(work)

    return subjob_status


def executeCmd(subjob):
    subjob_status = 0
        
    if bool(subjob['package'].get('dev')):
        pp = pprint.PrettyPrinter(indent=2, width=1)
    else:
        pp = None

    #============================================================
    #   Do the actual work 
    #============================================================
    print 'Processing job: %s' % subjob['name']

    testString = subjob['package']['testString']

    print '%s' % (80*'=',)
    cmd = 'echo Hello World: user %s says %s' % (subjob['user'], testString)
    print 'CMD: %s' % cmd
    retCode = os.system(cmd)
    print '%s%s' % (80*'=', '\n')
    if retCode > 0:
        print 'ERROR: Proccesing job failed\n'
    
    sys.stdout.flush()
    subjob_status = retCode

    # set the subjob status, then report it back to the supervisor so that it can update the server-side agenda
    if subjob_status == 0:
        # mark the subjob as complete
        subjob['status'] = 'complete'
    else:
        # either the subjob or the subjob itself has failed
        subjob['status'] = 'failed'
        subjob_status += 1

    # report the work status back to the supervisor
    print 'Reporting subjob as %(status)s: %(name)s ' % subjob

    return subjob_status


def main():
    ''' '''
    # 0 indicates success
    subjobStatus = 0    

    #import pdb; pdb.set_trace()
    # get the job from the supervisor
    subjob = jobSetup()

    # if the job is agenda-based or a command-line job
    # NOTE: jobtypes are almost always one or the other, it's just this example job that can be
    # either
    if subjob['todo']:
        print 'Agenda detected, executing work...'
        subjobStatus = executeWork(subjob)
    else:
        subjobStatus = executeCmd(subjob)
        
    return subjobStatus

    

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

