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


# Agent output not included since it has almost 100 lines
# it's available in our archive or fh's bitbucket

# Load a fake controller with known good values for the most
# important parameters only and try to define their importance
megaraid_bbu_refvalues = {
    'Remaining Capacity Low'                    : ('No', 1),    # nolearn
    'I2c Errors Detected'                       : ('No', 1),
    'Temperature'                               : ('OK', 2),
    'Pack is about to fail & should be replaced': ('No', 1),
    'Charging Status'                           : ('None', 1),  # nolearn
    'Battery State'                             : ('Operational', 2),  # nolearn
    'Learn Cycle Status'                        : ('OK', 1),
    'Learn Cycle Active'                        : ('Yes', 0),
    'Battery Pack Missing'                      : ('No', 2),
    'Battery Replacement required'              : ('No', 1),
    'Over Temperature'                          : ('No', 2),
    'Over Charged'                              : ('No', 1),
    'Voltage'                                   : ('OK', 2),   # nolearn
}


def megaraid_bbu_parse(info):
    controllers = {}
    for line in info:
        # Format the Agent output
        name, data = " ".join(line).split(":")
        name = name.strip()
        data = data.strip()

        # Scan each controller into its own dictionary
        if name in [ "BBU status for Adapter", "BBU status for Adpater" ]:
            current_hba = {}
            controllers[data] = current_hba
        else:
            # We lose the numerical temperature here
            # (same key is used twice in output of megacli)
            current_hba[name] = data
    return controllers


def inventory_megaraid_bbu(info):
    return [ (name, None) for name in megaraid_bbu_parse(info) ]


def check_megaraid_bbu(item, _no_params, info):
    controllers = megaraid_bbu_parse(info)
    if item not in controllers:
        return (3, "UNKNOWN - Controller data not found in agent output")

    controller = controllers[item]
    broken = []
    state  = 0
    # get current charge level
    if 'Relative State of Charge' not in controller:
        charge = ", No charge information reported for this controller"
    else:
        charge = ", Charge is %s" % controller['Relative State of Charge']

    # verify defined important parameters to current level
    for varname, (refvalue, refstate) in megaraid_bbu_refvalues.items():
        # the try/except should handle controller types that don't have certain values
        # if your bbu chipset fails and you still get a partial response this will lead
        # to a false result. but people asked for it :>
        try:
            if controller[varname] != refvalue:
    	        broken.append("%s is %s, but should be %s(%s)" % (varname, value, refvalue, "!" * refstate))
    	        state = max(state, refstate)
        except:
            pass

    if controller.get("Learn Cycle Active") == "Yes":
        return (0, "OK - no states to check (controller is in learn cycle)" + charge)
    # return assembled info
    elif broken:
	return (state, nagios_state_names[state] + " - " + ", ".join(broken) + charge)
    else:
	return (0, "OK - all states as expected" + charge)

    return (3, "UNKNOWN - Check not implemented")



check_info["megaraid_bbu"] = (check_megaraid_bbu, "RAID Adapter/BBU %s", 0, inventory_megaraid_bbu)
