#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2019 tribe29 GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

# NOTE: Careful when replacing the *-import below with a more specific import. This can cause
# problems because it might remove variables from the check-context which are necessary for
# resolving legacy discovery results such as [("SUMMARY", "diskstat_default_levels")]. Furthermore,
# it might also remove variables needed for accessing discovery rulesets.
from cmk.base.check_legacy_includes.cmctc import *  # pylint: disable=wildcard-import,unused-wildcard-import

# .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", " °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", " °C", "temp"),
            "22": ("Setpoint temperature monitoring RTT", " °C", "temp"),
            "23": ("Power output 20A", " A", "current"),
            "24": ("Door magnet automatic door release", "", None),
            "30": ("Control mode", "", None),
            "31": ("Min fan speed", " RPM", "rpm"),
            "32": ("Min delta T", " °C", "temp"),
            "33": ("Max delta T", " °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", " °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
        ],
    ),
}
