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


def parse_fritz(info):
    return {l[0]: ' '.join(l[1:]) for l in info if len(l) > 1}


check_info["fritz"] = {
    'parse_function': parse_fritz,
}


#
# Internet connection
#
def inventory_fritz_conn(parsed):
    conn_stat = parsed.get('NewConnectionStatus')
    if (conn_stat and conn_stat != 'Unconfigured' and 'NewExternalIPAddress' in parsed):
        return [(None, {})]


def check_fritz_conn(_unused, _no_params, parsed):

    conn_stat = parsed.get('NewConnectionStatus')
    yield 0, 'Status: %s' % conn_stat

    if conn_stat not in ('Connected', 'Connecting', 'Disconnected', 'Unconfigured'):
        yield 3, 'unhandled connection status'

    if conn_stat == 'Connected':
        yield 0, 'WAN IP Address: %s' % parsed.get('NewExternalIPAddress')
    else:
        yield 1, ''

    last_err = parsed.get('NewLastConnectionError')
    if last_err and last_err != 'ERROR_NONE':
        yield 0, 'Last Error: %s' % last_err

    uptime = parsed.get('NewUptime')
    if uptime:
        conn_time = check_uptime_seconds({}, float(uptime))
        yield 0, str(conn_time[1]), conn_time[2]


check_info['fritz.conn'] = {
    "inventory_function": inventory_fritz_conn,
    "check_function": check_fritz_conn,
    "service_description": "Connection",
    "includes": ["uptime.include"],
    "has_perfdata": True,
}


#
# Config
#
def inventory_fritz_config(parsed):
    if 'NewDNSServer1' in parsed:
        return [(None, {})]


def check_fritz_config(_unused, _no_params, parsed):

    label_val = [
        ('Auto Disconnect Time', parsed.get('NewAutoDisconnectTime', '0.0.0.0')),
        ('DNS-Server1', parsed.get('NewDNSServer1', '0.0.0.0')),
        ('DNS-Server2', parsed.get('NewDNSServer2', '0.0.0.0')),
        ('VoIP-DNS-Server1', parsed.get('NewVoipDNSServer1', '0.0.0.0')),
        ('VoIP-DNS-Server2', parsed.get('NewVoipDNSServer2', '0.0.0.0')),
        ('uPnP Config Enabled', parsed.get('NewUpnpControlEnabled', '0.0.0.0')),
    ]

    output = ['%s: %s' % (l, v) for l, v in label_val if v != '0.0.0.0']

    if output:
        return 0, ', '.join(output)
    return 3, 'Configuration info is missing'


check_info['fritz.config'] = {
    "inventory_function": inventory_fritz_config,
    "check_function": check_fritz_config,
    "service_description": "Configuration",
}


#
# WAN Interface Check
#
def fritz_wan_if_to_if64(parsed):
    link_stat = parsed.get('NewLinkStatus')
    if not link_stat:
        oper_status = None
    elif link_stat == 'Up':
        oper_status = '1'
    else:
        oper_status = '2'

    return [
        # ifIndex, ifDescr, ifType, ifSpeed, ifOperStatus,
        # ifInOctets,  inucast,  inmcast,  inbcast,  ifInDiscards,  ifInErrors,
        # ifOutOctets, outucast, outmcast, outbcast, ifOutDiscards, ifOutErrors,
        # ifOutQLen, ifAlias, ifPhysAddress
        ('0', 'WAN', '6', parsed.get('NewLayer1DownstreamMaxBitRate'), oper_status,
         parsed.get('NewTotalBytesReceived'), '0', '0', '0', '0', '0',
         parsed.get('NewTotalBytesSent'), '0', '0', '0', '0', '0', '0', 'WAN', '')
    ]


def inventory_fritz_wan_if(parsed):
    return inventory_if_common(fritz_wan_if_to_if64(parsed))


def check_fritz_wan_if(item, params, parsed):
    if not parsed:
        return 3, 'Interface info is missing'

    if_common_params = {
        'assumed_speed_in': int(parsed['NewLayer1DownstreamMaxBitRate']),
        'assumed_speed_out': int(parsed['NewLayer1UpstreamMaxBitRate']),
        'unit': 'bit',
    }
    if_common_params.update(params)

    return check_if_common(item, if_common_params, fritz_wan_if_to_if64(parsed))


check_info["fritz.wan_if"] = {
    'check_function': check_fritz_wan_if,
    'inventory_function': inventory_fritz_wan_if,
    'service_description': 'Interface %s',
    'has_perfdata': True,
    'group': 'if',
    'default_levels_variable': 'if_default_levels',
    'includes': ['if.include'],
}


#
# Link
#
def inventory_fritz_link(parsed):
    if 'NewLinkStatus' in parsed and 'NewPhysicalLinkStatus' in parsed:
        return [(None, {})]


def check_fritz_link(_no_item, _no_params, parsed):

    label_val = [
        ('Link Status', parsed.get('NewLinkStatus')),
        ('Physical Link Status', parsed.get('NewPhysicalLinkStatus')),
        ('Link Type', parsed.get('NewLinkType')),
        ('WAN Access Type', parsed.get('NewWANAccessType')),
    ]

    output = ['%s: %s' % (l, v) for l, v in label_val if v]

    if output:
        return 0, ', '.join(output)
    return 3, 'Link info is missing'


check_info["fritz.link"] = {
    'check_function': check_fritz_link,
    'inventory_function': inventory_fritz_link,
    'service_description': 'Link Info',
}
