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

# Original version by Thorsten Bruhns from OPITZ CONSULTING Deutschland GmbH

# <<<oracle_crs_res:sep(124)>>>
# oracle_host|NAME=ora.DG_CLUSTER.dg
# oracle_host|TYPE=ora.diskgroup.type
# oracle_host|STATE=ONLINE on oracle_host
# oracle_host|TARGET=ONLINE
# oracle_host|NAME=ora.I31_ARCH.dg
# oracle_host|TYPE=ora.diskgroup.type
# oracle_host|STATE=ONLINE on oracle_host
# oracle_host|TARGET=ONLINE
# oracle_host|NAME=ora.I31_DATA.dg
# oracle_host|TYPE=ora.diskgroup.type
# oracle_host|STATE=ONLINE on oracle_host
# oracle_host|TARGET=ONLINE
# oracle_host|NAME=ora.I31_MLOG.dg
# oracle_host|TYPE=ora.diskgroup.type
# oracle_host|STATE=ONLINE on oracle_host
# oracle_host|TARGET=ONLINE
# ...usw...


# Parse output into dict of dicts of dicts:
# nodename -> ressource name -> entry
# ressource. Example:
# { 'oracle_host' :
#     { 'ora.I31_ARCH.dg' : {
#           'state': 'ONLINE on ezszds9c',
#           'target': 'ONLINE',
#           'type': 'ora.diskgroup.type'}
#     }
# }
# Returns a pair of CRS node name and the former dict
def parse_oracle_crs_res(info):
    crs_nodename = None
    ressources = {}

    for line in info:
        if len(line) == 1:
            # Seems to be an old version where first column is missing:
            # <<<oracle_crs_res>>>
            # NAME=foo
            # TYPE=bar
            # STATE=baz
            nodename, varsetting = None, line[0]
        else:
            nodename, varsetting = line

        if nodename == "nodename":
            crs_nodename = varsetting
            continue

        key, value = varsetting.split("=", 1)
        if key == "NAME":
            res_name = value
            entry = {}
            ressources.setdefault(res_name, {})
            ressources[res_name][nodename] = entry
        else:
            entry[key.lower()] = value
    return crs_nodename, ressources


def inventory_oracle_crs_res(parsed):
    return [(name, None) for name in parsed[1]]


def check_oracle_crs_res(item, _no_params, parsed):
    _crs_nodename, ressources = parsed

    # In case of missing information we assume that the clusterware
    # is not running and we simple skip the result
    if item not in ressources:
        if item == "ora.cssd":
            yield 2, "Clusterware not running"
        elif item == "ora.crsd":
            yield 2, "Cluster Resource Service Daemon not running!"
        else:
            raise MKCounterWrapped(
                "No ressource details found for %s. Maybe the cssd/crsd is not running" % item
            )
        return

    for nodename, entry in ressources[item].items():
        resstate = entry["state"].split(" ", 1)[0]
        restarget = entry["target"]

        if nodename == "csslocal":
            infotext = "local: "
        elif nodename:
            infotext = "on " + nodename + ": "
        else:
            infotext = ""
        infotext += resstate.lower()

        if resstate != restarget:
            state = 2
            infotext += ", target state %s" % restarget.lower()
        else:
            state = 0
        yield state, infotext


check_info["oracle_crs_res"] = {
    "parse_function": parse_oracle_crs_res,
    "check_function": check_oracle_crs_res,
    "inventory_function": inventory_oracle_crs_res,
    "service_description": "ORA-GI %s Resource",
}
