#! /usr/bin/python3
import sys

from dcache_nagios_plugins.urlopen import urlopen
from getopt import gnu_getopt, GetoptError
from xml import sax

info_url = None
info_cert = None
info_certkey = None

class DoorCounter(sax.handler.ContentHandler):

    def __init__(self, domain_name, door_name):
        self._filter_prefix = door_name + '-'
        self._domain_name = domain_name
        self._door_name = door_name
        self.found_domain = False
        self.found_door = False
        self.match_count = 0

    def startElement(self, name, attrs):
        if name == 'domain':
            if attrs['name'] == self._domain_name:
                self.found_domain = True
        elif name == 'cell':
            cell_name = attrs['name']
            if cell_name == self._door_name:
                self.found_door = True
            elif cell_name.startswith(self._filter_prefix):
                self.match_count += 1

def count_slammed_doors(domain_name, door_name):
    url = '%s/domains/%s/cells' % (info_url, domain_name)
    fh = urlopen(url, certkey = info_certkey, cert = info_cert)
    handler = DoorCounter(domain_name, door_name)
    sax.parse(fh, handler)
    fh.close()
    return handler, url

def check(domain_name, door_name, warn_limit, crit_limit):
    res, url = count_slammed_doors(domain_name, door_name)
    if not res.found_domain:
        print('Did not find %s in result.' % domain_name)
        nagios_status = 3
    elif not res.found_door:
        print('Did not find %s in result.' % door_name)
        nagios_status = 3
    else:
        print('%d cells matches %s-*|doorslam=%d;%d;%d;0;'
              % (res.match_count, door_name,
                 res.match_count, warn_limit, crit_limit))
        if res.match_count > crit_limit:
            nagios_status = 2
        elif res.match_count > warn_limit:
            nagios_status = 1
        else:
            nagios_status = 0
    print('Source URL: %s' % url)
    print('Limits: warning from %d, critical from %d' % (warn_limit, crit_limit))
    sys.exit(nagios_status)

def main():
    global info_url
    global info_cert
    global info_certkey
    domain_name = None
    door_name = None
    warn_limit = 500
    crit_limit = 750
    try:
        opts, args = gnu_getopt(sys.argv[1:], 'w:c:U:K:C:', ['domain=', 'door='])
        for opt, arg in opts:
            if opt == '-U':
                info_url = arg
            elif opt == '-C':
                info_cert = arg
            elif opt == '-K':
                info_certkey = arg
            elif opt == '--domain':
                domain_name = arg
            elif opt == '--door':
                door_name = arg
            elif opt == '-w':
                warn_limit = int(arg)
            elif opt == '-c':
                crit_limit = int(arg)
            else:
                assert False
        if info_url is None:
            raise GetoptError('The -U option is requried.')
        if domain_name is None:
            raise GetoptError('The --domain option is required.')
        if door_name is None:
            raise GetoptError('The --door option is required.')
    except GetoptError as exn:
        sys.stderr.write('%s\n' % exn)
        sys.exit(64)

    check(domain_name, door_name, warn_limit, crit_limit)

main()
