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

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

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

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


def parse_storeonce4x_appliances(info):

    parsed = {}
    app_state_map = {"Reachable": 0}

    # Currently used metrics
    properties_federation = (
        "hostname",
        "address",
        "productName",
        "serialNumber",
        "localhost",
        "applianceState",
        "stateUpdatedDate",
        "federationApiVersion",
        "applianceStateString",
        "sinceStateUpdatedSeconds",
    )

    properties_dashboard = (
        "softwareUpdateRecommended",
        "softwareVersion",
        "localFreeBytes",
        "localCapacityBytes",
        "cloudFreeBytes",
        "cloudCapacityBytes",
        "metricsCpuTotal",
        "metricsMemoryUsedPercent",
        "metricsDataDiskUtilisationPercent",
        "applianceStatusString",
        "dataServicesStatusString",
        "licenseStatus",
        "licenseStatusString",
        "userStorageStatusString",
        "hardwareStatusString",
        "catStoresSummary",
        "cloudBankStoresSummary",
        "nasSharesSummary",
        "vtlLibrariesSummary",
        "nasRepMappingSummary",
        "vtlRepMappingSummary",
        "dedupeRatio",
    )

    federation_json = json.loads(info[0][0])
    dashboard_json_list = [json.loads(json_obj[0]) for json_obj in info[1:]]

    for member in federation_json["members"]:

        hostname = member["hostname"]

        parsed[hostname] = {}
        for mem_property in properties_federation:
            parsed[hostname][mem_property] = member[mem_property]

        parsed[hostname]["cmk_state"] = app_state_map.get(member["applianceStateString"], 3)

    # For every member uuid, we have more metrics in the dashboard
    for hostname in parsed:
        for dashboard_elem in dashboard_json_list:
            if hostname == dashboard_elem["hostname"]:
                for dashboard_property in properties_dashboard:
                    parsed[hostname][dashboard_property] = dashboard_elem[dashboard_property]

        # Calculate missing metrics (which where previously available in REST API 3x)
        for name in ("Free", "Capacity"):
            parsed[hostname]["combined%sBytes" % name] = (
                parsed[hostname]["cloud%sBytes" % name] + parsed[hostname]["local%sBytes" % name]
            )

    return parsed


def discovery_storeonce4x_appliances(parsed):
    for host in parsed.keys():
        yield host, {}


@get_parsed_item_data
def check_storeonce4x_appliances(item, params, data):
    yield data[
        "cmk_state"
    ], "State: %s, Serial Number: %s, Software version: %s, Product Name: %s" % (
        data["applianceStateString"],
        data["serialNumber"],
        data["softwareVersion"],
        data["productName"],
    )


check_info["storeonce4x_appliances"] = {
    "parse_function": parse_storeonce4x_appliances,
    "inventory_function": discovery_storeonce4x_appliances,
    "check_function": check_storeonce4x_appliances,
    "service_description": "Appliance %s Status",
}


@get_parsed_item_data
def check_storeonce4x_appliances_storage(item, params, data):
    return check_storeonce_space(item, params, data)


check_info["storeonce4x_appliances.storage"] = {
    "parse_function": parse_storeonce4x_appliances,
    "inventory_function": discovery_storeonce4x_appliances,
    "check_function": check_storeonce4x_appliances_storage,
    "service_description": "Appliance %s Storage",
    "group": "filesystem",
    "has_perfdata": True,
}


@get_parsed_item_data
def check_storeonce4x_appliances_license(item, params, data):

    license_map = {"OK": 0, "WARNING": 1, "CRITICAL": 2, "NOT_HARDWARE": 3, "NOT_APPLICABLE": 3}
    yield license_map.get(data["licenseStatus"], 3), "Status: %s" % data["licenseStatusString"]


check_info["storeonce4x_appliances.license"] = {
    "parse_function": parse_storeonce4x_appliances,
    "inventory_function": discovery_storeonce4x_appliances,
    "check_function": check_storeonce4x_appliances_license,
    "service_description": "Appliance %s License",
}


@get_parsed_item_data
def check_storeonce4x_appliances_summaries(item, param, data):
    for summary, summary_descr in (
        ("catStoresSummary", "Cat stores"),
        ("cloudBankStoresSummary", "Cloud bank"),
        ("nasSharesSummary", "NAS Shares"),
        ("vtlLibrariesSummary", "VTL Libraries"),
        ("nasRepMappingSummary", "NAS Replication Mapping"),
        ("vtlRepMappingSummary", "VTL Replication Mapping"),
    ):
        for descr, state in (("Ok", 0), ("Warning", 1), ("Critical", 2), ("Unknown", 3)):
            numbers = data[summary]["statusSummary"]["num%s" % descr]
            total = data[summary]["statusSummary"]["total"]
            if numbers == 0:
                continue
            yield state, "%s %s (%s of %s)" % (summary_descr, descr, str(numbers), str(total))


check_info["storeonce4x_appliances.summaries"] = {
    "parse_function": parse_storeonce4x_appliances,
    "inventory_function": discovery_storeonce4x_appliances,
    "check_function": check_storeonce4x_appliances_summaries,
    "service_description": "Appliance %s Summaries",
}
