#!/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.ibm_svc import *  # pylint: disable=wildcard-import,unused-wildcard-import

# Example output from agent:
# <<<ibm_svc_enclosure:sep(58)>>>
# 1:online:control:yes:0:io_grp0:2072-24C:7804037:2:2:2:2:24
# 2:online:expansion:yes:0:io_grp0:2072-24E:7804306:2:2:2:2:24
# 3:online:expansion:yes:0:io_grp0:2072-24E:7804326:2:2:2:2:24
# 4:online:expansion:yes:0:io_grp0:2072-24E:7804352:2:2:2:2:24

# After a firmware upgrade the output looked like this:
# 1:online:control:yes:0:io_grp0:2072-24C:7804037:2:2:2:2:24:0:0
# 2:online:expansion:yes:0:io_grp0:2072-24E:7804306:2:2:2:2:24:0:0
# 3:online:expansion:yes:0:io_grp0:2072-24E:7804326:2:2:2:2:24:0:0
# 4:online:expansion:yes:0:io_grp0:2072-24E:7804352:2:2:2:2:24:0:0

# FW >= 7.8
# 1:online:control:yes:0:io_grp0:2072-24C:7804037:2:2:2:2:24:0:0:0:0
# 2:online:expansion:yes:0:io_grp0:2072-24E:7804306:2:2:2:2:24:0:0:0:0
# 3:online:expansion:yes:0:io_grp0:2072-24E:7804326:2:2:2:2:24:0:0:0:0
# 4:online:expansion:yes:0:io_grp0:2072-24E:7804352:2:2:2:2:24:0:0:0:0

# The names of the columns are:
# id:status:type:managed:IO_group_id:IO_group_name:product_MTM:serial_number:total_canisters:online_canisters:total_PSUs:online_PSUs:drive_slots:total_fan_modules:online_fan_modules:total_sems:online_sems

# IBM-FLASH900
# <<<ibm_svc_enclosure:sep(58)>>>
# id:status:type:product_MTM:serial_number:total_canisters:online_canisters:online_PSUs:drive_slots
# 1:online:control:9843-AE2:6860407:2:2:2:12


def parse_ibm_svc_enclosure(info):
    dflt_header = _get_ibm_svc_enclosure_dflt_header(info)
    if dflt_header is None:
        return {}

    parsed = {}
    for id_, rows in parse_ibm_svc_with_header(info, dflt_header).items():
        try:
            data = rows[0]
        except IndexError:
            continue
        parsed.setdefault(id_, data)
    return parsed


def _try_int(string):
    try:
        return int(string)
    except (ValueError, TypeError):
        return None


@get_parsed_item_data
def check_ibm_svc_enclosure(item, params, data):
    if params is None:
        params = {}

    enclosure_status = data["status"]
    if enclosure_status == "online":
        status = 0
    else:
        status = 2
    yield status, "Status: %s" % enclosure_status

    for key, label in [
        ("canisters", "canisters"),
        ("PSUs", "PSUs"),
        ("fan_modules", "fan modules"),
        ("sems", "secondary expander modules"),
    ]:
        online = _try_int(data.get("online_%s" % key))
        total = _try_int(data.get("total_%s" % key))
        if online is None:
            continue
        # Valid values for WATO rule value levels_lower_online_canisters are
        # False, which shall be mapped to (total, total) or (warn, crit).
        levels_lower = params.get("levels_lower_online_%s" % key) or (total, total)
        levels = (None, None) + levels_lower
        state, infotext, _perfdata = check_levels(
            online, None, levels, human_readable_func=int, infoname="Online %s" % label
        )
        if total is not None:
            infotext += " of %s" % total
        yield state, infotext


check_info["ibm_svc_enclosure"] = {
    "parse_function": parse_ibm_svc_enclosure,
    "check_function": check_ibm_svc_enclosure,
    "inventory_function": discover(),
    "service_description": "Enclosure %s",
    "group": "ibm_svc_enclosure",
}

#   .--helper--------------------------------------------------------------.
#   |                    _          _                                      |
#   |                   | |__   ___| |_ __   ___ _ __                      |
#   |                   | '_ \ / _ \ | '_ \ / _ \ '__|                     |
#   |                   | | | |  __/ | |_) |  __/ |                        |
#   |                   |_| |_|\___|_| .__/ \___|_|                        |
#   |                                |_|                                   |
#   '----------------------------------------------------------------------'


def _get_ibm_svc_enclosure_dflt_header(info):
    try:
        first_line = info[0]
    except IndexError:
        return

    if len(first_line) == 9:
        return [
            "id",
            "status",
            "type",
            "product_MTM",
            "serial_number",
            "total_canisters",
            "online_canisters",
            "online_PSUs",
            "drive_slots",
        ]
    elif len(first_line) == 13:
        return [
            "id",
            "status",
            "type",
            "managed",
            "IO_group_id",
            "IO_group_name",
            "product_MTM",
            "serial_number",
            "total_canisters",
            "online_canisters",
            "total_PSUs",
            "online_PSUs",
            "drive_slots",
        ]
    elif len(first_line) == 15:
        return [
            "id",
            "status",
            "type",
            "managed",
            "IO_group_id",
            "IO_group_name",
            "product_MTM",
            "serial_number",
            "total_canisters",
            "online_canisters",
            "total_PSUs",
            "online_PSUs",
            "drive_slots",
            "total_fan_modules",
            "online_fan_modules",
        ]
    elif len(first_line) == 17:
        return [
            "id",
            "status",
            "type",
            "managed",
            "IO_group_id",
            "IO_group_name",
            "product_MTM",
            "serial_number",
            "total_canisters",
            "online_canisters",
            "total_PSUs",
            "online_PSUs",
            "drive_slots",
            "total_fan_modules",
            "online_fan_modules",
            "total_sems",
            "online_sems",
        ]
    return
