#!/usr/bin/env python
# -*- coding: utf-8 -*-

############################################################################
#    Copyright (C) 2011 by Michael Goerz                                   #
#    http://michaelgoerz.net                                               #
#                                                                          #
#    This program is free software; you can redistribute it and/or modify  #
#    it under the terms of the GNU General Public License as published by  #
#    the Free Software Foundation; either version 3 of the License, or     #
#    (at your option) any later version.                                   #
#                                                                          #
#    This program is distributed in the hope that it will be useful,       #
#    but WITHOut ANY WARRANTY; without even the implied warranty of        #
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         #
#    GNU General Public License for more details.                          #
#                                                                          #
#    You should have received a copy of the GNU General Public License     #
#    along with this program; if not, write to the                         #
#    Free Software Foundation, Inc.,                                       #
#    59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             #
############################################################################

"""
Delete one or more jobs.

The lqdel command accepts one or more job_identifier operands of the form
"sequence_number[.server_name][@server]" or 'all'.

Each batch job being deleted will be sent a SIGTERM signal following
by a SIGKILL signal
"""

import os
import os.path
import sys
import logging
import signal
import time
from glob import glob
from optparse import OptionParser
from LPBS.Config import get_config, verify_lpbs_home
from LPBS.JobUtils import send_sig_to_job_id, pid_for_job_id



def main(argv=None):
    """ Main Program """
    if argv is None:
        argv = sys.argv
    arg_parser = OptionParser(
    usage = "usage: %prog [options] <job_identifier>",
    description = __doc__)
    arg_parser.add_option(
      '--debug', action='store_true', dest='debug',
      default=False, help="Set logging to debug level")
    arg_parser.add_option(
      '--config', action='store', dest='config', help="Config file to "
      "use, on top of $LPBS_HOME/lpbs.cfg and $HOME/.lpbs.cfg")
    arg_parser.add_option(
      '-w', action='store', dest='delay', default='30',
      help="Specify the wait delay between the sending of the SIGTERM and "
      "SIGKILL signals. The argument is the length of time in seconds of the "
      "delay.")
    options, args = arg_parser.parse_args(argv)
    if (verify_lpbs_home() != 0):
        return 1
    options.config = get_config(options.config)
    if options.debug:
        logging.basicConfig(filename=os.path.join(os.environ['LPBS_HOME'],
        options.config.get('LPBS', 'logfile')),
        format='%(asctime)s %(funcName)s-%(levelname)s: %(message)s',
        datefmt='%m/%d/%Y %H:%M:%S %z', level=logging.DEBUG)
    else:
        logging.basicConfig(filename=os.path.join(os.environ['LPBS_HOME'],
        options.config.get('LPBS', 'logfile')),
        format='%(asctime)s: %(message)s', datefmt='%m/%d/%Y %H:%M:%S %z',
        level=logging.INFO)
    if options.config is None:
        return 1
    logging.debug("lqdel for args: %s", ', '.join(args[1:]))
    for arg in args[1:]:
        if arg == 'all':
            lock_files = glob(os.path.join(os.environ['LPBS_HOME'], '*.lock'))
            for lock_file in lock_files:
                send_sig_to_job_id(os.path.basename(lock_file))
                time.sleep(float(options.delay))
                send_sig_to_job_id(os.path.basename(lock_file),
                                   sig=signal.SIGKILL)
            break
        else:
            try:
                pgid = os.getpgid(int(pid_for_job_id(arg)))
            except ValueError:
                pass
            send_sig_to_job_id(arg, signal.SIGTERM)
            newpid = os.fork()
            if newpid == 0:
                time.sleep(float(options.delay))
                try:
                    os.killpg(pgid, signal.SIGKILL)
                except OSError:
                    pass
    return 0


if __name__ == "__main__":
    sys.exit(main())

