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

# Valid
# <<<saprouter_cert>>>
# SSO for USER "prdadm"
#   with PSE file "/usr/users/prdadm/saprouter/local.pse"
#
# Validity  -  NotBefore:   Wed Mar 30 11:21:33 2016 (160330102133Z)
#               NotAfter:   Thu Mar 30 11:21:33 2017 (170330102133Z)

# No certificate
# <<<saprouter_cert>>>
# get_my_name: no PSE name supplied, no SSO credentials found!

# running seclogin with USER="root"
# seclogin: No SSO credentials available

# PSE broken
# <<<saprouter_cert>>>
# get_my_name: Couldn't open PSE "/usr/users/prdadm/saprouter/local.pse" (Decoding error)

# Suggested by customer
factory_settings["saprouter_cert_default_levels"] = {
    "validity_age": (86400 * 30, 86400 * 7),
}


def parse_saprouter_cert(info):
    def parse_date(list_):
        time_struct = time.strptime(" ".join(list_), "%b %d %H:%M:%S %Y")
        return time.mktime(time_struct), "%s-%s-%s" % time_struct[:3]

    parsed = {}
    validity = None
    for line in info:
        if line[0] == "Validity":
            validity = "valid"
            parsed.setdefault(validity, {})

        if validity and "NotBefore:" in line:
            parsed[validity].setdefault("not_before", parse_date(line[-5:-1]))

        elif validity and ("NotAfter:" in line or "NotAfter" in line):
            parsed[validity].setdefault("not_after", parse_date(line[-5:-1]))

        elif " ".join(line[:3]).lower() == "sso for user":
            parsed.setdefault("sso_user", line[-1].replace('"', ""))

        elif " ".join(line[:3]).lower() == "with pse file":
            parsed.setdefault("pse_file", line[-1].replace('"', ""))

        elif not validity:
            parsed.setdefault("failed", [])
            parsed["failed"].append(" ".join(line))

    return parsed


def inventory_saprouter_cert(parsed):
    if parsed:
        return [(None, None)]


def check_saprouter_cert(_no_item, params, parsed):
    if "valid" in parsed:
        _not_before, not_before_readable = parsed["valid"]["not_before"]
        not_after, not_after_readable = parsed["valid"]["not_after"]
        validity_age = not_after - time.time()

        warn, crit = params["validity_age"]
        infotext = "Valid from %s to %s, %s to go" % (
            not_before_readable,
            not_after_readable,
            get_age_human_readable(validity_age),
        )

        state = 0
        if validity_age < crit:
            state = 2
        elif validity_age < warn:
            state = 1

        if state:
            infotext += " (warn/crit below %s/%s)" % (
                get_age_human_readable(warn),
                get_age_human_readable(crit),
            )

        return state, infotext

    elif "failed" in parsed:
        return 3, " - ".join(parsed["failed"])


check_info["saprouter_cert"] = {
    "parse_function": parse_saprouter_cert,
    "inventory_function": inventory_saprouter_cert,
    "check_function": check_saprouter_cert,
    "service_description": "SAP router certificate",
    "default_levels_variable": "saprouter_cert_default_levels",
    "group": "saprouter_cert_age",
}
