#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# |             ____ _               _        __  __ _  __           |
# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
# |                                                                  |
# | Copyright Mathias Kettner 2017             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_ddn_s2a_errors(info):
    preparsed = parse_ddn_s2a_api_response(info)
    return {
                "port_type"         : preparsed[u"port_type"],
                "link_failure_errs" : map(int, preparsed[u"link_failure_errs"]),
                "lost_sync_errs"    : map(int, preparsed[u"lost_sync_errs"]),
                "loss_of_signal_errs"  : map(int, preparsed[u"loss_of_sig_errs"]),
                "prim_seq_errs"     : map(int, preparsed[u"prim_seq_errs"]),
                "crc_errs"          : map(int, preparsed[u"CRC_errs"]),
                "receive_errs"      : map(int, preparsed[u"receive_errs"]),
                "ctio_timeouts"     : map(int, preparsed[u"CTIO_timeouts"]),
                "ctio_xmit_errs"    : map(int, preparsed[u"CTIO_xmit_errs"]),
                "ctio_other_errs"   : map(int, preparsed[u"CTIO_other_errs"]),
           }


def inventory_ddn_s2a_errors(parsed):

    def value_to_levels(value):
        # As the values in this check are all error counters since last reset,
        # we calculate default levels according to the current counter state,
        # so we'll be warned if an error occurs.
        return (value + 1, value + 5)

    for nr, port_type in enumerate(parsed[u"port_type"]):


        # Note: The API command returning the port errors that we evaluate
        #       in this check differentiates between FC and IB ports, providing
        #       different values according to port type. As we have no example
        #       for the IB ports at this time, we only implement logic for what
        #       we can test.
        if port_type == u"FC":

            yield "%d" % (nr + 1), {
                "link_failure_errs" : value_to_levels(parsed["link_failure_errs"][nr]),
                "lost_sync_errs"    : value_to_levels(parsed["lost_sync_errs"][nr]),
                "loss_of_signal_errs"  : value_to_levels(parsed["loss_of_signal_errs"][nr]),
                "prim_seq_errs"     : value_to_levels(parsed["prim_seq_errs"][nr]),
                "crc_errs"          : value_to_levels(parsed["crc_errs"][nr]),
                "receive_errs"      : value_to_levels(parsed["receive_errs"][nr]),
                "ctio_timeouts"     : value_to_levels(parsed["ctio_timeouts"][nr]),
                "ctio_xmit_errs"    : value_to_levels(parsed["ctio_xmit_errs"][nr]),
                "ctio_other_errs"   : value_to_levels(parsed["ctio_other_errs"][nr]),
                }


def check_ddn_s2a_errors(item, params, parsed):

    def check_errors(value, levels, infotext_formatstring):
        infotext = infotext_formatstring % value
        if levels is None:
            return 0, infotext
        else:
            warn, crit = levels
            levelstext = " (warn/crit at %d/%d errors)" % (warn, crit)
            if value >= crit:
                status = 2
                infotext += levelstext
            elif value >= warn:
                status = 1
                infotext += levelstext
            else:
                status = 0
            return status, infotext

    nr = int(item) - 1
    link_failure_errs   = parsed["link_failure_errs"][nr]
    lost_sync_errs      = parsed["lost_sync_errs"][nr]
    loss_of_signal_errs = parsed["loss_of_signal_errs"][nr]
    prim_seq_errs       = parsed["prim_seq_errs"][nr]
    crc_errs            = parsed["crc_errs"][nr]
    receive_errs        = parsed["receive_errs"][nr]
    ctio_timeouts       = parsed["ctio_timeouts"][nr]
    ctio_xmit_errs      = parsed["ctio_xmit_errs"][nr]
    ctio_other_errs     = parsed["ctio_other_errs"][nr]

    yield check_errors(link_failure_errs, params["link_failure_errs"], "Link failure errors: %d")
    yield check_errors(lost_sync_errs, params["lost_sync_errs"], "Lost sync errors: %d")
    yield check_errors(loss_of_signal_errs, params["loss_of_signal_errs"], "Loss of signal errors: %d")
    yield check_errors(prim_seq_errs, params["prim_seq_errs"], "PrimSeq errors: %d") # TODO: What is this?
    yield check_errors(crc_errs, params["crc_errs"], "CRC errors: %d")
    yield check_errors(receive_errs, params["receive_errs"], "Receive errors: %d")
    yield check_errors(ctio_timeouts, params["ctio_timeouts"], "CTIO timeouts: %d")
    yield check_errors(ctio_xmit_errs, params["ctio_xmit_errs"], "CTIO transmission errors: %d")
    yield check_errors(ctio_other_errs, params["ctio_other_errs"], "CTIO other errors: %d")


check_info['ddn_s2a_errors'] = {
    'parse_function'        : parse_ddn_s2a_errors,
    'inventory_function'    : inventory_ddn_s2a_errors,
    'check_function'        : check_ddn_s2a_errors,
    'service_description'   : 'DDN S2A Port Errors %s',
    'includes'              : [ "ddn_s2a.include" ],
    'group'                 : "ddn_s2a_port_errors",
}
