#!/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.

# Author: Lars Michelsen <lm@mathias-kettner.de>, 2011-03-16

# Example output for this case:
#
# 1.3.6.1.2.1.43.18.1.1.2.1.1  4
# 1.3.6.1.2.1.43.18.1.1.4.1.1  11
# 1.3.6.1.2.1.43.18.1.1.5.1.1  -1
# 1.3.6.1.2.1.43.18.1.1.7.1.1  1107
# 1.3.6.1.2.1.43.18.1.1.8.1.1  "The waste toner container is full soon."
#
# [['4', '11', '-1', '1107', 'The waste toner container is full soon.']]

printer_alerts_group_map = {
    '1': 'other',
    '3': 'hostResourcesMIBStorageTable',
    '4': 'hostResourcesMIBDeviceTable',
    '5': 'generalPrinter',
    '6': 'cover',
    '7': 'localization',
    '8': 'input',
    '9': 'output',
    '10': 'marker',
    '11': 'markerSupplies',
    '12': 'markerColorant',
    '13': 'mediaPath',
    '14': 'channel',
    '15': 'interpreter',
    '16': 'consoleDisplayBuffer',
    '17': 'consoleLights',
    '18': 'alert',
    '30': 'finDevice',
    '31': 'finSypply',
    '32': 'finSupplyMediaInput',
    '33': 'finAttributeTable',
}

# old
#printer_alerts_state_map = {
#  2: [ 8, 1101, 1102, 1112, 1114, 1115 ],
#  1: [ 2, 9, 12, 13, 801, 1104 ],
#  0: [ 1, 4, 6, 7, 19, 20, 22, 23, 24, 25, 27, 35, 36, 37, 38,
#       502, 503, 504, 505, 506, 507, 802, 803, 804, 805,
#       806, 807, 808, 809, 810, 1001, 1002, 1005, 1106,
#       1107, 1108, 1111, 1113, 1302, 1304, 1501, 1502,
#       1503, 1504, 1505, 1506, 1509 ],
#}

printer_code_map = {
    "1": ("other", 0),
    "2": ("unknown", 1),
    "3": ("coverOpen", 1),
    "4": ("coverClosed", 0),
    "5": ("interlockOpen", 3),
    "6": ("interlockClosed", 0),
    "7": ("configurationChange", 0),
    "8": ("jam", 2),
    "9": ("subunitMissing", 1),
    "10": ("subunitLifeAlmostOver", 1),
    "11": ("subunitLifeOver", 2),
    "12": ("subunitAlmostEmpty", 1),
    "13": ("subunitEmpty", 1),
    "14": ("subunitAlmostFull", 1),
    "15": ("subunitFull", 1),
    "16": ("subunitNearLimit", 1),
    "17": ("subunitAtLimit", 2),
    "18": ("subunitOpened", 1),
    "19": ("subunitClosed", 0),
    "20": ("subunitTurnedOn", 0),
    "21": ("subunitTurnedOff", 1),
    "22": ("subunitOffline", 0),
    "23": ("subunitPowerSaver", 0),
    "24": ("subunitWarmingUp", 0),
    "25": ("subunitAdded", 0),
    "26": ("subunitRemoved", 3),
    "27": ("subunitResourceAdded", 0),
    "28": ("subunitResourceRemoved", 1),
    "29": ("subunitRecoverableFailure", 1),
    "30": ("subunitUnrecoverableFailure", 2),
    "31": ("subunitRecoverableStorageError", 1),
    "32": ("subunitUnrecoverableStorageError", 2),
    "33": ("subunitMotorFailure", 1),
    "34": ("subunitMemoryExhausted", 1),
    "35": ("subunitUnderTemperature", 0),
    "36": ("subunitOverTemperature", 0),
    "37": ("subunitTimingFailure", 0),
    "38": ("subunitThermistorFailure", 0),
    "501": ("doorOpen", 1),
    "502": ("doorClosed", 0),
    "503": ("powerUp", 0),
    "504": ("powerDown", 0),
    "505": ("printerNMSReset", 0),
    "506": ("printerManualReset", 0),
    "507": ("printerReadyToPrint", 0),
    "801": ("inputMediaTrayMissing", 1),
    "802": ("inputMediaSizeChange", 0),
    "803": ("inputMediaWeightChange", 0),
    "804": ("inputMediaTypeChange", 0),
    "805": ("inputMediaColorChange", 0),
    "806": ("inputMediaFormPartsChange", 0),
    "807": ("inputMediaSupplyLow", 0),
    "808": ("inputMediaSupplyEmpty", 0),
    "809": ("inputMediaChangeRequest", 0),
    "810": ("inputManualInputRequest", 0),
    "811": ("inputTrayPositionFailure", 1),
    "812": ("inputTrayElevationFailure", 1),
    "813": ("inputCannotFeedSizeSelected", 0),
    "901": ("outputMediaTrayMissing", 1),
    "902": ("outputMediaTrayAlmostFull", 0),
    "903": ("outputMediaTrayFull", 1),
    "904": ("outputMailboxSelectFailure", 1),
    "1001": ("markerFuserUnderTemperature", 0),
    "1002": ("markerFuserOverTemperature", 0),
    "1003": ("markerFuserTimingFailure", 1),
    "1004": ("markerFuserThermistorFailure", 1),
    "1005": ("markerAdjustingPrintQuality", 0),
    "1101": ("markerTonerEmpty", 2),
    "1102": ("markerInkEmpty", 2),
    "1103": ("markerPrintRibbonEmpty", 2),
    "1104": ("markerTonerAlmostEmpty", 1),
    "1105": ("markerInkAlmostEmpty", 1),
    "1106": ("markerPrintRibbonAlmostEmpty", 0),
    "1107": ("markerWasteTonerReceptacleAlmostFull", 0),
    "1108": ("markerWasteInkReceptacleAlmostFull", 0),
    "1109": ("markerWasteTonerReceptacleFull", 2),
    "1110": ("markerWasteInkReceptacleFull", 2),
    "1111": ("markerOpcLifeAlmostOver", 0),
    "1112": ("markerOpcLifeOver", 2),
    "1113": ("markerDeveloperAlmostEmpty", 0),
    "1114": ("markerDeveloperEmpty", 2),
    "1115": ("markerTonerCartridgeMissing", 2),
    "1301": ("mediaPathMediaTrayMissing", 1),
    "1302": ("mediaPathMediaTrayAlmostFull", 0),
    "1303": ("mediaPathMediaTrayFull", 2),
    "1304": ("mediaPathCannotDuplexMediaSelected", 0),
    "1501": ("interpreterMemoryIncrease", 0),
    "1502": ("interpreterMemoryDecrease", 0),
    "1503": ("interpreterCartridgeAdded", 0),
    "1504": ("interpreterCartridgeDeleted", 0),
    "1505": ("interpreterResourceAdded", 0),
    "1506": ("interpreterResourceDeleted", 0),
    "1507": ("interpreterResourceUnavailable", 3),
    "1509": ("interpreterComplexPageEncountered", 0),
}

# Some printers send a code of -1 but an additional text
# that allows us to generate a useful state - at the price
# of providing texts in the native language of the country
# of the printers user.

printer_alerts_text_map = {
    'Energiesparen': 0,
    'Sleep': 0,
}


def inventory_printer_alerts(info):
    return [(None, None)]


def check_printer_alerts(_not_used, _not_used1, info):
    # Filter out empty status lines (e.g. sent by Brother)
    info = [i for i in info if i[1:5] != ["0", "0", "0", ""]]
    if not info:
        return (0, 'No alerts present')

    sum_state = 0
    sum_txt = []
    for sev, group, group_index, code, desc in info:

        code_txt, state = printer_code_map.get(code, ('unknown alert code: %s' % code, 3))

        if desc in printer_alerts_text_map:
            state = printer_alerts_text_map[desc]
            if state != 0:
                sum_state = max(state, sum_state)
                sum_txt.append(desc)
            continue

        # Code not found -> take into account severity
        if state == 3 and sev == '1':
            state = 0

        # determine the total(sum) state of the check
        if state == 2:
            sum_state = 2
        elif state == 3 and sum_state != 2:
            sum_state = 3
        elif state > sum_state:
            sum_state = max(state, sum_state)

        # collect the check output

        info_txt = printer_alerts_group_map.get(group, 'unknown alert group %s' % group)
        if group_index != '-1' and info_txt.startswith("unknown alert group"):
            info_txt += '#%s' % group_index
        info_txt += ": "
        if desc != "":
            info_txt += "%s" % desc
        elif code != "-1":
            info_txt += "%s" % code_txt
        sum_txt.append(info_txt)

    if len(sum_txt) == 0:
        sum_txt.append("No alerts found")

    return (sum_state, ', '.join(sum_txt))


# no longer used
# check_config_variables.append("printer_alerts_state_map")

check_config_variables.append("printer_alerts_text_map")

check_info["printer_alerts"] = {
    'check_function': check_printer_alerts,
    'inventory_function': inventory_printer_alerts,
    'service_description': 'Alerts',
    'snmp_info': (
        '.1.3.6.1.2.1.43.18.1.1',
        [
            '2',  # prtAlertSeverityLevel
            '4',  # prtAlertGroup
            '5',  # prtAlertGroupIndex
            '7',  # prtAlertCode
            '8',  # prtAlertDescription
        ]),
    'handle_empty_info': True,
    'snmp_scan_function': lambda oid: oid(".1.3.6.1.2.1.43.11.1.1.6.1.1") is not None,
}
