#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2019 tribe29 GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

# Author: Lars Michelsen <lm@mathias-kettner.de

# Example output of agent:
# <<<sylo>>>
#            7859            7859           10240
#
# Syntax of the hint file:
#
# +------------------------------------------+
# | in offset (Ascii, space padded, bytes)   |  16 Bytes
# +------------------------------------------+
# | out offset                               |  16 Bytes
# +------------------------------------------+
# | Size of sylo                             |  16 Bytes
# +------------------------------------------+
#
# The check_mk_agents add the mtime in front of the hint file contents

# 0: alive_report (max age of hint file in seconds)
# 1: warn fill level in percent
# 2: crit fill level in percent
sylo_default_levels = (70, 5, 25)


def inventory_sylo(info):
    if len(info) > 0 and len(info[0]) == 4:
        return [(None, "", "sylo_default_levels")]


def check_sylo(item, params, info):
    if len(info) != 1:
        return (2, "No hint file (sylo probably never ran on this system)")

    if len(info[0]) == 4:
        msg = ""

        alive_report, warn, crit = params

        mtime = int(info[0][0])
        inOffset = int(info[0][1])
        outOffset = int(info[0][2])
        size = int(info[0][3])
        size_mb = size / (1024 * 1024.0)
        warn_mb = size_mb * warn / 100.0
        crit_mb = size_mb * crit / 100.0

        # CRIT: too old
        now = int(time.time())
        age = now - mtime
        if age > alive_report:
            status = 2
            return (2, "Sylo not running (Hintfile too old: last update %d secs ago)" % age)

        # Current fill state
        if inOffset == outOffset:
            bytesUsed = 0
        elif inOffset > outOffset:
            bytesUsed = inOffset - outOffset
        elif inOffset < outOffset:
            bytesUsed = size - outOffset + inOffset
        percUsed = float(bytesUsed) / size * 100
        used_mb = bytesUsed / (1024 * 1024.0)

        # Rates for input and output
        in_rate = get_rate("sylo.in", mtime, inOffset)
        out_rate = get_rate("sylo.out", mtime, outOffset)
        msg += "Silo is filled %.1fMB (%.1f%%), in %.1f B/s, out %.1f B/s" % (
            bytesUsed / (1024 * 1024.0),
            percUsed,
            in_rate,
            out_rate,
        )

        status = 0
        if percUsed >= crit and status < 2:
            status = 2
        elif percUsed >= warn and status < 1:
            status = 1

        return (
            status,
            msg,
            [
                ("in", "%f" % in_rate),
                ("out", "%f" % out_rate),
                ("used", "%f" % used_mb, warn_mb, crit_mb, 0, size_mb),
            ],
        )

    return (3, "Invalid hint file contents: %s" % info)


check_info["sylo"] = {
    "check_function": check_sylo,
    "inventory_function": inventory_sylo,
    "service_description": "Sylo",
    "has_perfdata": True,
}
