#!/usr/bin/env python2
# -*- encoding: utf-8 -*-

#####################################################################
# (c) 2016 by Sven Velt, Germany                                    #
#             sven-mymonplugins@velt.biz                            #
#                                                                   #
# This file is part of "velt.biz - My Monitoring Plugins"           #
# a fork of "team(ix) Monitoring Plugins" in 2015                   #
# URL: https://gogs.velt.biz/velt.biz/MyMonPlugins/                 #
#                                                                   #
# This file 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 2 of the License, #
# or (at your option) any later version.                            #
#                                                                   #
# This file 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 file. If not, see <http://www.gnu.org/licenses/>. #
#####################################################################

import os
import re
import subprocess
import sys
import time

try:
	from monitoringplugin import MonitoringPlugin
except ImportError:
	print '=========================='
	print 'AIKS! Python import error!'
	print '==========================\n'
	print 'Could not find "monitoringplugin.py"!\n'
	print 'Did you download "%s"' % os.path.basename(sys.argv[0])
	print 'without "monitoringplugin.py"?\n'
	print 'Please go back to'
	print 'https://gogs.velt.biz/velt.biz/MyMonPlugins and download it,'
	print 'or even better:'
	print 'get a full archive at http://gogs.velt.biz/velt.biz/MyMonPlugins/releases'
	print 'or a master snapshot at http://gogs.velt.biz/velt.biz/MyMonPlugins/archive/master.tar.gz\n'
	sys.exit(127)


plugin = MonitoringPlugin(
		pluginname='check_cups',
		tagforstatusline='CUPS',
		description='Check CUPS jobs and printer queues',
		version='0.1',
	)


plugin.add_cmdlineoption('-P', '--check-printers', 'check_printers', 'check printer queue', default=False, action='store_true' )
plugin.add_cmdlineoption('-J', '--check-jobs', 'check_jobs', 'check job queue', default=False, action='store_true')
plugin.add_cmdlineoption('-w', '', 'warn', 'warning thresold for old jobs (seconds)', default='3600')
plugin.add_cmdlineoption('-c', '', 'crit', 'warning thresold for old jobs (seconds)', default='86400')

plugin.add_cmdlineoption('', '--mymonplugins-testmode', 'mymonplugins_testmode', None, default=False, action='store_true')

plugin.parse_cmdlineoptions()

##############################################################################
##### Testmode

if plugin.options.mymonplugins_testmode:
	# Because we need tzlocal from dateutil.tz
	mymonplugins_testmode = {}

	mymonplugins_testmode['lpstat -a'] = '''Printer_One accepting requests since Thu 16 Jun 2016 02:57:36 PM CEST
Printer_Two accepting requests since Thu 16 Jun 2016 02:57:36 PM CEST
Printer_Three accepting requests since Thu 16 Jun 2016 02:57:36 PM CEST
Printer_Rejecting not accepting requests since Thu 16 Jun 2016 02:57:36 PM CEST -
Rejecting Jobs'''.split('\n')

	mymonplugins_testmode['lpstat -o'] = '''Printer_One-1234 username 12345 Thu 01 Jan 1970 01:07:19 AM CET
Printer_Two-1234 username 12345 %s''' % time.strftime('%a %d %b %Y %I:%M:%S %p %Z', time.localtime())
	mymonplugins_testmode['lpstat -o'] = mymonplugins_testmode['lpstat -o'].split('\n')

##############################################################################

def check_printer_queue(output_printer_queue):
	lidx = 0
	printers = []
	printers_bad = []

	while lidx < len(output_printer_queue):
		printer =  output_printer_queue[lidx].split(' ')[0]
		if output_printer_queue[lidx].find('not accepting') > 0:
			reason = output_printer_queue[(lidx+1)].replace('\t', '').lstrip().rstrip()
			printers_bad.append( (printer, reason,) )
			lidx += 1

		printers.append( printer )
		lidx += 1

	plugin.remember_check('All Printers', 0, '%d printer%s found' % (len(printers), len(printers) != 1 and 's' or ''), perfdata=[ {'label':'printers', 'value':len(printers), 'unit':''}, ] )

	for p in printers_bad:
		plugin.remember_check('%s' % p[0], 1, p[1])


##############################################################################

def check_job_queue(output_job_queue):
	m = re.compile('(\w{3} \d\d \w{3} \d{4} \d\d:\d\d:\d\d (AM|PM) \w{3,5})')
	nowsecs = long( time.time() ) 

	jobs_warn = []
	jobs_crit = []
	for line in output_job_queue:
		plugin.verbose(3, line)
		f = m.search(line)
		if not f:
			plugin.verbose(1, 'No timestamp found in "%s"' % line)
			continue
		tstamp = time.strptime(f.group(1),  '%a %d %b %Y %I:%M:%S %p %Z')

		tsecs = long( time.mktime(tstamp) )
		age = nowsecs - tsecs
		rc = plugin.value_wc_to_returncode(age, plugin.options.warn, plugin.options.crit)
		if rc == 1:
			jobs_warn.append(line)
		elif rc == 2:
			jobs_crit.append(line)
		plugin.verbose(1, 'Job is %s seconds old, state/returncode: %s' % (age, rc))

	jobs = len(output_job_queue)
	jobs_old = len(jobs_warn) + len(jobs_crit)
	perfdata = []
	perfdata.append( { 'label':'jobs', 'value':'%d' % jobs, 'unit':'', } )
	perfdata.append( { 'label':'jobs_old', 'value':'%d' % jobs_old, 'unit':'', } )
	plugin.remember_check('Jobs', 0, '%d job%s found' % (jobs, jobs != 1 and 's' or ''), perfdata=perfdata )

	for j in jobs_crit:
		plugin.remember_check('Job %s' % j.split(' ')[0], 2, m.search(j).group(0) )
	for j in jobs_warn:
		plugin.remember_check('Job %s' % j.split(' ')[0], 1, m.search(j).group(0) )

##############################################################################

def call_cmd(cmdline):
	if plugin.options.mymonplugins_testmode:
		return (mymonplugins_testmode.get(' '.join(cmdline)), '', 0)

	myenv = dict(os.environ)
	myenv['LC_ALL'] = 'C'

	try:
		cmd = subprocess.Popen(cmdline, stdout=subprocess.PIPE, env=myenv)
		(sout, serr) = cmd.communicate()
		if sout:
			sout = sout.lstrip().rstrip().split('\n')
		else:
			sout = []
	except OSError:
		plugin.back2nagios(3, 'Could not execute "%s"' % ' '.join(cmdline))
	return (sout, serr, cmd.returncode)

##############################################################################

allchecks = not( plugin.options.check_printers or plugin.options.check_jobs )

if allchecks or plugin.options.check_printers:
	(sout, serr, retcode) = call_cmd(['lpstat', '-a'])
	check_printer_queue(sout)
if allchecks or  plugin.options.check_jobs:
	(sout, serr, retcode) = call_cmd(['lpstat', '-o'])
	check_job_queue(sout)

# Exit
plugin.brain2output()
plugin.exit()