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

# .1.3.6.1.4.1.9.9.117.1.1.2.1.2.22 2
# .1.3.6.1.4.1.9.9.117.1.1.2.1.2.23 2
# .1.3.6.1.4.1.9.9.117.1.1.2.1.2.470 2
# .1.3.6.1.4.1.9.9.117.1.1.2.1.2.471 2
# .1.3.6.1.4.1.9.9.117.1.1.2.1.2.472 2
# .1.3.6.1.4.1.9.9.117.1.1.2.1.2.473 2
# .1.3.6.1.4.1.9.9.117.1.1.2.1.2.113000022 2
# .1.3.6.1.4.1.9.9.117.1.1.2.1.2.113000470 2
# .1.3.6.1.4.1.9.9.117.1.1.2.1.2.113000471 2
# .1.3.6.1.4.1.9.9.117.1.1.2.1.2.116000022 2
# .1.3.6.1.4.1.9.9.117.1.1.2.1.2.116000470 2
# .1.3.6.1.4.1.9.9.117.1.1.2.1.2.116000471 2

# .1.3.6.1.2.1.47.1.1.1.1.7.10 Fabric [VPC domain:12]
# .1.3.6.1.2.1.47.1.1.1.1.7.22 Nexus 56128P Supervisor in Fixed Module-1
# .1.3.6.1.2.1.47.1.1.1.1.7.23 24 ports 10GE SFP+ and 2xQSFP ports Ethernet Module
# .1.3.6.1.2.1.47.1.1.1.1.7.149 Nexus 56128P Chassis
# .1.3.6.1.2.1.47.1.1.1.1.7.214 Fixed Slot-1
# .1.3.6.1.2.1.47.1.1.1.1.7.215 Module Slot-2
# .1.3.6.1.2.1.47.1.1.1.1.7.216 Module Slot-3
# .1.3.6.1.2.1.47.1.1.1.1.7.278 PowerSupplyBay-1
# .1.3.6.1.2.1.47.1.1.1.1.7.279 PowerSupplyBay-2
# .1.3.6.1.2.1.47.1.1.1.1.7.280 PowerSupplyBay-3
# .1.3.6.1.2.1.47.1.1.1.1.7.281 PowerSupplyBay-4
# .1.3.6.1.2.1.47.1.1.1.1.7.342 FanBay-1
# .1.3.6.1.2.1.47.1.1.1.1.7.343 FanBay-2
# .1.3.6.1.2.1.47.1.1.1.1.7.344 FanBay-3
# .1.3.6.1.2.1.47.1.1.1.1.7.345 FanBay-4
# .1.3.6.1.2.1.47.1.1.1.1.7.470 PowerSupply-1
# .1.3.6.1.2.1.47.1.1.1.1.7.471 PowerSupply-2
# .1.3.6.1.2.1.47.1.1.1.1.7.472 PowerSupply-3
# .1.3.6.1.2.1.47.1.1.1.1.7.473 PowerSupply-4
# .1.3.6.1.2.1.47.1.1.1.1.7.534 FanModule-1
# .1.3.6.1.2.1.47.1.1.1.1.7.535 FanModule-2
# .1.3.6.1.2.1.47.1.1.1.1.7.536 FanModule-3
# .1.3.6.1.2.1.47.1.1.1.1.7.537 FanModule-4
# .1.3.6.1.2.1.47.1.1.1.1.7.538 PowerSupply-1 Fan-1
# .1.3.6.1.2.1.47.1.1.1.1.7.539 PowerSupply-1 Fan-2
# .1.3.6.1.2.1.47.1.1.1.1.7.540 PowerSupply-2 Fan-1
# .1.3.6.1.2.1.47.1.1.1.1.7.541 PowerSupply-2 Fan-2
# ...


def parse_cisco_fru_power(info):
    map_states = {
        "1": (1, "off env other"),
        "2": (0, "on"),
        "3": (1, "off admin"),
        "4": (2, "off denied"),
        "5": (2, "off env power"),
        "6": (2, "off env temp"),
        "7": (2, "off env fan"),
        "8": (2, "failed"),
        "9": (1, "on but fan fail"),
        "10": (1, "off cooling"),
        "11": (1, "off connector rating"),
        "12": (2, "on but inline power fail"),
    }

    ppre_parsed = {}
    for end_oid, oper_state, fru_current in info[0]:
        # We discover only "real" power supplies which have current value >= 0
        # Others such as modules do not have such values
        if oper_state not in ["", "0", "1", "5"] and fru_current and int(fru_current) >= 0:
            ppre_parsed.setdefault(
                end_oid, map_states.get(oper_state, (3, "unexpected(%s)" % oper_state))
            )

    pre_parsed = {}
    for end_oid, name in info[1]:
        if end_oid in ppre_parsed:
            pre_parsed.setdefault(name, [])
            pre_parsed[name].append(ppre_parsed[end_oid])

    parsed = {}
    for name, infos in pre_parsed.items():
        if len(infos) > 1:
            for k, state_info in enumerate(infos):
                parsed["%s-%d" % (name, k + 1)] = state_info
        else:
            parsed[name] = infos[0]

    return parsed


def inventory_cisco_fru_power(parsed):
    for item in parsed:
        yield item, None


def check_cisco_fru_power(item, _no_params, parsed):
    if item in parsed:
        state, state_readable = parsed[item]
        return state, "Status: %s" % state_readable


check_info["cisco_fru_power"] = {
    "parse_function": parse_cisco_fru_power,
    "inventory_function": inventory_cisco_fru_power,
    "check_function": check_cisco_fru_power,
    "service_description": "FRU Power %s",
    "snmp_info": [
        (
            ".1.3.6.1.4.1.9.9.117.1.1.2.1",
            [
                OID_END,
                "2",  # CISCO-ENTITY-FRU-CONTROL-MIB::cefcFRUPowerOperStatus
                "3",  # CISCO-ENTITY-FRU-CONTROL-MIB::cefcFRUCurrent
            ],
        ),
        (
            ".1.3.6.1.2.1.47.1.1.1.1",
            [
                OID_END,
                CACHED_OID(7),  # ENTITY-MIB::entPhysicalName
            ],
        ),
    ],
    # Exclude cisco_power check
    "snmp_scan_function": lambda oid: "cisco" in oid(".1.3.6.1.2.1.1.1.0").lower()
    and not oid(".1.3.6.1.4.1.9.9.13.1.5.1.*"),
}
