#!/usr/bin/env python3
# This file is placed in the Public Domain.
#
# pylint: disable=C,R,W0105,W0201,W0212,W0613,E0401,E0402,E0611
# ruff: noqa: E402


"daemon"


import getpass
import os
import pwd
import readline # pylint: disable=W0611
import sys
import time


from botl.client  import spl
from botl.command import Command
from botl.default import Default
from botl.errors  import enable, errors
from botl.object  import cdir
from botl.workdir import Workdir, skel


Cfg             = Default()
Cfg.mod         = "cmd,irc,mod,rss"
Cfg.opts        = ""
Cfg.name        = "botld"
Cfg.version     = "107
Cfg.wd          = os.path.expanduser(f"~/.{Cfg.name}")
Cfg.pidfile     = os.path.join(Cfg.wd, f"{Cfg.name}.pid")
Workdir.workdir = Cfg.wd


from botl import modules


def daemon(pidfile, verbose=False):
    pid = os.fork()
    if pid != 0:
        os._exit(0)
    os.setsid()
    pid2 = os.fork()
    if pid2 != 0:
        os._exit(0)
    if not verbose:
        with open('/dev/null', 'r', encoding="utf-8") as sis:
            os.dup2(sis.fileno(), sys.stdin.fileno())
        with open('/dev/null', 'a+', encoding="utf-8") as sos:
            os.dup2(sos.fileno(), sys.stdout.fileno())
        with open('/dev/null', 'a+', encoding="utf-8") as ses:
            os.dup2(ses.fileno(), sys.stderr.fileno())
    os.umask(0)
    os.chdir("/")
    if os.path.exists(pidfile):
        os.unlink(pidfile)
    cdir(os.path.dirname(pidfile))
    with open(pidfile, "w", encoding="utf-8") as fds:
        fds.write(str(os.getpid()))


def init(pkg, modstr, disable=""):
    mds = []
    for modname in spl(modstr):
        if modname in spl(disable):
            continue
        module = getattr(pkg, modname, None)
        if not module:
            continue
        if "init" in dir(module):
            module.init()
            mds.append(module)
    return mds


def privileges(username):
    pwnam = pwd.getpwnam(username)
    os.setgid(pwnam.pw_gid)
    os.setuid(pwnam.pw_uid)


def ver(event):
    event.reply(f"{Cfg.name.upper()} {Cfg.version}")


def main():
    Command.add(ver)
    enable(print)
    skel()
    Cfg.mod = "," + ",".join(modules.__dir__())
    Cfg.user = getpass.getuser()
    daemon(Cfg.pidfile, "-v" in sys.argv)
    privileges(Cfg.user)
    init(modules, Cfg.mod)
    while 1:
        time.sleep(1.0)


if __name__ == "__main__":
    main()
    errors()
