#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# |             ____ _               _        __  __ _  __           |
# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
# |                                                                  |
# | Copyright Mathias Kettner 2016             mk@mathias-kettner.de |
# +------------------------------------------------------------------+
#
# This file is part of Check_MK.
# The official homepage is at http://mathias-kettner.de/check_mk.
#
# check_mk is free software;  you can redistribute it and/or modify it
# under the  terms of the  GNU General Public License  as published by
# the Free Software Foundation in version 2.  check_mk is  distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY;  with-
# out even the implied warranty of  MERCHANTABILITY  or  FITNESS FOR A
# PARTICULAR PURPOSE. See the  GNU General Public License for more de-
# tails. You should have  received  a copy of the  GNU  General Public
# License along with GNU Make; see the file  COPYING.  If  not,  write
# to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
# Boston, MA 02110-1301 USA.

# .1.3.6.1.4.1.10222.2.1.2.9.1.1.1.1.1 1 --> ICS-CHASSIS-MIB::icsChassisSlotIndex.1.1.1
# .1.3.6.1.4.1.10222.2.1.2.9.1.1.1.2.1 2 --> ICS-CHASSIS-MIB::icsChassisSlotIndex.1.2.1
#
# .1.3.6.1.4.1.10222.2.1.9.8.1.2.1.1.1 2 --> ICS-CHASSIS-MIB::icsChassisSensorSlotType.1.1.1
# .1.3.6.1.4.1.10222.2.1.9.8.1.2.1.1.2 2 --> ICS-CHASSIS-MIB::icsChassisSensorSlotType.1.1.2
# .1.3.6.1.4.1.10222.2.1.9.8.1.2.1.2.1 2 --> ICS-CHASSIS-MIB::icsChassisSensorSlotType.1.2.1
# .1.3.6.1.4.1.10222.2.1.9.8.1.2.1.2.2 2 --> ICS-CHASSIS-MIB::icsChassisSensorSlotType.1.2.2
# .1.3.6.1.4.1.10222.2.1.9.8.1.3.1.1.1 4 --> ICS-CHASSIS-MIB::icsChassisSensorSlotOperStatus.1.1.1
# .1.3.6.1.4.1.10222.2.1.9.8.1.3.1.1.2 4 --> ICS-CHASSIS-MIB::icsChassisSensorSlotOperStatus.1.1.2
# .1.3.6.1.4.1.10222.2.1.9.8.1.3.1.2.1 4 --> ICS-CHASSIS-MIB::icsChassisSensorSlotOperStatus.1.2.1
# .1.3.6.1.4.1.10222.2.1.9.8.1.3.1.2.2 4 --> ICS-CHASSIS-MIB::icsChassisSensorSlotOperStatus.1.2.2
# .1.3.6.1.4.1.10222.2.1.9.8.1.7.1.1.1  FUSION -- baseboard temp --> ICS-CHASSIS-MIB::icsChassisSensorSlotDescription.1.1.1
# .1.3.6.1.4.1.10222.2.1.9.8.1.7.1.1.2  FUSION -- fusion temp --> ICS-CHASSIS-MIB::icsChassisSensorSlotDescription.1.1.2
# .1.3.6.1.4.1.10222.2.1.9.8.1.7.1.2.1  FUSION -- baseboard temp --> ICS-CHASSIS-MIB::icsChassisSensorSlotDescription.1.2.1
# .1.3.6.1.4.1.10222.2.1.9.8.1.7.1.2.2  FUSION -- fusion temp --> ICS-CHASSIS-MIB::icsChassisSensorSlotDescription.1.2.2
# .1.3.6.1.4.1.10222.2.1.9.8.1.8.1.1.1 41 --> ICS-CHASSIS-MIB::icsChassisSensorSlotValue.1.1.1
# .1.3.6.1.4.1.10222.2.1.9.8.1.8.1.1.2 32 --> ICS-CHASSIS-MIB::icsChassisSensorSlotValue.1.1.2
# .1.3.6.1.4.1.10222.2.1.9.8.1.8.1.2.1 49 --> ICS-CHASSIS-MIB::icsChassisSensorSlotValue.1.2.1
# .1.3.6.1.4.1.10222.2.1.9.8.1.8.1.2.2 31 --> ICS-CHASSIS-MIB::icsChassisSensorSlotValue.1.2.2


def parse_intel_true_scale_sensors(info):
    map_slot_types = {
        "0": "unspecified",
        "1": "switch master",
        "2": "switch slave",
        "3": "eiou",
        "4": "fciou",
        "5": "other",
        "6": "spine master",
        "7": "spine slave",
        "8": "spine",
        "9": "leaf",
        "10": "viofx",
        "11": "vioex",
        "12": "shuttle master",
        "13": "shuttle slave",
        "14": "xMM master",
        "15": "xMM slave",
        "16": "xspine",
        "17": "xQleaf",
        "18": "xDleaf",
        "19": "xVioFx",
        "20": "xVioEx"
    }

    map_sensor_types = {
        "1": "other",
        "2": "temp",
        "3": "fan",
        "4": "humid",
        "5": "acpower",
        "6": "dcpower",
        "7": "slot",
        "8": "fuse",
    }

    map_states = {
        "0": (2, "invalid"),
        "1": (3, "unknown"),
        "2": (2, "bad"),
        "3": (1, "warning"),
        "4": (0, "good"),
        "5": (3, "disabled"),
    }

    slots, sensors = info
    parsed = {}
    for slot_id, slot_ty in slots:
        parsed.setdefault("slot %s" % slot_id, {"slot_type": map_slot_types[slot_ty]})

    for oid_end, ty, status, descr, reading_str in sensors:
        slot_id, sensor_id = oid_end.split(".")[1:]
        slot_name = "slot %s" % slot_id
        sensor_name = " ".join(descr.split(" ")[2:-1])

        # We do not known for all sensors. Feel free to extend
        if ty in ["5", "6"]:
            factor = 0.001
        else:
            factor = 1

        state, state_readable = map_states[status]
        kwargs = {"dev_status": state, "dev_status_name": state_readable}

        sensor_ty = map_sensor_types[ty]
        parsed[slot_name].setdefault(sensor_ty, [])
        parsed[slot_name][sensor_ty].append(
            ("%s %s" % (sensor_id, sensor_name), float(reading_str) * factor, kwargs))

    return parsed


#   .--temperature---------------------------------------------------------.
#   |      _                                      _                        |
#   |     | |_ ___ _ __ ___  _ __   ___ _ __ __ _| |_ _   _ _ __ ___       |
#   |     | __/ _ \ '_ ` _ \| '_ \ / _ \ '__/ _` | __| | | | '__/ _ \      |
#   |     | ||  __/ | | | | | |_) |  __/ | | (_| | |_| |_| | | |  __/      |
#   |      \__\___|_| |_| |_| .__/ \___|_|  \__,_|\__|\__,_|_|  \___|      |
#   |                       |_|                                            |
#   +----------------------------------------------------------------------+
#   |                            main check                                |
#   '----------------------------------------------------------------------'


def inventory_intel_true_scale_sensors_temp(parsed):
    for slot_name, slot_info in parsed.items():
        if slot_info.get("temp"):
            yield slot_name, {}


def check_intel_true_scale_sensors_temp(item, params, parsed):
    if item in parsed:
        yield check_temperature_list(parsed[item]["temp"], params,
                                     "intel_true_scale_sensors_temp_%s" % item)


check_info['intel_true_scale_sensors_temp'] = {
    'parse_function': parse_intel_true_scale_sensors,
    'inventory_function': inventory_intel_true_scale_sensors_temp,
    'check_function': check_intel_true_scale_sensors_temp,
    'service_description': 'Temperature sensors %s',
    'has_perfdata': True,
    'snmp_info': [
        (
            ".1.3.6.1.4.1.10222.2.1.2.9.1",
            [
                "1",  # ICS-CHASSIS-MIB::icsChassisSlotIndex
                "3",  # ICS-CHASSIS-MIB::icsChassisSlotCardType
            ]),
        (
            ".1.3.6.1.4.1.10222.2.1.9.8.1",
            [
                OID_END,
                "2",  # icsChassisSensorSlotType
                "3",  # icsChassisSensorSlotOperStatus
                "7",  # icsChassisSensorSlotDescription
                "8",  # icsChassisSensorSlotValue
            ])
    ],
    'snmp_scan_function': scan_intel_true_scale,
    'includes': ['temperature.include', 'intel_true_scale.include'],
}
