#!/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.elphase import *  # pylint: disable=wildcard-import,unused-wildcard-import

# Knowledge from customer:
# Devices with OID_END=38 are 12 port power switches with two powerbanks.
# Means each powerbank has 6 outlets. Here we can use ChanStatus in order
# to find out if one powerbank is enabled/used.
#
# Device with OID_END=19 is a simple switch outlet: 1 Port and 1 powerbank
# Once it's plugged in, the state is "on". Thus we use PortState in
# discovering function.

factory_settings["gude_powerbank_default_levels"] = {
    "voltage": (220, 210),
    "current": (15, 16),
}


def parse_gude_powerbanks(info):
    map_port_states = {
        "0": (2, "off"),
        "1": (0, "on"),
    }
    map_channel_states = {
        "0": (2, "data not active"),
        "1": (0, "data valid"),
    }

    ports = dict(info[0])
    parsed = {}
    for (
        oid_idx,
        dev_state,
        energy_str,
        active_power_str,
        current_str,
        volt_str,
        freq_str,
        appower_str,
    ) in info[1]:

        oid, idx = oid_idx.split(".")
        device_state = None
        if oid in ["19"]:
            device_state = map_port_states[ports[oid_idx]]
        if oid in ["38"]:
            device_state = map_channel_states[dev_state]

        if device_state is None:
            continue

        parsed.setdefault(idx, {"device_state": device_state})

        for what, key, factor in [
            (energy_str, "energy", 1.0),
            (active_power_str, "power", 1.0),
            (current_str, "current", 0.001),
            (volt_str, "voltage", 1.0),
            (freq_str, "frequency", 0.01),
            (appower_str, "appower", 1.0),
        ]:
            parsed[idx][key] = float(what) * factor

    return parsed


def inventory_gude_powerbanks(parsed):
    return [
        (powerbank, {})
        for powerbank, attrs in parsed.items()
        if attrs["device_state"][1] not in ["off", "data not active"]
    ]


check_info["gude_powerbanks"] = {
    "parse_function": parse_gude_powerbanks,
    "inventory_function": inventory_gude_powerbanks,
    "check_function": check_elphase,
    "service_description": "Powerbank %s",
    "has_perfdata": True,
    "snmp_info": [
        (
            ".1.3.6.1.4.1.28507",
            ["19", "38"],
            [
                OID_END,
                "1.3.1.2.1.3",  # GUDEADS=EPC****-MIB::epc****PortState
            ],
        ),
        (
            ".1.3.6.1.4.1.28507",
            ["19", "38"],
            [
                OID_END,
                "1.5.1.2.1.2",  # GUDEADS-EPC****-MIB::epc****ChanStatus
                "1.5.1.2.1.3",  # GUDEADS-EPC****-MIB::epc****AbsEnergyActive
                "1.5.1.2.1.4",  # GUDEADS-EPC****-MIB::epc****PowerActive
                "1.5.1.2.1.5",  # GUDEADS-EPC****-MIB::epc****Current
                "1.5.1.2.1.6",  # GUDEADS-EPC****-MIB::epc****Voltage
                "1.5.1.2.1.7",  # GUDEADS-EPC****-MIB::epc****Frequency
                "1.5.1.2.1.10",  # GUDEADS-EPC****-MIB::epc****PowerApparent
            ],
        ),
    ],
    "snmp_scan_function": lambda oid: oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.4.1.28507.19")
    or oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.4.1.28507.38"),
    "default_levels_variable": "gude_powerbank_default_levels",
    "group": "el_inphase",
}
