#! /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' ) )

from string import ascii_uppercase
import glob
from Mobyle.MobyleLogger import MLogger
MLogger()

from Mobyle.JobFacade import JobFacade
from Mobyle.MobyleError import MobyleError
from Mobyle.ConfigManager import Config
from Mobyle.Job import path2url

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 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 = os.path.realpath( admins[0] )
                    job_path = os.path.dirname( adminPath )
                    
                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:
                job_id = path2url( job_path )
                job_name = job_path.split( os.path.sep )[-2 ]
                job_facade = JobFacade.getFromJobId( job_id )
            except MobyleError , err :
                errors.append( ( key , "invalid key" ) )
                continue
            
            if job_id is None:
                # an error occured on this jobID but I continue to kill the other jobIDs
                errors.append( ( "%s/%s"%( job_name, key) , 'no jobID for this job' ) )
                continue
            try:
                
                try:
                    job_facade.killJob()
                except Exception , err :
                    errors.append( ( "%s/%s"%( job_name, key) , str( err )  ) )
                    continue
                    
            except MobyleError , err :
                errors.append( ( "%s/%s"%( job_name, key) , 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 )
