'''
A conveniance system to manage jobs, both active and already run
'''

# Import Python Modules
import os

# Import Salt Modules
import salt.client
import salt.payload
import salt.utils
from salt.exceptions import SaltException

# Import Third party libs
import yaml

def active():
    '''
    Return a report on all actively running jobs from a job id centric
    perspective
    '''
    ret = {}
    job_dir = os.path.join(__opts__['cachedir'], 'jobs')
    client = salt.client.LocalClient(__opts__['conf_file'])
    active = client.cmd('*', 'saltutil.running', timeout=1)
    for minion, data in active.items():
        if not isinstance(data, tuple):
            continue
        for job in data:
            if not job['jid'] in ret:
                ret[job['jid']] = {'Running': [],
                                   'Returned': [],
                                   'Function': job['fun'],
                                   'Arguments': list(job['arg']),
                                   'Target': job['tgt'],
                                   'Target-type': job['tgt_type']}
            else:
                ret[job['jid']]['Running'].append({minion: job['pid']})
    if os.path.isdir(job_dir):
        for jid in os.listdir(job_dir):
            if not jid in ret:
                continue
            jid_dir = os.path.join(job_dir, jid)
            if not os.path.isdir(jid_dir):
                continue
            for minion in os.listdir(jid_dir):
                if minion.startswith('.'):
                    continue
                if os.path.exists(os.path.join(jid_dir, minion)):
                    ret[jid]['Returned'].append(minion)
    print yaml.dump(ret)


def lookup_jid(jid):
    '''
    Return the printout from a previousely executed job
    '''

    out = None

    def _format_ret(full_ret):
        '''
        Take the full return data and format it to simple output
        '''
        ret = {}
        for key, data in full_ret.items():
            ret[key] = data['ret']
            if 'out' in data:
                out = data['out']
            return ret, out

    client = salt.client.LocalClient(__opts__['conf_file'])
    full_ret = client.get_full_returns(jid, [], 0)
    formatted = _format_ret(full_ret)

    if formatted:
        ret = formatted[0]
        out = formatted[1]
    else:
        ret = SaltException('Job {0} hasn\'t finished. No data yet :('.format(jid))
        out = ''

    # Determine the proper output method and run it
    get_outputter = salt.output.get_outputter
    if isinstance(ret, (list, dict, basestring)) and out:
        printout = get_outputter(out)
    # Pretty print any salt exceptions
    elif isinstance(ret, SaltException):
        printout = get_outputter("txt")
    else:
        printout = get_outputter(None)
    printout(ret)
    return ret

def list_jobs():
    '''
    List all detectable jobs and associated functions
    '''
    serial = salt.payload.Serial(__opts__)
    ret = {}
    job_dir = os.path.join(__opts__['cachedir'], 'jobs')
    for jid in os.listdir(job_dir):
        loadpath = os.path.join(job_dir, jid, '.load.p')
        if not os.path.isfile(loadpath):
            continue
        load = serial.load(open(loadpath, 'rb'))
        ret[jid] = {'Start Time': salt.utils.jid_to_time(jid),
                    'Function': load['fun'],
                    'Arguments': list(load['arg']),
                    'Target': load['tgt'],
                    'Target-type': load['tgt_type']}
    print yaml.dump(ret)


@@ -520,16 +520,17 @@
   active
+_
  = clien
@@ -601,16 +601,17 @@
 n active
+_
 .items()
@@ -648,13 +648,12 @@
 ta, 
-tuple
+list
 ):%0A 
@@ -1183,75 +1183,63 @@
     
-if os.path.isdir(job_dir):%0A        for jid in os.listdir(job
+for jid in ret:%0A        jid_dir = salt.utils.jid
 _dir
-):%0A
+(%0A 
     
@@ -1250,105 +1250,110 @@
     
-if not jid in ret:%0A                continue%0A            jid_dir = os.path.join(job_dir, jid)%0A    
+   jid,%0A                __opts__%5B'cachedir'%5D,%0A                __opts__%5B'hash_type'%5D%0A                )%0A
     
@@ -1391,36 +1391,32 @@
 r):%0A            
-  
-  
 continue%0A       
@@ -1400,36 +1400,32 @@
        continue%0A
-    
         for mini
@@ -1463,20 +1463,16 @@
         
-    
 if minio
@@ -1498,36 +1498,32 @@
                 
- 
-   
 continue%0A       
@@ -1511,28 +1511,24 @@
    continue%0A
-    
             
@@ -1577,20 +1577,16 @@
 nion)):%0A
-    
         

update jobs.active to support new hashed jobs