#! /usr/bin/env python

#############################################################
#                                                           #
#   Author: Bertrand Neron                                  #
#   Organization:'Biological Software and Databases' Group, #
#                Institut Pasteur, Paris.                   #
#   Distributed under GPLv2 Licence. Please refer to the    #
#   COPYING.LIB document.                                   #
#                                                           #
#############################################################

import os, sys, getopt

MOBYLEHOME = None
if os.environ.has_key('MOBYLEHOME'):
    MOBYLEHOME = os.environ['MOBYLEHOME']
if not MOBYLEHOME:
    sys.exit('MOBYLEHOME must be defined in your environment')

if ( MOBYLEHOME ) not in sys.path:
    sys.path.append( MOBYLEHOME )
if ( os.path.join( MOBYLEHOME , 'Src' ) ) not in sys.path:    
    sys.path.append( os.path.join( MOBYLEHOME , 'Src' ) )

import string
import types
import glob

from Mobyle import RunnerChild
from Mobyle.Utils import Admin
from Mobyle.MobyleError import MobyleError
from Mobyle.ConfigManager import Config

def killJobs( keys ):
    """
    kill the job corresponding to the keys
    @param keys: the keys of the job to kill
    @type keys: list of strings
    """
    errors = []

    for key in keys:

        if len( key ) == 15  and key[0] in string.ascii_uppercase :
            try:
                int( key[1:] )
            except ValueError:
                errors.append( ( key , "invalid key" ) )
                continue
            else:
                config = Config()
                search = "%s/*.%s" %( config.admindir() , key )
                admins = glob.glob( search )
                
                if len( admins ) == 1 :
                    adminPath = admins[0]
                elif len( admins ) == 0:
                    errors.append( ( key , "no running job with key : " + key  ) )
                    continue
                else:
                    raise MobyleError , "there is more than 1 running job with the same key : " + key 
            try:
                adm = Admin( adminPath )
            except MobyleError , err :
                errors.append( ( key , "invalid key" ) )
                continue
        
            batch = adm.getBatch()
            jobNum = adm.getNumber()
            job = adm.getJobName() + "/" + key 
            
            if jobNum is None:
                # an error occured on this jobID but I continue to kill the other jobIDs
                errors.append( ( job , 'no jobNum for this job' ) )
                continue

            try:
                try:
                    killer = "RunnerChild.%s.kill( '%s' )" %( batch , jobNum )
                    eval( killer )
                except ( NameError , AttributeError ) , err:
                    errors.append( ( job , "unknown batch \""+ batch +"\" " ) )
                    continue
                except Exception , err :
                    errors.append( ( job , str( err )  ) )
                    continue
                    
            except MobyleError ,err :
                errors.append( ( job , str( err ) ) )

        else: # len(key) != 15
            errors.append( ( key , "invalid key" ) )
            continue

    if errors:
        msg = ''
        for job , msgErr in errors :
            msg = "%s Mkill( %s ) - %s\n" %( msg , job , msgErr )

        raise MobyleError , msg

if __name__ == '__main__':

    def usage():
        print """
        usage: mkill jobKeys  ... 
    
        option:
            -h or --help  ... Print this message and exit.
        """

    # ===== command line parser
    try:
        opts, args = getopt.gnu_getopt( sys.argv[1:], "h", ["help"] )
    
        for option , value in opts: 
    
            if option in ( "-h","--help" ):
                usage()
                sys.exit( 0 )
    
        if not args:
            usage()
            sys.exit( 1 )
            
    except getopt.GetoptError:
            print usage()
            sys.exit( 1 )
    
    # ===== killer
    try:
        killJobs( args )
    except MobyleError , err:
        print >> sys.stderr , err
        sys.exit( 2 )
