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

# For more information about the used API and data refer to: https://support.hpe.com/hpesc/public/docDisplay?docId=c03606339

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

factory_settings["threepar_ports_default_levels"] = {
    "1_link": 1,
    "2_link": 1,
    "3_link": 1,
    "4_link": 0,
    "5_link": 2,
    "6_link": 2,
    "7_link": 1,
    "8_link": 0,
    "9_link": 1,
    "10_link": 1,
    "11_link": 1,
    "12_link": 1,
    "13_link": 1,
    "14_link": 1,
    "1_fail": 0,
    "2_fail": 2,
    "3_fail": 2,
    "4_fail": 2,
    "5_fail": 2,
    "6_fail": 2,
    "7_fail": 1,
}


def translate_protocol_3par_ports(number):
    protocols = {
        1: "FC",
        2: "iSCSI",
        3: "FCOE",
        4: "IP",
        5: "SAS",
        6: "NVMe",
    }
    return protocols.get(number)


def inventory_3par_ports(parsed):
    for entry in parsed.get("members", {}):
        translated_protocol = translate_protocol_3par_ports(entry["protocol"])

        # Only create an item if not "FREE" (type = 3) and if the protocol is known
        if not entry.get("type", 3) == 3 and translated_protocol is not None:
            item = "%s Node %s Slot %s Port %s" % (
                translated_protocol,
                entry["portPos"]["node"],
                entry["portPos"]["slot"],
                entry["portPos"]["cardPort"],
            )
            yield (item, {})


def check_3par_ports(item, params, parsed):
    failover_translate = {
        1: "NONE",
        2: "FAILOVER_PENDING",
        3: "FAILED_OVER",
        4: "ACTIVE",
        5: "ACTIVE_DOWN",
        6: "ACTIVE_FAILED",
        7: "FAILBACK_PENDING",
    }

    link_translate = {
        1: "CONFIG_WAIT",
        2: "ALPA_WAIT",
        3: "LOGIN_WAIT",
        4: "READY",
        5: "LOSS_SYNC",
        6: "ERROR_STATE",
        7: "XXX",
        8: "NONPARTICIPATE",
        9: "COREDUMP",
        10: "OFFLINE",
        11: "FWDEAD",
        12: "IDLE_FOR_RESET",
        13: "DHCP_IN_PROGRESS",
        14: "PENDING_RESET",
    }

    mode_translate = {
        1: "SUSPENDED",
        2: "TARGET",
        3: "INITIATOR",
        4: "PEER",
    }

    for entry in parsed.get("members", {}):

        translated_protocol = translate_protocol_3par_ports(entry["protocol"])

        if translated_protocol is None:
            continue

        if item == "%s Node %s Slot %s Port %s" % (
            translated_protocol,
            entry["portPos"]["node"],
            entry["portPos"]["slot"],
            entry["portPos"]["cardPort"],
        ):

            if "label" in entry:
                yield 0, "Label: %s" % entry["label"]

            if "linkState" in entry:
                state = entry["linkState"]
                yield params["%s_link" % state], link_translate[state]

            if "portWWN" in entry:
                yield 0, "portWWN: %s" % entry["portWWN"]

            if "mode" in entry:
                yield 0, "Mode: %s" % mode_translate[entry["mode"]]

            if "failoverState" in entry:
                state = entry["failoverState"]
                yield params["%s_fail" % state], "Failover: %s" % failover_translate[state]


check_info["3par_ports"] = {
    "parse_function": parse_3par,
    "inventory_function": inventory_3par_ports,
    "check_function": check_3par_ports,
    "service_description": "Port %s",
    "default_levels_variable": "threepar_ports_default_levels",
    "group": "threepar_ports",
}
