#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# |             ____ _               _        __  __ _  __           |
# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
# |                                                                  |
# | Copyright Mathias Kettner 2018             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.


def parse_hp_hh3c_ext(info):
    entity_info = dict(info[1])
    parsed = {}
    for index, admin_state, oper_state, cpu, \
        mem_usage, temperature, mem_size in info[0]:
        name = entity_info.get(index, (None, None))

        # mem_size measured in 'bytes' (hh3cEntityExtMemSize)
        # check_memory_multiitem needs values in bytes, not percent
        mem_total = int(mem_size)
        mem_used = 0.01 * int(mem_usage) * mem_total

        parsed.setdefault(
            "%s %s" % (name, index), {
                'temp': int(temperature),
                'cpu': int(cpu),
                'mem_total': mem_total,
                'mem_used': mem_used,
                'admin': admin_state,
                'oper': oper_state,
            })
    return parsed


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


def inventory_hp_hh3c_ext(parsed):
    for k, v in parsed.iteritems():
        # The invalid value is 65535.
        # We assume: If mem_total <= 0, this module is not installed or
        # does not provide reasonable data or is not a real sensor.
        if v["temp"] != 65535 and v['mem_total'] > 0:
            yield k, {}


def check_hp_hh3c_ext(item, params, parsed):
    if item not in parsed:
        return
    return check_temperature(parsed[item]['temp'], params, "hp_hh3c_ext.%s" % item)


check_info['hp_hh3c_ext'] = {
    'parse_function': parse_hp_hh3c_ext,
    'inventory_function': inventory_hp_hh3c_ext,
    'check_function': check_hp_hh3c_ext,
    'service_description': 'Temperature %s',
    'snmp_info': [
        (
            '.1.3.6.1.4.1.25506.2.6.1.1.1.1',
            [  # HH3C-ENTITY-EXT-MIB
                OID_END,
                '2',  # hh3cEntityExtAdminStatus
                '3',  # hh3cEntityExtOperStatus
                '6',  # hh3cEntityExtCpuUsage
                '8',  # hh3cEntityExtMemUsage
                '12',  # hh3cEntityExtTemperature
                '10',  # hh3cEntityExtMemSize
            ]),
        (
            '.1.3.6.1.2.1.47.1.1.1.1',
            [
                OID_END,
                CACHED_OID(2),  # entPhysicalDescr
            ])
    ],
    'snmp_scan_function': lambda oid: oid('.1.3.6.1.2.1.1.2.0').startswith(
        '.1.3.6.1.4.1.25506.11.1.239'),
    'includes': ['temperature.include'],
    'group': 'temperature',
    'has_perfdata': True,
}

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


def inventory_hp_hh3c_ext_states(parsed):
    for k, v in parsed.iteritems():
        if v["mem_total"] > 0:
            # We assume: if mem_total > 0 then
            # this module is installed and provides
            # reasonable data.
            yield k, {}


def check_hp_hh3c_ext_states(item, params, parsed):
    if item not in parsed:
        return

    map_admin_states = {
        '1': (1, 'not_supported', 'not supported'),
        '2': (0, 'locked', 'locked'),
        '3': (2, 'shutting_down', 'shutting down'),
        '4': (2, 'unlocked', 'unlocked'),
    }
    map_oper_states = {
        '1': (1, 'not_supported', 'not supported'),
        '2': (2, 'disabled', 'disabled'),
        '3': (0, 'enabled', 'enabled'),
        '4': (2, 'dangerous', 'dangerous'),
    }

    attrs = parsed[item]
    for state_type, title, mapping in [('admin', 'Administrative', map_admin_states),
                                       ('oper', 'Operational', map_oper_states)]:
        dev_state = attrs[state_type]
        state, params_key, state_readable = mapping.get(dev_state, (3, 'unknown[%s]' % dev_state))
        params_state_type = params.get(state_type, {})
        if params_key in params_state_type:
            state = params_state_type[params_key]
        yield state, "%s: %s" % (title, state_readable)


check_info['hp_hh3c_ext.states'] = {
    'inventory_function': inventory_hp_hh3c_ext_states,
    'check_function': check_hp_hh3c_ext_states,
    'service_description': 'Status %s',
    'group': 'hp_hh3c_ext_states',
}

#.
#   .--CPU utilization-----------------------------------------------------.
#   |    ____ ____  _   _         _   _ _ _          _   _                 |
#   |   / ___|  _ \| | | |  _   _| |_(_) (_)______ _| |_(_) ___  _ __      |
#   |  | |   | |_) | | | | | | | | __| | | |_  / _` | __| |/ _ \| '_ \     |
#   |  | |___|  __/| |_| | | |_| | |_| | | |/ / (_| | |_| | (_) | | | |    |
#   |   \____|_|    \___/   \__,_|\__|_|_|_/___\__,_|\__|_|\___/|_| |_|    |
#   |                                                                      |
#   '----------------------------------------------------------------------'


def inventory_hp_hh3c_ext_cpu(parsed):
    for k, v in parsed.iteritems():
        if v["mem_total"] > 0:
            # We assume: if mem_total > 0 then
            # this module is installed and provides
            # reasonable data.
            yield k, {}


def check_hp_hh3c_ext_cpu(item, params, parsed):
    if item not in parsed:
        return
    return check_cpu_util(parsed[item]['cpu'], params)


check_info['hp_hh3c_ext.cpu'] = {
    'inventory_function': inventory_hp_hh3c_ext_cpu,
    'check_function': check_hp_hh3c_ext_cpu,
    'service_description': 'CPU utilization %s',
    'includes': ['cpu_util.include'],
    'group': 'cpu_utilization_multiitem',
    'has_perfdata': True,
}

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

factory_settings['hp_hh3c_ext_mem_default_levels'] = {
    "levels": (80.0, 90.0),
}


def inventory_hp_hh3c_ext_mem(parsed):
    for name, attrs in parsed.iteritems():
        if attrs["mem_total"] > 0:
            # We assume: if mem_total > 0 then
            # this module is installed and provides
            # reasonable data.
            yield name, {}


def check_hp_hh3c_ext_mem(item, params, parsed):
    if item not in parsed:
        return
    return check_memory_multiitem(params, parsed[item])


check_info['hp_hh3c_ext.mem'] = {
    'inventory_function': inventory_hp_hh3c_ext_mem,
    'check_function': check_hp_hh3c_ext_mem,
    'service_description': 'Memory %s',
    'includes': ['memory.include'],
    'group': 'memory_multiitem',
    'has_perfdata': True,
    'default_levels_variable': 'hp_hh3c_ext_mem_default_levels',
}
