#!/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 json
import sys

import lib.args
import lib.base
import lib.human
import lib.lftest
import lib.nodebb
import lib.time
import lib.version
from lib.globals import STATE_OK, STATE_UNKNOWN, STATE_WARN

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

DESCRIPTION = """Checks if a NodeBB update is available by comparing the installed version against the
latest release.
Alerts when an update is available."""

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


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(
        '--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(
        '--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(
        '-p',
        '--token',
        help='NodeBB API bearer token.',
        dest='TOKEN',
    )

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

    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:
        result = lib.nodebb.get_data(args, '/api/admin/dashboard')
    else:
        # do not call the command, put in test data
        stdout, _stderr, _retc = lib.lftest.test(args.TEST)
        result = json.loads(stdout)

    # init some vars
    perfdata = ''

    # analyze data
    installed_version = result['version']
    latest_version = result['latestVersion']
    perfdata = lib.base.get_perfdata(
        'nodebb-version',
        lib.version.version2float(installed_version),
        _min=0,
    )

    # build the message
    if not result['upgradeAvailable']:
        state = STATE_OK
        msg = f'NodeBB v{installed_version} is up to date'
    else:
        state = STATE_WARN
        msg = (
            f'NodeBB v{installed_version} installed, NodeBB v{latest_version} available'
        )

    if result['lastrestart']['timestamp']:
        last_restart = result['lastrestart']['timestamp'] / 1000
        restart_user = result['lastrestart']['user']
        ago = lib.human.seconds2human(
            lib.time.now(as_type='epoch') - last_restart,
        )
        msg += (
            f', Last restart:'
            f' {lib.time.epoch2iso(last_restart)}'
            f' by {restart_user["username"]}'
            f' <{restart_user["email"]}>'
            f' ({ago} ago)'
        )

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


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