#!/usr/bin/env python3
# Copyright (C) 2019 Checkmk 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.

# <<<netapp_api_cluster:sep(9)>>>
# current-time    1443882397
# current-mode    non_ha
# is-enabled      true
# state   ERROR
# is-interconnect-up      false
# partner-in-headswap     false
# local-in-headswap       false
# new-partner-sysid       0


from cmk.base.check_api import LegacyCheckDefinition
from cmk.base.config import check_info

from cmk.agent_based.v2 import StringTable


def inventory_netapp_api_cluster(info):
    data = {line[0]: line[1] for line in info if len(line) == 2}
    # non_ha is standalone
    if data.get("current-mode", "").lower() != "non_ha" and data.get("partner") is not None:
        return [(data.get("partner"), {"state": data.get("state", "").lower()})]
    return []


# Cluster states according to docu:
# connected - Partner is available for takeover
# takeover_scheduled - Partner is down and takeover is scheduled
# takeover_started - Takeover process has begun
# takeover - Currently controlling partner's resources.
# taken_over - Partner is controlling filer's resources
# takeover_failed - Failed to takeover the partner
# giving_back - Sendhome process in progress
# giveback_partial_waiting - This node controls partner aggregates even
#                            though the node is not in takeover. And we're waiting for a connection to the partner.
# giveback_partial_connected - This node controls partner aggregates even though the node is not in takeover.
#                              The partner is available to receive the aggregates.
# waiting_for_root_aggr - Partner is controlling dblade's root aggregate If we're in this state, many other optional fields are not returned.
# waiting - Waiting for a connection to partner. Generally happens while partner is rebooting.
# in_maintenance_mode - node is in maintenance mode. In the mode it is not possible to determine more detailed information (e.g. cluster or not; takeover or not, etc).
# pending_shutdown - starting a takeover/sendhome is inhibited due to a pending system shutdown. i
# error - There is an error with the system
# User have to compare the return values case-insensitively.


def check_netapp_api_cluster(item, params, info):
    data = {line[0]: line[1] for line in info if len(line) == 2}

    had_errors = False
    state = data["state"].lower()
    if state == "error":
        had_errors = True
        yield 2, "Cluster state error"
    if state == "takeover":
        had_errors = True
        yield 1, "Cluster takeover"
    elif state == "takeover_failed":
        had_errors = True
        yield 2, "Takeover failed. Reason: %s" % data.get(
            "takeover-failure-reason", "None available"
        )
    elif state != params["state"]:
        had_errors = True
        yield 1, "Cluster state is {}. ({} expected)".format(state, params.get("state"))

    if data.get("is-interconnect-up") != "true":
        had_errors = True
        yield 2, "Cluster interconnect is not up"

    if data.get("current-mode", "") == "non_ha":
        had_errors = True
        yield 1, "Running in stand-alone mode"

    if data.get("partner") != item:
        had_errors = True
        yield 1, "Partner name changed: {} instead of {}".format(data.get("partner", "None"), item)

    if not had_errors:
        yield 0, "Cluster Status OK"


def parse_netapp_api_cluster(string_table: StringTable) -> StringTable:
    return string_table


check_info["netapp_api_cluster"] = LegacyCheckDefinition(
    parse_function=parse_netapp_api_cluster,
    service_name="Cluster with %s",
    discovery_function=inventory_netapp_api_cluster,
    check_function=check_netapp_api_cluster,
    check_default_parameters={},
)
