#!/usr/bin/env python3
# This file is placed in the Public Domain.
#
# pylint: disable=C,R,W0201,W0212,W0105,W0613,W0406,W0611,E0102


"main"


import inspect
import os
import readline
import sys
import termios
import time


sys.path.insert(0, os.getcwd())


from sbn import Commands, Default, Errors, Event, Object, Reactor, Storage
from sbn import modules, spl

from sbn.utils import command, debug, forever, launch, parse, scan


Cfg = Default()
Cfg.mod  = "cmd,dbg,err,fnd,log,mod,mre,pwd,req,tdo,thr,ver"
Cfg.name = "sbn"
Cfg.version = "78"
Cfg.wd = os.path.expanduser(f"~/.{Cfg.name}")
Errors.output = print
Storage.wd = Cfg.wd


class Console(Reactor):

    def __init__(self):
        Reactor.__init__(self)
        self.register("command", Commands.handle)

    def announce(self, txt):
        self.say("", txt)

    def poll(self) -> Event:
        evt = Event()
        evt.orig = object.__repr__(self)
        evt.txt = input("> ")
        evt.type = "command"
        parse(evt)
        return evt

    def say(self, channel, txt):
        txt = txt.encode('utf-8', 'replace').decode()
        sys.stdout.write(txt)
        sys.stdout.write("\n")
        sys.stdout.flush()


def wrap(func) -> None:
    old = None
    try:
        old = termios.tcgetattr(sys.stdin.fileno())
    except termios.error:
        pass
    try:
        func()
    except (EOFError, KeyboardInterrupt):
        sys.stdout.write("\n")
        sys.stdout.flush()
    finally:
        if old:
            termios.tcsetattr(sys.stdin.fileno(), termios.TCSADRAIN, old)


def main():
    parse(Cfg, " ".join(sys.argv[1:]))
    if "v" in Cfg.opts:
        dte = time.ctime(time.time()).replace("  ", " ")
        debug(f"{Cfg.name.upper()} started {Cfg.opts.upper()} started {dte}")
    csl = Console()
    if "c" in Cfg.opts:
        mods = scan(modules, Cfg.mod, Cfg.hasmods)
        if "w" in Cfg.opts:
            for mod in mods:
                if "_thr_" in dir(mod):
                    mod._thr.join()
        if "t" in Cfg.opts:
            csl.threaded = True
        csl.start()
        forever()
        return
    scan(modules, Cfg.mod)
    command(Cfg.otxt)


if __name__ == "__main__":
    wrap(main)
    Errors.show()
