#!/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',
}
