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

import cmk.base.plugins.agent_based.utils.ucs_bladecenter as ucs_bladecenter

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

# <<ucs_bladecenter_fans:sep(9)>>>
# equipmentNetworkElementFanStats Dn sys/switch-A/fan-module-1-1/fan-1/stats      SpeedAvg 8542
# equipmentFanModuleStats Dn sys/chassis-2/fan-module-1-1/stats   AmbientTemp 29.000000
# equipmentFan    Dn sys/chassis-1/fan-module-1-1/fan-1   Model N20-FAN5  OperState operable
# equipmentFanStats       Dn sys/chassis-2/fan-module-1-1/fan-1/stats     SpeedAvg 3652


def parse_ucs_bladecenter_fans(info):
    data = ucs_bladecenter.generic_parse(info)
    fans = {}

    def get_item_name(key):
        tokens = key.split("/")
        tokens[1] = tokens[1].replace("fan-module-", "Module ").replace("-", ".")
        tokens = [x[0].upper() + x[1:] for x in tokens]
        if len(tokens) > 2:
            tokens[2] = tokens[2].replace("fan-", ".")
        return " ".join(tokens).replace("-", " ")

    for component, key_low, key_high in [
        ("equipmentNetworkElementFanStats", 4, -6),
        ("equipmentFanModuleStats", 4, -6),
        ("equipmentFan", 4, 100),
        ("equipmentFanStats", 4, -6),
    ]:
        for key, values in data.get(component, {}).items():
            fan = key[key_low:key_high]
            del values["Dn"]
            name = get_item_name(fan)
            fans.setdefault(name, {}).update(values)

    return fans


#   .--Fans----------------------------------------------------------------.
#   |                         _____                                        |
#   |                        |  ___|_ _ _ __  ___                          |
#   |                        | |_ / _` | '_ \/ __|                         |
#   |                        |  _| (_| | | | \__ \                         |
#   |                        |_|  \__,_|_| |_|___/                         |
#   |                                                                      |
#   '----------------------------------------------------------------------'


def inventory_ucs_bladecenter_fans(parsed):
    for key, values in parsed.items():
        if "SpeedAvg" in values:
            yield " ".join(key.split()[:2]), None


def check_ucs_bladecenter_fans(item, _no_params, parsed):
    my_fans = {}
    for key, values in parsed.items():
        if key.startswith(item) and "OperState" in values:
            my_fans[key] = values

    if not my_fans:
        yield 3, "Fan statistics not available"
        return

    yield 0, "%d Fans" % len(my_fans)
    for key, fan in sorted(my_fans.items()):
        if fan["OperState"] != "operable":
            yield 2, "Fan %s %s: average speed %s RPM" % (
                key.split()[-1][2:],
                fan["OperState"],
                fan.get("SpeedAvg"),
            )


check_info["ucs_bladecenter_fans"] = {
    "parse_function": parse_ucs_bladecenter_fans,
    "inventory_function": inventory_ucs_bladecenter_fans,
    "check_function": check_ucs_bladecenter_fans,
    "service_description": "Fans %s",
}

# .
#   .--Temperature---------------------------------------------------------.
#   |     _____                                   _                        |
#   |    |_   _|__ _ __ ___  _ __   ___ _ __ __ _| |_ _   _ _ __ ___       |
#   |      | |/ _ \ '_ ` _ \| '_ \ / _ \ '__/ _` | __| | | | '__/ _ \      |
#   |      | |  __/ | | | | | |_) |  __/ | | (_| | |_| |_| | | |  __/      |
#   |      |_|\___|_| |_| |_| .__/ \___|_|  \__,_|\__|\__,_|_|  \___|      |
#   |                       |_|                                            |
#   '----------------------------------------------------------------------'

factory_settings["ucs_bladecenter_fans_temp_default_levels"] = {
    "levels": (40, 50),
}


# Fans are grouped per module, usually 8 components
def inventory_ucs_bladecenter_fans_temp(parsed):
    for key, values in parsed.items():
        if "AmbientTemp" in values:
            yield "Ambient %s FAN" % " ".join(key.split()[:2]), {}


def check_ucs_bladecenter_fans_temp(item, params, parsed):
    sensor_item = item[8:-4]  # drop "Ambient " and " FAN"
    sensor_list = []
    for key, values in parsed.items():
        if key.startswith(sensor_item) and "AmbientTemp" in values:
            loc = key.split()[-1].split(".")
            sensor_list.append(
                (
                    "Module %s Fan %s" % (loc[0], loc[1]),
                    float(values.get("AmbientTemp")),
                )
            )
    return check_temperature_list(sensor_list, params, "ucs_bladecenter_fans_%s" % item)


check_info["ucs_bladecenter_fans.temp"] = {
    "inventory_function": inventory_ucs_bladecenter_fans_temp,
    "check_function": check_ucs_bladecenter_fans_temp,
    "service_description": "Temperature %s",
    "group": "temperature",
    "has_perfdata": True,
    "default_levels_variable": "ucs_bladecenter_fans_temp_default_levels",
}
