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

# NOTE: Careful when replacing the *-import below with a more specific import. This can cause
# problems because it might remove variables from the check-context which are necessary for
# resolving legacy discovery results such as [("SUMMARY", "diskstat_default_levels")]. Furthermore,
# it might also remove variables needed for accessing discovery rulesets.
from cmk.base.check_legacy_includes.f5_bigip import *  # pylint: disable=wildcard-import,unused-wildcard-import

factory_settings["f5_bigip_conns_default_levels"] = {
    "conns": (25000, 30000),
    "ssl_conns": (25000, 30000),
    "http_req_rate": (500, 1000),
}


def inventory_f5_bigip_conns(info):
    if info:
        return [(None, {})]


def get_conn_rate_params(params):
    # upper_bound is dict, tuple or None
    upper_bound = params.get("connections_rate", (None, None))
    # lower_bound is tuple or None
    lower_bound = params.get("connections_rate_lower", (None, None))
    if isinstance(upper_bound, tuple):
        return upper_bound + lower_bound

    # Lower bound was not configured, all good
    if isinstance(upper_bound, dict) and lower_bound == (None, None):
        return upper_bound
    raise ValueError(
        "Can't configure minimum connections per second when the maximum "
        "connections per second is setup in predictive levels. Please use the given "
        "lower bound specified in the maximum connections, or set maximum "
        "connections to use fixed levels."
    )


def check_f5_bigip_conns(item, params, info):
    # Connection rate
    now = time.time()
    total_native_compat_rate = 0
    conns_dict = {}

    for line in info:
        if line[2] != "":
            native_conn_rate = get_rate("native", now, int(line[2]))
        else:
            native_conn_rate = 0

        if line[3] != "":
            compat_conn_rate = get_rate("compat", now, int(line[3]))
        else:
            compat_conn_rate = 0

            total_native_compat_rate += native_conn_rate + compat_conn_rate

        if line[4] != "":
            stat_http_req_rate = get_rate("stathttpreqs", now, int(line[4]))
        else:
            stat_http_req_rate = None

        if line[0] != "":
            conns_dict.setdefault("total", 0)
            conns_dict["total"] += int(line[0])

        if line[1] != "":
            conns_dict.setdefault("total_ssl", 0)
            conns_dict["total_ssl"] += int(line[1])

    try:
        conn_rate_params = get_conn_rate_params(params)
    except ValueError as err:
        yield 3, str(err)
        return

    # Current connections
    for val, params_values, perfkey, title in [
        (conns_dict.get("total"), params.get("conns"), "connections", "Connections"),
        (
            conns_dict.get("total_ssl"),
            params.get("ssl_conns"),
            "connections_ssl",
            "SSL connections",
        ),
        (total_native_compat_rate, conn_rate_params, "connections_rate", "Connections/s"),
        (stat_http_req_rate, params.get("http_req_rate"), "requests_per_second", "HTTP requests/s"),
    ]:

        # SSL may not be configured, eg. on test servers
        if val is None:
            yield 0, "%s: not configured" % title
        else:
            yield check_levels(val, perfkey, params_values, infoname=title)


check_info["f5_bigip_conns"] = {
    "check_function": check_f5_bigip_conns,
    "inventory_function": inventory_f5_bigip_conns,
    "service_description": "Open Connections",
    "snmp_info": (
        ".1.3.6.1.4.1.3375.2.1.1.2",
        [
            "1.8",  # F5-BIGIP-SYSTEM-MIB::sysStatClientCurConns
            "9.2",  # F5-BIGIP-SYSTEM-MIB::sysClientsslStatCurConns
            "9.6",  # F5-BIGIP-SYSTEM-MIB::sysClientSslStatTotNativeConns
            "9.9",  # F5-BIGIP-SYSTEM-MIB::sysClientSslStatTotCompatConns
            "1.56",  # F5-BIGIP-SYSTEM-MIB::sysStatHttpRequests
        ],
    ),
    "snmp_scan_function": scan_f5_bigip,
    "has_perfdata": True,
    "group": "f5_connections",
    "default_levels_variable": "f5_bigip_conns_default_levels",
}
