#!/usr/bin/env python3
# SIGNL4 Alerting
# -*- encoding: utf-8; py-indent-offset: 4 -*-

# (c) 2026 Derdack GmbH
#          SIGNL4 <info@signl4.com>

# This is free software;  you can redistribute it and/or modify it
# under the  terms of the  GNU General Public License  as published by
# the Free Software Foundation in version 2.  check_mk is  distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY;  with-
# out even the implied warranty of  MERCHANTABILITY  or  FITNESS FOR A
# PARTICULAR PURPOSE. See the  GNU General Public License for more de-
# tails. You should have  received  a copy of the  GNU  General Public
# License along with GNU Make; see the file  COPYING.  If  not,  write
# to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
# Boston, MA 02110-1301 USA.

import requests
import json
import os
import sys
import base64
import unicodedata
from cmk.notification_plugins.utils import get_password_from_env_or_context

api_url = "https://connect.signl4.com/webhook/"

def main():
    context = dict([ (var[7:], value)
                      for (var, value) in os.environ.items()
                      if var.startswith("NOTIFY_")])

    message    = get_text(context)

    password = get_password_from_env_or_context(
        key="NOTIFY_PARAMETER_PASSWORD"
    )

    return send_alert(password, message)

def get_text(context):

    host_name = context['HOSTNAME']
    notification_type = context['NOTIFICATIONTYPE']
    service_state = ''
    service_desc = ''
    service_output = ''
    host_state = ''
    notification_comment = ''
    contact_name = context['CONTACTNAME']
    contact_alias = context['CONTACTALIAS']
    contact_email = context['CONTACTEMAIL']
    contact_pager = context['CONTACTPAGER'].replace(' ', '')
    description = notification_type + ' on ' + host_name
    service_problem_id = ''
    
    host_problem_id = context.get('HOSTPROBLEMID') or ''
    date_time = context['SHORTDATETIME']

    # Prepare Default information and Type PROBLEM, RECOVERY
    if context['WHAT'] == 'SERVICE':
        if notification_type in [ "PROBLEM", "RECOVERY" ]:
            service_state = context['SERVICESTATE']
            service_desc = context['SERVICEDESC']
            service_output = context['SERVICEOUTPUT']
            description += ' (' + service_desc + ')'
            service_problem_id = context['SERVICEPROBLEMID']
        else:
            service_desc = context['SERVICEDESC']
            description += ' (' + service_desc + ')'

    else:
        if notification_type in [ "PROBLEM", "RECOVERY" ]:
            host_state = context.get('HOSTSTATE') or ''
            description += ' (' + host_state + ')'
        else:
            description += ' (' + host_state + ')'

    # Remove placeholder "$SERVICEPROBLEMID$" if exists
    if service_problem_id.find('$') != -1:
        service_problem_id = ''

    # Check if this is a new problem or a recovery
    s4_status = 'new'
    if notification_type == 'RECOVERY':
        s4_status = 'resolved'
    
    service_desc_base64 = ''
    service_desc_id_part = ''
    if len(service_desc) > 0:
        # orig: service_desc_bytes = service_desc.encode("ascii")
        # use unicode Normalization Form Compatibility Decomposition to make unique but valid ascii
        # even if service_desc includes i.e. german umlauts
        service_desc_bytes = unicodedata.normalize("NFKD",service_desc).encode("ascii","ignore")
        service_desc_base64 = base64.b64encode(service_desc_bytes).decode()
        service_desc_id_part = ':ServiceDesc:' + service_desc_base64

    message = {
        'Title': description,
        'HostName': host_name,
        'NotificationType': notification_type,
        'ServiceState': service_state,
        'ServiceDescription': service_desc,
        'ServiceOutput': service_output,
        'HostState': host_state,
        'NotificationComment': notification_comment,
        'ContactName': contact_name,
        'ContactAlias': contact_alias,
        'ContactEmail': contact_email,
        'ContactPager': contact_pager,
        'HostProblemId': host_problem_id,
        'ServiceProblemId': service_problem_id,
        'DateTime': date_time,
        'X-S4-ExternalID': 'Checkmk: ' + host_name + '-' + host_problem_id + '-' + service_problem_id + service_desc_id_part,
        'X-S4-Status': s4_status,
        'X-S4-SourceSystem': 'Checkmk'
    }

    return message

def send_alert(password, message):

    resp = requests.post(api_url + password, params=None, data=json.dumps(message))

    if resp.status_code == 201:
        return 0

    sys.stderr.write(resp.text)
    return 2

sys.exit(main())

