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

# Example output from agent:
# Slot Number: 0
# Device Id: 4
# Raw Size: 140014MB [0x11177330 Sectors]
# Firmware state: Unconfigured(good)
# Inquiry Data: FUJITSU MBB2147RC       5204BS04P9104BV5
# Slot Number: 1
# Device Id: 5
# Raw Size: 140014MB [0x11177330 Sectors]
# Firmware state: Unconfigured(good)
# Inquiry Data: FUJITSU MBB2147RC       5204BS04P9104BSC

# The agent provides some new information since 1.1.9.
# The dev2enc infos are sent from the agent to have the
# real enclosure numbers instead of the device ids which
# seem to be generated somehow.
#
# dev2enc Enclosure 0 Device ID  6
# dev2enc Enclosure 1 Device ID  252
#
# On new inventory runs the enclosure number is used as
# index and item part.
megaraid_pdisks_legacy_mode = False
# This makes service descriptions backward compatible to match
# inventory made by older versions that didn't support multiple
# controllers
megaraid_pdisks_adapterstr = ['e', 'f', 'g', 'h', 'i', 'j', 'k', 'l']


def megaraid_pdisks_parse(info):
    adapters = {0: {}}
    current_adapter = adapters[0]
    return_var = []
    adapter = 0
    enclosure_devid = -181
    for line in info:
        if line[0] == 'adapter':
            current_adapter = {}
            adapters[int(line[1])] = current_adapter
        elif line[0] == 'dev2enc':
            if line[2].isdigit():
                current_adapter[int(line[5])] = int(line[2])
        elif line[0] == 'Adapter' and len(line) == 2:
            current_adapter = adapters[int(line[1][1:])]  # Raute weglassen
            adapter = int(line[1][1:])
        elif line[0] == "Enclosure" and line[1] == "Device":
            try:
                enclosure_devid = int(line[-1])
                # this should fix inventory problems.
                adapters[adapter][enclosure_devid] = enclosure_devid

            except:  # no enclosure device
                enclosure_devid = 0
                adapters[adapter][0] = 0
        elif line[0] == "Enclosure" and line[1] == "Number:":
            for devid, number in current_adapter.items():
                if number == int(line[-1]):
                    enclosure_devid = devid
                    break

        elif line[0] == "Slot":
            slot = int(line[-1])
        elif line[0] == "Firmware" and line[1] == "state:":
            state = line[2].rstrip(',')
        elif line[0] == "Inquiry" and line[1] == "Data:":
            name = " ".join(line[2:])
            #Adapter, Enclosure, Encolsure Device ID, Slot, State, Name
            return_var.append(
                (megaraid_pdisks_adapterstr[adapter], adapters[adapter][enclosure_devid],
                 enclosure_devid, slot, state, name))

    return return_var


def inventory_megaraid_pdisks(info):
    info = megaraid_pdisks_parse(info)
    inventory = []
    for adapter, enclosure, _enc_dev_id, slot, _state, _name in info:
        inventory.append(("%s%s/%s" % (adapter, enclosure, slot), None))
    return inventory


megaraid_pdisks_states = {
    'Online': 0,
    'Hotspare': 0,
    'Unconfigured(good)': 0,
    'JBOD': 0,
    'Failed': 2,
    'Unconfigured(bad)': 1,
    'Copyback': 1,
    'Rebuild': 1,
}


def check_megaraid_pdisks(item, _no_params, info):
    info = megaraid_pdisks_parse(info)
    for adapter, enclosure, _enc_dev_id, slot, state, name in info:
        if "%s%s/%s" % (adapter, enclosure, slot) == item:
            return megaraid_pdisks_states.get(state, 3), "%s (%s)" % (state, name)
    return 3, "No disk in encl/slot %s found" % item


check_info["megaraid_pdisks"] = {
    'check_function': check_megaraid_pdisks,
    'inventory_function': inventory_megaraid_pdisks,
    'service_description': 'RAID PDisk Adapt/Enc/Sl %s',
    'has_perfdata': False,
}
