#!/usr/bin/env python3
# This file is placed in the Public Domain.


import inspect
import json
import os
import pathlib
import sys
import time


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


from tob.clients import Client
from tob.command import Commands, Config, command, parse, scanner, table
from tob.handler import Event
from tob.logging import level
from tob.package import Mods, getmod, inits, modules, sums
from tob.persist import Workdir, moddir, pidname, skel
from tob.runtime import check, daemon, control, console, service, privileges
from tob.runtime import boot, wrap, wrapped
from tob.utility import md5sum, spl


from tobot import modules as MODS


Config.name = "tobot"
Config.version = 2


class CLI(Client):

    def __init__(self):
        Client.__init__(self)
        self.register("command", command)

    def raw(self, txt):
        print(txt.encode('utf-8', 'replace').decode("utf-8"))


class Console(CLI):

    def callback(self, event):
        if not event.txt:
            return
        super().callback(event)
        event.wait()

    def poll(self):
        evt = Event()
        evt.txt = input("> ")
        evt.type = "command"
        return evt


def first(doparse=True):
    Mods.add("modules", os.path.dirname(inspect.getfile(MODS)))
    Mods.add("mods", moddir())
    Commands.add(cmd)
    Commands.add(ver)


"utility"


def banner():
    tme = time.ctime(time.time()).replace("  ", " ")
    print("%s %s since %s (%s)" % (Config.name.upper(), Config.version, tme, Config.level.upper()))


"commands"


def cmd(event):
    event.reply(",".join(sorted(Commands.names or Commands.cmds)))


def md5(event):
    tbl = getmod("tbl")
    if tbl:
        event.reply(md5sum(tbl.__file__))
    else:
        event.reply("table is not there.")


def srv(event):
    import getpass
    name = getpass.getuser()
    event.reply(TXT % (Config.name.upper(), name, name, name, Config.name))


def tbl(event):
    Commands.names = {}
    scanner()
    event.reply("# This file is placed in the Public Domain.")
    event.reply("")
    event.reply("")
    event.reply('"lookup tables"')
    event.reply("")
    event.reply("")
    event.reply(f"NAMES = {json.dumps(Commands.names, indent=4, sort_keys=True)}")
    event.reply("")
    event.reply("")
    event.reply("MD5 = {")
    for module in scanner():
        event.reply(f'    "{module.__name__.split(".")[-1]}": "{md5sum(module.__file__)}",')
    event.reply("}")


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


TXT = """[Unit]
Description=%s
After=network-online.target

[Service]
Type=simple
User=%s
Group=%s
ExecStart=/home/%s/.local/bin/%s -s

[Install]
WantedBy=multi-user.target"""


"runtime"


def main():
    if check('v'):
        banner()
    if check("c"):
        first()
        wrap(console, Console)
    elif check("d"):
        first()
        background()
    elif check("s"):
        first()
        wrapped(service, CLI)
    else:
        first()
        Commands.add(md5)
        Commands.add(tbl)
        Commands.add(srv)
        wrapped(control, CLI)


"trampoline"


if __name__ == "__main__":
    main()
