#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# |             ____ _               _        __  __ _  __           |
# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
# |                                                                  |
# | Copyright Mathias Kettner 2014             mk@mathias-kettner.de |
# +------------------------------------------------------------------+
#
# This file is part of Check_MK.
# The official homepage is at http://mathias-kettner.de/check_mk.
#
# check_mk 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 in version 2.  check_mk is  distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY;  with-
# out even the implied warranty of  MERCHANTABILITY  or  FITNESS FOR A
# PARTICULAR PURPOSE. See the  GNU General Public License for more de-
# tails. You should have  received  a copy of the  GNU  General Public
# License along with GNU Make; see the file  COPYING.  If  not,  write
# to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
# Boston, MA 02110-1301 USA.

isc_dhcpd_default_levels = (15.0, 5.0)


# Example output from agent:
# <<<isc_dhcpd>>>
# [general]
# PID: 3670
# [pools]
# 10.0.1.1 10.0.1.254
# [leases]
# 10.0.1.16
# 10.0.1.24
# 10.0.1.26
# 10.0.1.27
# 10.0.1.34
# 10.0.1.36
# 10.0.1.45
# 10.0.1.50
# 10.0.1.53
# 10.0.1.57


def parse_isc_dhcpd(info):
    def ip_to_number(ip):
        number = 0
        factor = 1
        for part in ip.split('.')[::-1]:
            number += factor * int(part)
            factor *= 256
        return number

    parsed = {
        "pids":   [],
        "pools":  {},
        "leases": [],
    }

    mode = None
    for line in info:
        if line[0] == '[general]':
            mode = "general"
        elif line[0] == '[pools]':
            mode = "pools"
        elif line[0] == '[leases]':
            mode = "leases"

        elif mode == "general":
            if line[0] == "PID:":
                parsed["pids"] = map(int, line[1:])

        elif mode == "pools":
            if 'bootp' in line[0]:
                line = line[1:]
            start, end = line[0], line[1]
            item = "%s-%s" % (start, end)
            parsed["pools"][item] = (ip_to_number(start), ip_to_number(end))

        elif mode == "leases":
            parsed["leases"].append(ip_to_number(line[0]))

    return parsed


def inventory_isc_dhcpd(parsed):
    return [(item, "isc_dhcpd_default_levels") for item in parsed["pools"]]


def check_isc_dhcpd(item, params, parsed):
    if len(parsed["pids"]) == 0:
        yield 2, "DHCP Daemon not running"
    elif len(parsed["pids"]) > 1:
        yield 1, "DHCP Daemon running %d times (PIDs: %s)" % (
            len(parsed["pids"]), ", ".join(map(str, parsed["pids"])))

    if item not in parsed["pools"]:
        return

    range_from, range_to = parsed["pools"][item]
    num_leases = range_to - range_from + 1
    num_used = 0
    for lease_dec in parsed["leases"]:
        if lease_dec >= range_from and lease_dec <= range_to:
            num_used += 1

    for check_result in check_dhcp_pools_levels(num_leases - num_used, num_used, None, num_leases, params):
        yield check_result


check_info["isc_dhcpd"] = {
    'parse_function':          parse_isc_dhcpd,
    'inventory_function':      inventory_isc_dhcpd,
    'check_function':          check_isc_dhcpd,
    'service_description':     'DHCP Pool %s',
    'group':                   'win_dhcp_pools',
    'has_perfdata':            True,
    'includes':                ["dhcp_pools.include"],
}
