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

# 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

#
# Based on contribution by Karsten Schöke <karsten.schoeke@geobasis-bb.de>
#
# Example Output:
# .1.3.6.1.4.1.5951.4.1.1.41.7.1.1.12.1 "CPUFan0Speed"
# .1.3.6.1.4.1.5951.4.1.1.41.7.1.1.12.2 "CPUFan1Speed"
# .1.3.6.1.4.1.5951.4.1.1.41.7.1.1.14.2 "SystemFanSpeed"
# .1.3.6.1.4.1.5951.4.1.1.41.7.1.1.14.3 "CPU0Temperature"
# .1.3.6.1.4.1.5951.4.1.1.41.7.1.1.14.4 "CPU1Temperature"
# .1.3.6.1.4.1.5951.4.1.1.41.7.1.1.19.3 "InternalTemperature"
# .1.3.6.1.4.1.5951.4.1.1.41.7.1.1.25.2 "PowerSupply1FailureStatus"
# .1.3.6.1.4.1.5951.4.1.1.41.7.1.1.25.7 "PowerSupply2FailureStatus"
# .1.3.6.1.4.1.5951.4.1.1.41.7.1.2.12.1 9975
# .1.3.6.1.4.1.5951.4.1.1.41.7.1.2.12.2 9750
# .1.3.6.1.4.1.5951.4.1.1.41.7.1.2.14.2 9825
# .1.3.6.1.4.1.5951.4.1.1.41.7.1.2.14.3 60
# .1.3.6.1.4.1.5951.4.1.1.41.7.1.2.14.4 72
# .1.3.6.1.4.1.5951.4.1.1.41.7.1.2.19.3 32
# .1.3.6.1.4.1.5951.4.1.1.41.7.1.2.25.2 0
# .1.3.6.1.4.1.5951.4.1.1.41.7.1.2.25.7 9900


def netscaler_health_scan(oid):
    return oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.4.1.5951.1")


netscaler_health_info = (
    ".1.3.6.1.4.1.5951.4.1.1.41.7.1",
    [  # nsSysHealthTable
        1,  # sysHealthname
        2,  # sysHealthvalue
    ],
)
# .
#   .--fan-----------------------------------------------------------------.
#   |                            __                                        |
#   |                           / _| __ _ _ __                             |
#   |                          | |_ / _` | '_ \                            |
#   |                          |  _| (_| | | | |                           |
#   |                          |_|  \__,_|_| |_|                           |
#   |                                                                      |
#   +----------------------------------------------------------------------+

factory_settings["netscaler_health_fan_default_levels"] = {
    "lower": (3500, 3000),
    "upper": (None, None),
}


def inventory_netscaler_health_fan(info):
    for name, value in info:
        if name.endswith("Speed") and value != "0":
            yield name[:-5], {}


def check_netscaler_health_fan(item, params, info):
    for name, value in info:
        if name[:-5] == item:
            return check_fan(int(value), params)


check_info["netscaler_health.fan"] = {
    "inventory_function": inventory_netscaler_health_fan,
    "check_function": check_netscaler_health_fan,
    "service_description": "FAN %s",
    "snmp_info": netscaler_health_info,
    "snmp_scan_function": netscaler_health_scan,
    "has_perfdata": True,
    "default_levels_variable": "netscaler_health_fan_default_levels",
    "group": "hw_fans",
}
# .
#   .--temp----------------------------------------------------------------.
#   |                       _                                              |
#   |                      | |_ ___ _ __ ___  _ __                         |
#   |                      | __/ _ \ '_ ` _ \| '_ \                        |
#   |                      | ||  __/ | | | | | |_) |                       |
#   |                       \__\___|_| |_| |_| .__/                        |
#   |                                        |_|                           |
#   +----------------------------------------------------------------------+

factory_settings["netscaler_health_temp_default_levels"] = {
    "levels": (80, 90),
}


def inventory_netscaler_health_temp(info):
    for name, value in info:
        if name.endswith("Temperature") and value != "0":
            yield name[:-11], {}


def check_netscaler_health_temp(item, params, info):
    for name, value in info:
        if name[:-11] == item and name.endswith("Temperature"):
            temp = int(value)
            return check_temperature(temp, params, "netscaler_health_%s" % item)


check_info["netscaler_health.temp"] = {
    "check_function": check_netscaler_health_temp,
    "inventory_function": inventory_netscaler_health_temp,
    "service_description": "Temperature %s",
    "group": "temperature",
    "has_perfdata": True,
    "snmp_info": netscaler_health_info,
    "snmp_scan_function": netscaler_health_scan,
    "default_levels_variable": "netscaler_health_temp_default_levels",
}

# .
#   .--psu-----------------------------------------------------------------.
#   |                                                                      |
#   |                           _ __  ___ _   _                            |
#   |                          | '_ \/ __| | | |                           |
#   |                          | |_) \__ \ |_| |                           |
#   |                          | .__/|___/\__,_|                           |
#   |                          |_|                                         |
#   +----------------------------------------------------------------------+


def inventory_netscaler_health_psu(info):
    for name, state in info:
        r = regex(r"PowerSupply([\d])(Failure|)Status")
        m = r.match(name)
        if m:
            if int(state) > 0:
                yield m.group(1), None


def check_netscaler_health_psu(item, _no_params, info):
    psu_status_map = (
        (3, "not supported"),  # 0
        (2, "not present"),  # 1
        (2, "failed"),  # 2
        (0, "normal"),  # 3
    )

    for name, state in info:
        if name.startswith("PowerSupply" + item) and (
            name.endswith("Status") or name.endswith("FailureStatus")
        ):
            return psu_status_map[int(state)]


check_info["netscaler_health.psu"] = {
    "check_function": check_netscaler_health_psu,
    "inventory_function": inventory_netscaler_health_psu,
    "service_description": "Power Supply %s",
    "snmp_info": netscaler_health_info,
    "snmp_scan_function": netscaler_health_scan,
}
