#!/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  # pylint: disable=C0413
import sys  # pylint: disable=C0413

import lib.base  # pylint: disable=C0413
import lib.human  # pylint: disable=C0413
import lib.rocket  # pylint: disable=C0413
from lib.globals import (STATE_OK, STATE_UNKNOWN) # pylint: disable=C0413

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

DESCRIPTION = """This plugin allows you to track statistics about a Rocket.Chat server,
                 structured in the same way as on the https://rocket.chat/admin/info page.
                 Requires a user with a strong password and (only) "view-statistics" permission."""

DEFAULT_INSECURE = False
DEFAULT_NO_PROXY = False
DEFAULT_TIMEOUT = 3
DEFAULT_URL = 'http://localhost:3000/api/v1'
DEFAULT_USERNAME = 'rocket-stats'


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

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

    parser.add_argument(
        '--insecure',
        help='This option explicitly allows to perform "insecure" SSL connections. '
             'Default: %(default)s',
        dest='INSECURE',
        action='store_true',
        default=DEFAULT_INSECURE,
    )

    parser.add_argument(
        '--no-proxy',
        help='Do not use a proxy. '
             'Default: %(default)s',
        dest='NO_PROXY',
        action='store_true',
        default=DEFAULT_NO_PROXY,
    )

    parser.add_argument(
        '-p', '--password',
        help='Rocket.Chat API password.',
        dest='PASSWORD',
        required=True,
    )

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

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

    parser.add_argument(
        '--username',
        help='Rocket.Chat API username. '
             'Default: %(default)s',
        dest='USERNAME',
        default=DEFAULT_USERNAME,
        required=True,
    )

    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)

    # fetch data
    credentials = lib.base.coe(lib.rocket.get_token(
        args.URL,
        args.USERNAME,
        args.PASSWORD,
        insecure=args.INSECURE,
        no_proxy=args.NO_PROXY,
        timeout=args.TIMEOUT,
    ))
    auth_token, user_id = credentials.split(':')
    result = lib.base.coe(lib.rocket.get_stats(
        args.URL,
        auth_token,
        user_id,
        insecure=args.INSECURE,
        no_proxy=args.NO_PROXY,
        timeout=args.TIMEOUT,
    ))

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

    # build a compact multiline message with the most important info first
    msg += '{}/{} users online, {} {}, {} {}, {} upload total size, v{}'.format(
        result.get('onlineUsers', 'n/a'),
        result.get('totalUsers', 'n/a'),
        lib.human.number2human(result.get('totalMessages', 0)),
        lib.txt.pluralize('msg', result.get('totalMessages', 0)),
        lib.human.number2human(result.get('uploadsTotal', 0)),
        lib.txt.pluralize('upload', result.get('uploadsTotal', 0)),
        lib.human.bytes2human(result.get('uploadsTotalSize', 0)),
        result.get('version', 'n/a'),
    )

    # no checks here, just for your information
    msg += '\n* Users: {} total ({} online, {} busy, {} away, {} offline)'.format(
        result.get('totalUsers', 'n/a'),
        result.get('onlineUsers', 'n/a'),
        result.get('busyUsers', 'n/a'),
        result.get('awayUsers', 'n/a'),
        result.get('offlineUsers', 'n/a'),
    )

    msg += '\n* Types and Distribution: {} of {} activated {} online, {} activated {}, {} deactivated {}, {} Rocket.Chat app {}'.format( # pylint: disable=C0301
        result.get('totalConnectedUsers', 'n/a'),
        result.get('activeUsers', 'n/a'),
        lib.txt.pluralize('user', result.get('activeUsers', 0)),
        result.get('activeGuests', 'n/a'),
        lib.txt.pluralize('guest', result.get('activeGuests', 0)),
        result.get('nonActiveUsers', 'n/a'),
        lib.txt.pluralize('user', result.get('nonActiveUsers', 0)),
        result.get('appUsers', 'n/a'),
        lib.txt.pluralize('user', result.get('appUsers', 0)),
    )

    msg += '\n* Total Uploads: {}, {} size'.format(
        result.get('uploadsTotal', 'n/a'),
        lib.human.bytes2human(result.get('uploadsTotalSize', 0)),
    )

    msg += '\n* Total Rooms: {} ({}, {} {}, {} private {}, {} direct msg {}, {} {}, {} omnichannel {})'.format( # pylint: disable=C0301
        result.get('totalRooms', 'n/a'),
        lib.txt.pluralize('room', result.get('totalRooms', 0)),
        result.get('totalChannels', 'n/a'),
        lib.txt.pluralize('channel', result.get('totalChannels', 0)),
        result.get('totalPrivateGroups', 'n/a'),
        lib.txt.pluralize('group', result.get('totalPrivateGroups', 0)),
        result.get('totalDirect', 'n/a'),
        lib.txt.pluralize('room', result.get('totalDirect', 0)),
        result.get('totalDiscussions', 'n/a'),
        lib.txt.pluralize('discussion', result.get('totalDiscussions', 0)),
        result.get('totalLivechat', 'n/a'),
        lib.txt.pluralize('room', result.get('totalLivechat', 0)),
    )

    msg += '\n* Total Messages: {}, {} {}, {} in channels, {} in priv groups, {} in direct msg, {} in omnichannel'.format( # pylint: disable=C0301
        lib.human.number2human(result.get('totalMessages', 0)),
        result.get('totalThreads', 'n/a'),
        lib.txt.pluralize('thread', result.get('totalThreads', 0)),
        result.get('totalChannelMessages', 'n/a'),
        lib.human.number2human(result.get('totalPrivateGroupMessages', 0)),
        lib.human.number2human(result.get('totalDirectMessages', 0)),
        lib.human.number2human(result.get('totalLivechatMessages', 0)),
    )

    perfdata += lib.base.get_perfdata('rc_totalUsers', result.get('totalUsers', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_onlineUsers', result.get('onlineUsers', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_busyUsers', result.get('busyUsers', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_awayUsers', result.get('awayUsers', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_offlineUsers', result.get('offlineUsers', 0), None, None, None, 0, None) # pylint: disable=C0301

    perfdata += lib.base.get_perfdata('rc_totalConnectedUsers', result.get('totalConnectedUsers', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_activeUsers', result.get('activeUsers', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_activeGuests', result.get('activeGuests', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_nonActiveUsers', result.get('nonActiveUsers', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_appUsers', result.get('appUsers', 0), None, None, None, 0, None) # pylint: disable=C0301

    perfdata += lib.base.get_perfdata('rc_uploadsTotal', result.get('uploadsTotal', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_uploadsTotalSize', result.get('uploadsTotalSize', 0), 'B', None, None, 0, None) # pylint: disable=C0301

    perfdata += lib.base.get_perfdata('rc_totalRooms', result.get('totalRooms', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_totalChannels', result.get('totalChannels', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_totalPrivateGroups', result.get('totalPrivateGroups', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_totalDirect', result.get('totalDirect', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_totalDiscussions', result.get('totalDiscussions', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_totalLivechat', result.get('totalLivechat', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_totalMessages', result.get('totalMessages', 0), None, None, None, 0, None) # pylint: disable=C0301

    perfdata += lib.base.get_perfdata('rc_totalThreads', result.get('totalThreads', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_totalChannelMessages', result.get('totalChannelMessages', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_totalPrivateGroupMessages', result.get('totalPrivateGroupMessages', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_totalDirectMessages', result.get('totalDirectMessages', 0), None, None, None, 0, None) # pylint: disable=C0301
    perfdata += lib.base.get_perfdata('rc_totalLivechatMessages', result.get('totalLivechatMessages', 0), None, None, None, 0, None) # pylint: disable=C0301

    # over and out
    lib.base.oao(msg, state, perfdata)


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