#!/usr/bin/env python3
# This file is placed in the Public Domain.
#
# pylint: disable=C0413,W0212,W0611


"""OTPCR 

    otpcr  <cmd> [key=val] [key==val]
    otpcr  [-a] [-c] [-h] [-v]
    otpcrd

    options are:

    -a     load all modules
    -c     start console
    -h     show help
    -v     use verbose

    the cmd command show available commands.
    
    $ otpcr cmd
    cfg,cmd,dpl,err,exp,imp,mod,mre,nme,pwd,rem,res,rss,thr

"""


import getpass
import os
import pathlib
import pwd
import readline
import sys
import termios
import time


from otpcr.client  import Client, cmnd, init, scan
from otpcr.default import Default
from otpcr.disk    import Workdir
from otpcr.errors  import Errors, errors
from otpcr.event   import Event
from otpcr.log     import Logging, debug
from otpcr.parser  import parse
from otpcr.run     import broker


from otpcr import modules


Cfg             = Default()
Cfg.dis         = ""
Cfg.mod         = "cmd,err,irc,log,mod,req,slg,rss,tdo,thr,tmr"
Cfg.name        = "otpcr"
Cfg.opts        = ""
Cfg.version     = "21"
Cfg.wdr         = os.path.expanduser(f"~/.{Cfg.name}")
Cfg.pidfile     = os.path.join(Cfg.wdr, f"{Cfg.name}.pid")


Workdir.workdir = Cfg.wdr


class Console(Client):

    "Console"

    def __init__(self):
        Client.__init__(self)
        broker.add(self)

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

    def callback(self, evt):
        "wait for callback."
        Client.callback(self, evt)
        evt.wait()

    def poll(self):
        "poll console and create event."
        evt = Event()
        evt.orig = object.__repr__(self)
        evt.txt = input("> ")
        evt.type = "command"
        return evt

    def say(self, _channel, txt):
        "print to console"
        txt = txt.encode('utf-8', 'replace').decode()
        print(txt)


def wrap(func):
    "restore console."
    old2 = None
    try:
        old2 = termios.tcgetattr(sys.stdin.fileno())
    except termios.error:
        pass
    try:
        func()
    except (KeyboardInterrupt, EOFError):
        print("")
    finally:
        if old2:
            termios.tcsetattr(sys.stdin.fileno(), termios.TCSADRAIN, old2)
    errors()


def main():
    "main"
    parse(Cfg, " ".join(sys.argv[1:]))
    Workdir.skel()
    if "v" in Cfg.opts and "d" not in Cfg.opts:
        Errors.out = Logging.out = print
    if "a" in Cfg.opts:
        Cfg.mod = ",".join(modules.__dir__())
    if "v" in Cfg.opts:
        dte = " ".join(time.ctime(time.time()).replace("  ", " ").split()[1:])
        debug(f'{dte} {Cfg.name.upper()} {Cfg.opts.upper()} {Cfg.mod.upper()}')
    if "h" in Cfg.opts:
        print(__doc__)
    scan(modules, Cfg.mod, Cfg.sets.dis)
    if "c" in Cfg.opts:
        init(modules, Cfg.mod, Cfg.sets.dis)
        csl = Console()
        csl.start()
        while 1:
            time.sleep(1.0)
    elif Cfg.otxt:
        cmnd(Cfg.otxt, print)


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