#!/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.

# Example outputs from agent:
#
# <<<win_dhcp_pools>>>
#
# MIB-Anzahl:
#     Entdeckungen = 0.
#     Angebote = 0.
#     Anforderungen = 0.
#     Acks = 0.
#     Naks = 0.
#     Abweisungen = 0.
#     Freigaben = 0.
#     ServerStartTime = Dienstag, 29. Juni 2010 19:08:55
#     Bereiche = 1.
#     Subnetz = 192.168.123.0.
#         Anzahl der verwendeten Adressen = 0.
#         Anzahl der freien Adressen = 239.
#         Anzahl der anstehenden Angebote = 0.
#
# MIBCounts:
#         Discovers = 0.
#         Offers = 0.
#         Requests = 0.
#         Acks = 1.
#         Naks = 0.
#         Declines = 0.
#         Releases = 0.
#         ServerStartTime = Sunday, May 25, 2008 12:38:06 PM
#         Scopes = 1.
#         Subnet = 172.16.11.0.
#                 No. of Addresses in use = 1.
#                 No. of free Addresses = 23.
#                 No. of pending offers = 0.

#   .--Pools---------------------------------------------------------------.
#   |                       ____             _                             |
#   |                      |  _ \ ___   ___ | |___                         |
#   |                      | |_) / _ \ / _ \| / __|                        |
#   |                      |  __/ (_) | (_) | \__ \                        |
#   |                      |_|   \___/ \___/|_|___/                        |
#   |                                                                      |
#   '----------------------------------------------------------------------'

win_dhcp_pools_default_levels = (10, 5)
win_dhcp_pools_inventorize_empty = False
discovery_win_dhcp_pools = []

win_dhcp_pools_stats_translate = {
    'Entdeckungen': 'Discovers',
    'Angebote': 'Offers',
    'Anforderungen': 'Requests',
    'Acks': 'Acks',
    'Naks': 'Nacks',
    'Abweisungen': 'Declines',
    'Freigaben': 'Releases',
    'Subnetz': 'Subnet',
    'Bereiche': 'Scopes',
    'Anzahl der verwendeten Adressen': 'No. of Addresses in use',
    'Anzahl der freien Adressen': 'No. of free Addresses',
    'Anzahl der anstehenden Angebote': 'No. of pending offers',
}

def parse_win_dhcp_pools(info):
    return [ ' '.join(line).rstrip('.').split(' = ') for line in info ]

def inventory_win_dhcp_pools(info):
    settings = host_extra_conf_merged(g_hostname, discovery_win_dhcp_pools)
    discover_empty = settings.get("empty_pools", win_dhcp_pools_inventorize_empty)

    inventory = []
    in_block = False
    last_pool = ""
    pool_stats = []
    for line in parse_win_dhcp_pools(info):
        if win_dhcp_pools_stats_translate.get(line[0], line[0]) == 'Subnet':
            in_block = True
            pool_stats = []
            last_pool = line[1]
            continue
        if in_block:
            pool_stats.append(saveint(line[1]))
        if len(pool_stats) == 3:
            in_block = False
            used, free, pending = pool_stats
            size = used + free + pending
            if size > 0 or discover_empty:
                inventory.append((last_pool, 'win_dhcp_pools_default_levels'))
    return inventory

def check_win_dhcp_pools(item, params, info):
    in_block = False
    pool_stats = []
    for line in parse_win_dhcp_pools(info):
        if win_dhcp_pools_stats_translate.get(line[0], line[0]) == 'Subnet' and line[1] == item:
            in_block = True
            continue
        if in_block:
            pool_stats.append(saveint(line[1]))
        if len(pool_stats) == 3:
            break

    if len(pool_stats) == 3:
        used, free, pending = pool_stats
        size = used + free + pending

        # Catch unused pools
        if size == 0:
            yield 3, "DHCP Pool contains no IP addresses / is deactivated"
            return

        for check_result in check_dhcp_pools_levels(free, used, pending, size, params):
            yield check_result

    else:
        yield 3, 'Pool information not found'


check_info["win_dhcp_pools"] = {
    'check_function':          check_win_dhcp_pools,
    'inventory_function':      inventory_win_dhcp_pools,
    'service_description':     'DHCP Pool %s',
    'has_perfdata':            True,
    'group':                   'win_dhcp_pools',
    'includes':                ['dhcp_pools.include'],
}


#.
#   .--Pool stats----------------------------------------------------------.
#   |              ____             _       _        _                     |
#   |             |  _ \ ___   ___ | |  ___| |_ __ _| |_ ___               |
#   |             | |_) / _ \ / _ \| | / __| __/ _` | __/ __|              |
#   |             |  __/ (_) | (_) | | \__ \ || (_| | |_\__ \              |
#   |             |_|   \___/ \___/|_| |___/\__\__,_|\__|___/              |
#   |                                                                      |
#   '----------------------------------------------------------------------'

def inventory_win_dhcp_pools_stats(info):
    return [ (None, None) for line in info if line[0] != '' ]

def check_win_dhcp_pools_stats(item, params, info):
    output = ''
    perfdata = []
    this_time = int(time.time())

    for line in parse_win_dhcp_pools(info):
        if len(line) > 0:
            key = win_dhcp_pools_stats_translate.get(line[0], line[0])
            if key in [ 'Discovers', 'Offers', 'Requests', 'Acks',
                        'Nacks', 'Declines', 'Releases', 'Scopes' ]:
                value = saveint(line[1])
                per_sec = get_rate("win_dhcp_stats.%s" % key, this_time, value)
                output += '%s: %.0f/s, ' % (key, per_sec)
                perfdata.append((key, per_sec))

    if output == '':
        return (3, "Information not available")
    else:
        return 0, output.rstrip(', '), perfdata


check_info["win_dhcp_pools.stats"] = {
    'check_function':          check_win_dhcp_pools_stats,
    'inventory_function':      inventory_win_dhcp_pools_stats,
    'service_description':     'DHCP Stats',
    'has_perfdata':            True,
}
