#!/usr/bin/env python3
# -*- coding: utf-8; py-indent-offset: 4 -*-
#
# Author:  Linuxfabrik GmbH, Zurich, Switzerland
# Contact: info (at) linuxfabrik (dot) ch
#          https://www.linuxfabrik.ch/
# License: The Unlicense, see LICENSE file.

# https://github.com/Linuxfabrik/monitoring-plugins/blob/main/CONTRIBUTING.md

"""See the plugins's README for more details.
"""

import argparse                        # pylint: disable=C0413
import socket                          # pylint: disable=C0413
import sys                             # pylint: disable=C0413
import textwrap                        # pylint: disable=C0413
import urllib.parse                    # pylint: disable=C0413
import urllib.request                  # pylint: disable=C0413

import lib.args                       # pylint: disable=C0413
import lib.base                       # pylint: disable=C0413
import lib.url                        # pylint: disable=C0413
from lib.globals import STATE_UNKNOWN # pylint: disable=C0413

__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
__version__ = '2025021301'

DESCRIPTION = 'Sends service notifications using the RocketChat API.'

TIMEOUT = 4 # seconds

def parse_args():
    """Parse command line arguments using argparse.
    """
    parser = argparse.ArgumentParser(description=DESCRIPTION)

    parser.add_argument(
        '--datetime',
        help='Set the message timestamp.',
        default=None,
        type=str,
        dest='DATETIME',
        required=True,
    )

    parser.add_argument(
        '--host-displayname',
        help='Set the display name of the host.',
        default=None,
        type=str,
        dest='HOST_DISPLAYNAME',
        required=True,
    )

    parser.add_argument(
        '--hostname',
        help='Set the hostname.',
        default=None,
        type=str,
        dest='HOSTNAME',
    )

    parser.add_argument(
        '--icingaweb2-url',
        help='Set the Icinga Web 2 URL, for example "https://example.com/icingaweb2".',
        default=None,
        type=str,
        dest='ICINGAWEB2_URL',
    )

    parser.add_argument(
        '--notification-author',
        help='Set the author of the comment.',
        default=None,
        type=str,
        dest='NOTIFICATION_AUTHOR',
    )

    parser.add_argument(
        '--notification-comment',
        help='Set the comment.',
        default=None,
        type=str,
        dest='NOTIFICATION_COMMENT',
    )

    parser.add_argument(
        '--rocketchat-mentions',
        help='Set the Rocket.Chat Mentions (repeating).',
        type=str,
        action='append',
        dest='ROCKETCHAT_MENTIONS',
    )

    parser.add_argument(
        '--rocketchat-url',
        help='Set the Rocket.Chat Webhook API URL.',
        type=str,
        dest='ROCKETCHAT_URL',
        required=True,
    )

    parser.add_argument(
        '--service-output',
        help='Set the service output.',
        default=None,
        type=str,
        dest='SERVICE_OUTPUT',
    )

    parser.add_argument(
        '--service-state',
        help='Set the service state.',
        default=None,
        type=str,
        dest='SERVICE_STATE',
        required=True,
    )

    parser.add_argument(
        '--servicename',
        help='Set the servicename.',
        default=None,
        type=str,
        dest='SERVICENAME',
    )

    parser.add_argument(
        '-V', '--version',
        action='version',
        version='%(prog)s: v{} by {}'.format(__version__, __author__)
    )

    return parser.parse_args()


def main():
    """The main function. Hier spielt die Musik.
    """

    # parse the command line, exit with UNKNOWN if it fails
    try:
        args = parse_args()
    except SystemExit:
        sys.exit(STATE_UNKNOWN)

    message = textwrap.dedent('''
        {SERVICE_STATE:.4}: {SERVICENAME} ({DATETIME})
        HOST: {HOST_DISPLAYNAME}
        ```
        {SERVICE_OUTPUT}
        ```
    ''').strip().format(
        SERVICE_STATE=args.SERVICE_STATE,
        SERVICENAME=args.SERVICENAME,
        DATETIME=args.DATETIME,
        HOST_DISPLAYNAME=args.HOST_DISPLAYNAME,
        SERVICE_OUTPUT = args.SERVICE_OUTPUT,
    )

    if args.NOTIFICATION_COMMENT:
        comment = '\nCOMMENT: {NOTIFICATION_COMMENT} ({NOTIFICATION_AUTHOR})'.format(
            NOTIFICATION_AUTHOR=args.NOTIFICATION_AUTHOR,
            NOTIFICATION_COMMENT=args.NOTIFICATION_COMMENT,
        )
        message += comment

    notifying_hostname = socket.gethostname().split('.', 1)[0] # short hostname of the icinga2 server sending the notif
    icingaweb2_url = None
    if args.ICINGAWEB2_URL and args.HOSTNAME and args.SERVICENAME:
        params = urllib.parse.urlencode(
            {
                'name': args.SERVICENAME,
                'host.name': args.HOSTNAME,
            },
            quote_via=urllib.parse.quote
        )

        icingaweb2_url = urllib.parse.urljoin(
            '{}/'.format(args.ICINGAWEB2_URL),
            'icingadb/service?{}'.format(params)
        )

    if args.ROCKETCHAT_MENTIONS:
        message += '\n'
        for mention in args.ROCKETCHAT_MENTIONS:
            message += '@{} '.format(mention)

    if args.SERVICE_STATE == 'OK':
        icon = ':service_ok:'
    elif args.SERVICE_STATE == 'WARNING':
        icon = ':service_warn:'
    elif args.SERVICE_STATE == 'CRITICAL':
        icon = ':service_crit:'
    elif args.SERVICE_STATE == 'UNKNOWN':
        icon = ':service_unknown:'
    else:
        icon = ':Pingu:'

    if icingaweb2_url:
        data = {
            "icon_emoji": icon,
            "text": message,
            "attachments": [
                {
                    "title": notifying_hostname,
                    "title_link": icingaweb2_url,
                }
            ]
        }
    else:
        data = {
            "emoji": icon,
            "text": message
        }

    lib.base.coe(lib.url.fetch_json(
        args.ROCKETCHAT_URL,
        header={
            'Content-Type': 'application/json',
        },
        data=data,
        encoding='serialized-json',
        extended=True,
        timeout=TIMEOUT,
    ))


if __name__ == '__main__':
    try:
        main()
    except Exception:   # pylint: disable=W0703
        lib.base.cu()
