#!python
# -*- coding: utf-8 -*-
# Copyright (C) 2018-2022 fjord-technologies
# SPDX-License-Identifier: GPL-3.0-or-later
"""autond"""

__version__ = '0.2.22'

import argparse
import logging
import grp
import os
import pwd
import six

from dwho.modules import * # XXX
from dwho.config import init_logger, make_piddir, make_logdir
from httpdis.ext import httpdis_json
from sonicprobe.libs import daemonize

from auton.classes.config import DWHO_THREADS, load_conf, start_endpoints
from auton.modules import * # XXX
from auton.plugins import * # XXX


SYSLOG_NAME       = "autond"
LOG               = logging.getLogger(SYSLOG_NAME)

DEFAULT_PIDFILE   = "/run/auton/autond.pid"
DEFAULT_LOGFILE   = "/var/log/autond/daemon.log"
DEFAULT_USER      = "auton"
DEFAULT_GROUP     = "auton"

try:
    AUTON_USER  = pwd.getpwnam(os.environ.get('AUTON_USER') or DEFAULT_USER).pw_name
except KeyError:
    AUTON_USER  = pwd.getpwuid(os.geteuid())[0]

try:
    AUTON_GROUP = grp.getgrnam(os.environ.get('AUTON_GROUP') or DEFAULT_GROUP).gr_name
except KeyError:
    AUTON_GROUP = grp.getgrgid(os.getegid())[0]

AUTOND_PIDFILE = os.environ.get('AUTOND_PIDFILE') or DEFAULT_PIDFILE
AUTOND_LOGFILE = os.environ.get('AUTOND_LOGFILE') or DEFAULT_LOGFILE


def argv_parse_check():
    """
    Parse (and check a little) command line parameters
    """
    parser        = argparse.ArgumentParser()

    parser.add_argument("-l",
                        dest      = 'loglevel',
                        default   = 'info',   # warning: see affectation under
                        choices   = ('critical', 'error', 'warning', 'info', 'debug'),
                        help      = ("Emit traces with LOGLEVEL details, must be one of:\t"
                                     "critical, error, warning, info, debug"))
    parser.add_argument("-d",
                        action    = 'store_true',
                        dest      = 'dontlauchmain',
                        default   = False,
                        help      = "Don't call the main function, for installation test purposes")
    parser.add_argument("-f",
                        action    = 'store_true',
                        dest      = 'foreground',
                        default   = False,
                        help      = "Foreground, don't daemonize")
    parser.add_argument("-c",
                        dest      = 'conffile',
                        type      = six.ensure_text,
                        default   = '/etc/auton/auton.yml',
                        help      = "Use configuration file <conffile> instead of %(default)s")
    parser.add_argument("-p",
                        dest      = 'pidfile',
                        type      = six.ensure_text,
                        default   = AUTOND_PIDFILE,
                        help      = "Use PID file <pidfile> instead of %(default)s")
    parser.add_argument("-u",
                        dest      = 'username',
                        type      = six.ensure_text,
                        default   = AUTON_USER,
                        help      = "Use username for the process instead of %(default)s")
    parser.add_argument("-g",
                        dest      = 'groupname',
                        type      = six.ensure_text,
                        default   = AUTON_GROUP,
                        help      = "Use groupname for the process instead of %(default)s")
    parser.add_argument("--logfile",
                        dest      = 'logfile',
                        type      = six.ensure_text,
                        default   = AUTOND_LOGFILE,
                        help      = "Use log file <logfile> instead of %(default)s")
    parser.add_argument("--listen-addr",
                        dest      = 'listen_addr',
                        type      = six.ensure_text,
                        help      = "Listen on address <listen_addr>")
    parser.add_argument("--listen-port",
                        dest      = 'listen_port',
                        type      = int,
                        help      = "Listen on port <listen_port>")

    args          = parser.parse_args()
    args.loglevel = getattr(logging, args.loglevel.upper(), logging.INFO)

    return args


def main(options):
    """
    Main function; start the server
    """
    uid = pwd.getpwnam(options.username)[2]
    gid = grp.getgrnam(options.groupname)[2]

    make_piddir(options.pidfile, uid, gid)
    make_logdir(options.logfile, uid, gid)

    root_logger = init_logger(options.logfile, SYSLOG_NAME)
    options     = load_conf(options.conffile, options, envvar = 'AUTOND_CONFIG')

    setattr(options, 'server_version', "%s/%s" % (SYSLOG_NAME, __version__))
    setattr(options, 'sys_version', '')

    httpdis_json.init(options, False)
    DWHO_THREADS.append(httpdis_json.stop)

    if not options.foreground:
        LOG.info("Transforming into a daemon from hell")
        daemonize.daemonize()

    LOG.info("locking PID")
    daemonize.lock_pidfile_or_die(options.pidfile)

    try:
        LOG.info("pidfile ok")
        root_logger.setLevel(options.loglevel)
        os.chown(options.pidfile, uid, gid)
        os.setgid(gid)
        os.setuid(uid)
        os.umask(0o22)

        start_endpoints()
        httpdis_json.run(options)
    except (KeyboardInterrupt, SystemExit):
        pass
    except Exception:
        LOG.exception("bad things happen")
    finally:
        daemonize.unlock_pidfile(options.pidfile)

if __name__ == '__main__':
    def _start():
        "entry point"
        options = argv_parse_check()
        if not options.dontlauchmain:
            main(options)
    _start()
