#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# |             ____ _               _        __  __ _  __           |
# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
# |                                                                  |
# | Copyright Mathias Kettner 2017             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.

# .1.3.6.1.4.1.2606.4.2.5.6.2.1.1.1 1
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.1.2 2
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.1.3 3
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.2.1 18
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.2.2 18
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.2.3 18
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.3.1 PSM On/Off
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.3.2 PSM On/Off
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.3.3 PSM On/Off
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.4.1 6
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.4.2 6
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.4.3 6
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.5.1 1
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.5.2 1
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.5.3 1
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.6.1 2
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.6.2 2
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.6.3 2
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.7.1 1
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.7.2 1
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.7.3 1
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.8.1 0
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.8.2 0
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.8.3 0
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.9.1 1
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.9.2 1
# .1.3.6.1.4.1.2606.4.2.5.6.2.1.9.3 1


def parse_cmctc_output(info):
    def parse_output_sensor(sensor):
        type_map = {
            #ID    Type                                    Unit      Perfkey
            "4": ("Door locking TS8 Ergoform", "", None),
            "5": ("Universal lock 1 lock with power", "", None),
            "6": ("Universal lock 2 unlock with power", "", None),
            "7": ("Fan relay", "", None),
            "8": ("Fan controlled", "", None),
            "9": ("Universal relay output", "", None),
            "10": ("Room door lock", "", None),
            "11": ("Power output", "", None),
            "12": ("Door lock with Master key", "", None),
            "13": ("Door lock FR(i)", "", None),
            "14": ("Setpoint", "", None),
            "15": ("Setpoint temperature monitoring", u" °C", "temp"),
            "16": ("Hysteresis of setpoint", "", None),
            "17": ("Command for remote control of RCT", "", None),
            "18": ("Relay", "", None),
            "19": ("High setpoint current monitoring", " A", "current"),
            "20": ("Low setpoint current monitoring", " A", "current"),
            "21": ("Retpoint temperature RTT", u" °C", "temp"),
            "22": ("Setpoint temperature monitoring RTT", u" °C", "temp"),
            "23": ("Power output 20A", u" A", "current"),
            "24": ("Door magnet automatic door release", "", None),
            "30": ("Control mode", "", None),
            "31": ("Min fan speed", " RPM", "rpm"),
            "32": ("Min delta T", u" °C", "temp"),
            "33": ("Max delta T", u" °C", "temp"),
            "34": ("PID controller", "", None),
            "35": ("PID controller", "", None),
            "36": ("PID controller", "", None),
            "37": ("Flowrate flowmeter", " l/min", "flow"),
            "38": ("Cw value of water", "", ""),
            "39": ("deltaT", u" °C", "temp"),
            "40": ("Control mode", "", None),
            "42": ("Setpoint high voltage PSM", "V", "voltage"),
            "43": ("Setpoint low voltage PSM", "V", "voltage"),
            "44": ("Setpoint high current PSM", "A", "current"),
            "45": ("Setpoint low current PSM", "A", "current"),
            "46": ("Command PSM", "", None),
        }

        status_map = {
            '1': 'not available',
            '2': 'lost',
            '3': 'changed',
            '4': 'ok',
            '5': 'off',
            '6': 'on',
            '7': 'set off',
            '8': 'set on',
        }

        command_map = {
            '1': 'off',
            '2': 'on',
            '3': 'lock',
            '4': 'unlock',
            '5': 'unlock delay',
        }

        config_map = {
            '1': 'disable remote control',
            '2': 'enable remote control',
        }

        timeout_map = {
            '1': 'stay',
            '2': 'off',
            '3': 'on',
        }

        (index, sensor_type_id, description, status, value, command, config, delay,
         timeout_action) = sensor

        sensor_type, unit, perfkey = type_map.get(sensor_type_id, ("Unknown output", "", None))

        parsed = {
            'status': status_map.get(status),
            'value': int(value),
            'unit': unit,
            'perfkey': perfkey,
            'command': command_map.get(command),
            'config': config_map.get(config),
            'delay': int(delay),
            'timeout_action': timeout_map.get(timeout_action),
            'description': description
        }

        if parsed['status'] == 'not available':
            return None

        name = '%s %s' % (sensor_type, index)

        return name, parsed

    parsed = {}
    for sensor in info:
        parsed_sensor = parse_output_sensor(sensor)
        if parsed_sensor:
            name, data = parsed_sensor
            parsed[name] = data

    return parsed


def inventory_cmctc_output(parsed):
    for entry in parsed:
        yield entry, {}


def check_cmctc_output(item, params, parsed):
    sensor = parsed.get(item)

    status_map = {
        'ok': 0,
        'on': 0,
        'set off': 0,
        'set on': 0,
        'changed': 1,
        'lost': 2,
        'off': 2,
        'not available': 3,
    }

    state = status_map.get(sensor['status'], 3)
    infotext = '[%(description)s] %(value)d%(unit)s, %(status)s' % sensor
    if sensor['perfkey'] is None:
        yield state, infotext
    else:
        yield state, infotext, [(sensor['perfkey'], sensor['value'])]

    yield 0, ('Command: %(command)s, Config: %(config)s, '
              'Delay: %(delay)d, Timeout action: %(timeout_action)s') % sensor


check_info['cmctc_output'] = {
    "parse_function": parse_cmctc_output,
    "inventory_function": inventory_cmctc_output,
    "check_function": check_cmctc_output,
    "service_description": "%s",
    "has_perfdata": True,
    "snmp_scan_function": cmctc_snmp_scan_function,
    "snmp_info": (
        ".1.3.6.1.4.1.2606.4.2",  # RITTAL-CMC-TC-MIB
        [
            "3",  # cmcTcUnit1OutputTable
            "4",  # cmcTcUnit2OutputTable
            "5",  # cmcTcUnit3OutputTable
            "6",  # cmcTcUnit4OutputTable
        ],
        [
            "6.2.1.1",  # unit1OutputIndex
            "6.2.1.2",  # unit1OutputType
            "6.2.1.3",  # unit1OutputText
            "6.2.1.4",  # unit1OutputStatus
            "6.2.1.5",  # unit1OutputValue
            "6.2.1.6",  # unit1OutputSet
            "6.2.1.7",  # unit1OutputConfig
            "6.2.1.8",  # unit1OutputDelay
            "6.2.1.9",  # unit1OutputTimeoutAction
        ]),
    "includes": ["cmctc.include"],
}
