#!/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 check's README for more details."""

import argparse
import sys

import lib.args
import lib.base
import lib.human
import lib.jitsi
import lib.lftest
import lib.txt
import lib.version
from lib.globals import STATE_OK, STATE_UNKNOWN

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

DESCRIPTION = """Monitors Jitsi Videobridge performance via the COLIBRI REST API. Reports conference
count, participant count, video channels, bitrates, packet rates, and other bridge
metrics."""

DEFAULT_INSECURE = False
DEFAULT_NO_PROXY = False
DEFAULT_TIMEOUT = 3
DEFAULT_URL = 'http://localhost:8080'


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

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

    parser.add_argument(
        '--always-ok',
        help=lib.args.help('--always-ok'),
        dest='ALWAYS_OK',
        action='store_true',
        default=False,
    )

    parser.add_argument(
        '-c',
        '--critical',
        help=argparse.SUPPRESS,  # removed / deprecated parameter
        dest='CRIT',
        type=int,
    )

    parser.add_argument(
        '--insecure',
        help=lib.args.help('--insecure'),
        dest='INSECURE',
        action='store_true',
        default=DEFAULT_INSECURE,
    )

    parser.add_argument(
        '--no-proxy',
        help=lib.args.help('--no-proxy'),
        dest='NO_PROXY',
        action='store_true',
        default=DEFAULT_NO_PROXY,
    )

    parser.add_argument(
        '-p',
        '--password',
        help='Jitsi API password.',
        dest='PASSWORD',
        default=None,
    )

    parser.add_argument(
        '--test',
        help=lib.args.help('--test'),
        dest='TEST',
        type=lib.args.csv,
    )

    parser.add_argument(
        '--timeout',
        help=lib.args.help('--timeout') + ' Default: %(default)s (seconds)',
        dest='TIMEOUT',
        type=int,
        default=DEFAULT_TIMEOUT,
    )

    parser.add_argument(
        '--url',
        help='Jitsi API URL. Default: %(default)s',
        dest='URL',
        default=DEFAULT_URL,
    )

    parser.add_argument(
        '--username',
        help='Jitsi API username. Default: %(default)s',
        dest='USERNAME',
        default=None,
    )

    parser.add_argument(
        '-w',
        '--warning',
        help=argparse.SUPPRESS,  # removed / deprecated parameter
        dest='WARN',
        type=int,
    )

    args, _ = parser.parse_known_args()
    return args


def main():
    """The main function. This is where the magic happens."""

    # parse the command line
    try:
        args = parse_args()
    except SystemExit:
        sys.exit(STATE_UNKNOWN)

    # fetch data
    if args.TEST is None:
        # Fetch the `/colibri/stats` endpoint.
        args.URL += '/colibri/stats'
        result = lib.base.coe(lib.jitsi.get_data(args))
    else:
        # do not call the command, put in test data
        stdout, _, _ = lib.lftest.test(args.TEST)
        import json

        result = {}
        result['response_json'] = json.loads(stdout)

    # init some vars
    msg = ''
    state = STATE_OK
    perfdata = ''

    # build the message
    perfdata += lib.base.get_perfdata(
        'bit_rate_download',
        result['response_json'].get('bit_rate_download', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'bit_rate_upload',
        result['response_json'].get('bit_rate_upload', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'conferences',
        result['response_json'].get('conferences', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'current_timestamp',
        result['response_json'].get('current_timestamp', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'dtls_failed_endpoints',
        result['response_json'].get('dtls_failed_endpoints', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'endpoints',
        result['response_json'].get('endpoints', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'endpoints_sending_audio',
        result['response_json'].get('endpoints_sending_audio', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'endpoints_sending_video',
        result['response_json'].get('endpoints_sending_video', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'endpoints_with_spurious_remb',
        result['response_json'].get('endpoints_with_spurious_remb', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'graceful_shutdown',
        result['response_json'].get('graceful_shutdown', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'inactive_conferences',
        result['response_json'].get('inactive_conferences', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'inactive_endpoints',
        result['response_json'].get('inactive_endpoints', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'largest_conference',
        result['response_json'].get('largest_conference', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'local_active_endpoints',
        result['response_json'].get('local_active_endpoints', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'local_endpoints',
        result['response_json'].get('local_endpoints', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'num_eps_oversending',
        result['response_json'].get('num_eps_oversending', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'octo_conferences',
        result['response_json'].get('octo_conferences', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'octo_endpoints',
        result['response_json'].get('octo_endpoints', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'octo_receive_bitrate',
        result['response_json'].get('octo_receive_bitrate', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'octo_receive_packet_rate',
        result['response_json'].get('octo_receive_packet_rate', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'octo_send_bitrate',
        result['response_json'].get('octo_send_bitrate', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'octo_send_packet_rate',
        result['response_json'].get('octo_send_packet_rate', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'p2p_conferences',
        result['response_json'].get('p2p_conferences', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'packet_rate_download',
        result['response_json'].get('packet_rate_download', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'packet_rate_upload',
        result['response_json'].get('packet_rate_upload', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'preemptive_kfr_sent',
        result['response_json'].get('preemptive_kfr_sent', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'receive_only_endpoints',
        result['response_json'].get('receive_only_endpoints', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'region',
        result['response_json'].get('region', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'rtt_aggregate',
        result['response_json'].get('rtt_aggregate', 0),
        uom='ms',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'stress_level',
        result['response_json'].get('stress_level', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'threads',
        result['response_json'].get('threads', 0),
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_bytes_received',
        result['response_json'].get('total_bytes_received', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_bytes_received_octo',
        result['response_json'].get('total_bytes_received_octo', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_bytes_sent',
        result['response_json'].get('total_bytes_sent', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_bytes_sent_octo',
        result['response_json'].get('total_bytes_sent_octo', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_colibri_web_socket_messages_received',
        result['response_json'].get('total_colibri_web_socket_messages_received', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_colibri_web_socket_messages_sent',
        result['response_json'].get('total_colibri_web_socket_messages_sent', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_conference_seconds',
        result['response_json'].get('total_conference_seconds', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_conferences_completed',
        result['response_json'].get('total_conferences_completed', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_conferences_created',
        result['response_json'].get('total_conferences_created', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_data_channel_messages_received',
        result['response_json'].get('total_data_channel_messages_received', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_data_channel_messages_sent',
        result['response_json'].get('total_data_channel_messages_sent', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_dominant_speaker_changes',
        result['response_json'].get('total_dominant_speaker_changes', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_failed_conferences',
        result['response_json'].get('total_failed_conferences', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_ice_failed',
        result['response_json'].get('total_ice_failed', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_ice_succeeded',
        result['response_json'].get('total_ice_succeeded', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_ice_succeeded_relayed',
        result['response_json'].get('total_ice_succeeded_relayed', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_packets_dropped_octo',
        result['response_json'].get('total_packets_dropped_octo', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_packets_received',
        result['response_json'].get('total_packets_received', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_packets_received_octo',
        result['response_json'].get('total_packets_received_octo', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_packets_sent',
        result['response_json'].get('total_packets_sent', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_packets_sent_octo',
        result['response_json'].get('total_packets_sent_octo', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_partially_failed_conferences',
        result['response_json'].get('total_partially_failed_conferences', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'total_participants',
        result['response_json'].get('total_participants', 0),
        uom='c',
        _min=0,
    )
    perfdata += lib.base.get_perfdata(
        'version',
        lib.version.version2float(result['response_json']['version']),
        _min=0,
    )

    total_p = result['response_json']['total_participants']
    confs = result['response_json']['conferences']
    msg += (
        f'{total_p} total'
        f' {lib.txt.pluralize("participant", total_p)},'
        f' {confs}'
        f' {lib.txt.pluralize("conference", confs)}'
    )
    if result['response_json']['total_participants'] > 0:
        msg += f', Stress Level {result["response_json"]["stress_level"]}'
        msg += f', {result["response_json"]["threads"]} JVM threads'
        dl = lib.human.bps2human(
            result['response_json']['bit_rate_download'] * 1000,
        )
        ul = lib.human.bps2human(
            result['response_json']['bit_rate_upload'] * 1000,
        )
        msg += f', {dl} download, {ul} upload'

    # over and out
    lib.base.oao(msg, state, perfdata, always_ok=args.ALWAYS_OK)


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