#!/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_stats(info):
    parsed = parse_ddn_s2a_api_response(info)

    for key in parsed.keys():
        if key.startswith(u"All_ports"):
            parsed[key] = parsed[key][0]

    return parsed


#   .--Read hits-----------------------------------------------------------.
#   |               ____                _   _     _ _                      |
#   |              |  _ \ ___  __ _  __| | | |__ (_) |_ ___                |
#   |              | |_) / _ \/ _` |/ _` | | '_ \| | __/ __|               |
#   |              |  _ <  __/ (_| | (_| | | | | | | |_\__ \               |
#   |              |_| \_\___|\__,_|\__,_| |_| |_|_|\__|___/               |
#   |                                                                      |
#   '----------------------------------------------------------------------'

ddn_s2a_readhits_default_levels = (85.0, 70.0)

def inventory_ddn_s2a_stats_readhits(parsed):
    if u"All_ports_Read_Hits" in parsed:
        yield "Total", "ddn_s2a_readhits_default_levels"
    for nr, _  in enumerate(parsed.get(u"Read_Hits",[])):
        yield "%d" % (nr + 1), "ddn_s2a_readhits_default_levels"


def check_ddn_s2a_stats_readhits(item, params, parsed):

    if item == "Total":
        read_hits = float(parsed[u"All_ports_Read_Hits"])
    else:
        read_hits = float(parsed[u"Read_Hits"][int(item)-1])

    infotext = "%.1f%%" % read_hits
    if params is None:
        perfdata = [ ("read_hits", read_hits) ] # TODO: Define metric
        status = 0
    else:
        warn, crit = params
        levelstext = " (warn/crit below %.1f/%.1f%%)" % params
        perfdata = [ ("read_hits", read_hits, warn, crit) ]
        if read_hits < crit:
            status = 2
            infotext += levelstext
        elif read_hits < warn:
            status = 1
            infotext += levelstext
        else:
            status = 0

    return status, infotext, perfdata


check_info["ddn_s2a_stats.readhits"] = {
    "inventory_function"    : inventory_ddn_s2a_stats_readhits,
    "check_function"        : check_ddn_s2a_stats_readhits,
    "service_description"   : "DDN S2A Read Hits %s",
    "has_perfdata"          : True,
    "group"                 : "read_hits",
}

#.
#   .--I/O transactions----------------------------------------------------.
#   |                            ___    _____                              |
#   |                           |_ _|  / / _ \                             |
#   |                            | |  / / | | |                            |
#   |                            | | / /| |_| |                            |
#   |                           |___/_/  \___/                             |
#   |                                                                      |
#   |      _                                  _   _                        |
#   |     | |_ _ __ __ _ _ __  ___  __ _  ___| |_(_) ___  _ __  ___        |
#   |     | __| '__/ _` | '_ \/ __|/ _` |/ __| __| |/ _ \| '_ \/ __|       |
#   |     | |_| | | (_| | | | \__ \ (_| | (__| |_| | (_) | | | \__ \       |
#   |      \__|_|  \__,_|_| |_|___/\__,_|\___|\__|_|\___/|_| |_|___/       |
#   |                                                                      |
#   '----------------------------------------------------------------------'

factory_settings["ddn_s2a_stats_io_default_levels"] = {
    "total" : (28000, 33000),
}


def inventory_ddn_s2a_stats_io(parsed):
    if  u"All_ports_Read_IOs" in parsed:
        yield "Total", {}
    for nr, _ in enumerate(parsed.get(u"Read_IOs", [])):
        yield "%d" % (nr + 1), {}


def check_ddn_s2a_stats_io(item, params, parsed):

    def check_io_levels(value, levels, infotext_formatstring, perfname=None):
        infotext = infotext_formatstring % value
        if levels is None:
            perfdata = [ (perfname, value) ]
            status = 0
        else:
            warn, crit = levels
            perfdata = [ (perfname, value, warn, crit) ]
            levelstext = " (warn/crit at %.2f/%.2f 1/s)" % (warn, crit)
            if value >= crit:
                status = 2
                infotext += levelstext
            elif value >= warn:
                status = 1
                infotext += levelstext
            else:
                status = 0

        if perfname is None:
            return status, infotext
        else:
            return status, infotext, perfdata

    if item == "Total":
        read_ios_s = float(parsed[u"All_ports_Read_IOs"])
        write_ios_s = float(parsed[u"All_ports_Write_IOs"])
    else:
        read_ios_s = float(parsed[u"Read_IOs"][int(item)-1])
        write_ios_s = float(parsed[u"Write_IOs"][int(item)-1])
    total_ios_s = read_ios_s + write_ios_s

    yield check_io_levels(read_ios_s, params.get("read"), "Read: %.2f 1/s", "disk_read_ios")
    yield check_io_levels(write_ios_s, params.get("write"), "Write: %.2f 1/s", "disk_write_ios")
    yield check_io_levels(total_ios_s, params.get("total"), "Total: %.2f 1/s")


check_info["ddn_s2a_stats.io"] = {
    "default_levels_variable"   : "ddn_s2a_stats_io_default_levels",
    "inventory_function"        : inventory_ddn_s2a_stats_io,
    "check_function"            : check_ddn_s2a_stats_io,
    "service_description"       : "DDN S2A IO %s",
    "has_perfdata"              : True,
    "group"                     : "storage_iops",
}

#.
#   .--Data rate-----------------------------------------------------------.
#   |              ____        _                    _                      |
#   |             |  _ \  __ _| |_ __ _   _ __ __ _| |_ ___                |
#   |             | | | |/ _` | __/ _` | | '__/ _` | __/ _ \               |
#   |             | |_| | (_| | || (_| | | | | (_| | ||  __/               |
#   |             |____/ \__,_|\__\__,_| |_|  \__,_|\__\___|               |
#   |                                                                      |
#   '----------------------------------------------------------------------'

factory_settings["ddn_s2a_stats_default_levels"] = {
    "total" : (4800*1024*1024, 5500*1024*1024),
}


def inventory_ddn_s2a_stats(parsed):
    if u"All_ports_Read_MBs" in parsed:
        yield "Total", {}
    for nr, value in enumerate(parsed.get(u"Read_MBs",[])):
        yield "%d" % (nr + 1), {}


def check_ddn_s2a_stats(item, params, parsed):

    def check_datarate_levels(value, value_mb, levels, infotext_formatstring, perfname=None):
        infotext = infotext_formatstring % value_mb
        if levels is None:
            perfdata = [ (perfname, value) ]
            status = 0
        else:
            warn, crit = levels
            warn_mb, crit_mb = map(lambda x: x/(1024*1024.0), levels)
            perfdata = [ (perfname, value, warn, crit) ]
            levelstext = " (warn/crit at %.2f/%.2f MB/s)" % (warn_mb, crit_mb)
            if value >= crit:
                status = 2
                infotext += levelstext
            elif value >= warn:
                status = 1
                infotext += levelstext
            else:
                status = 0

        if perfname is None:
            return status, infotext
        else:
            return status, infotext, perfdata


    if item == "Total":
        read_mb_s = float(parsed[u"All_ports_Read_MBs"])
        write_mb_s = float(parsed[u"All_ports_Write_MBs"])
    else:
        read_mb_s = float(parsed[u"Read_MBs"][int(item) - 1])
        write_mb_s = float(parsed[u"Write_MBs"][int(item) - 1])
    total_mb_s = read_mb_s + write_mb_s
    read = read_mb_s * 1024 * 1024
    write = write_mb_s * 1024 * 1024
    total = total_mb_s * 1024 * 1024

    yield check_datarate_levels(read, read_mb_s, params.get("read"), "Read: %.2f MB/s", "disk_read_throughput")
    yield check_datarate_levels(write, write_mb_s, params.get("write"), "Write: %.2f MB/s", "disk_write_throughput")
    yield check_datarate_levels(total, total_mb_s, params.get("total"), "Total: %.2f MB/s")


check_info["ddn_s2a_stats"] = {
    "default_levels_variable"   : "ddn_s2a_stats_default_levels",
    "parse_function"            : parse_ddn_s2a_stats,
    "inventory_function"        : inventory_ddn_s2a_stats,
    "check_function"            : check_ddn_s2a_stats,
    "service_description"       : "DDN S2A Data Rate %s",
    "includes"                  : [ "ddn_s2a.include" ],
    "group"                     : "storage_throughput",
    "has_perfdata"              : True,
}
