#!python
# This file is placed in the Public Domain.

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

import importlib
import os
import pkgutil
import readline
import sys
import termios
import time

from obj import RunCfg, Object, fmt, keys, save
from run import Client, Runtime, Table, elapsed, find, fntime, get_exception
from run import listfiles, spl


RunCfg.wd = os.path.expanduser("~/.kamer")


class Console(Client):

    def handle(self, clt, e):
        k.put(e)
        e.wait()

    def poll(self):
        return input("> ")

    def raw(self, txt):
        print(txt)
        sys.stdout.flush()


class Kernel(Runtime):

    def error(self, txt):
        print(txt)
        sys.stdout.flush()

    def log(self, txt):
        if "PONG" in txt or "PING" in txt:
            return
        if RunCfg.verbose:
            print(txt.rstrip())
            sys.stdout.flush()


class Table(Table):

    def addmod(self, mn):
        spc = importlib.util.find_spec(mn)
        if not spc:
            return
        mod = importlib.import_module(mn)
        self.introspect(mod)

    def scan(self, pn):
        spc = importlib.util.find_spec(pn)
        if not spc:
            return
        pkg = importlib.import_module(pn)
        for mn in pkgutil.walk_packages(pkg.__path__, pn + "."):
            mod = importlib.import_module(mn.name)
            if mod:
                self.introspect(mod)


def daemon():
    pid = os.fork()
    if pid != 0:
        termreset()
        os._exit(0)
    os.setsid()
    os.umask(0)
    si = open("/dev/null", 'r')
    so = open("/dev/null", 'a+')
    se = open("/dev/null", 'a+')
    os.dup2(si.fileno(), sys.stdin.fileno())
    os.dup2(so.fileno(), sys.stdout.fileno())
    os.dup2(se.fileno(), sys.stderr.fileno())


def wrap(func):
    fd = sys.stdin.fileno()
    old = termios.tcgetattr(fd)
    try:
        func()
    except KeyboardInterrupt:
        print("")
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old)


clt = Console()
k = Kernel()
tbl = Table()


def cmd(event):
    event.reply(",".join(tbl.modnames))

def main():
    from run import __version__
    k.boot()
    tbl.add(cmd)
    if RunCfg.verbose:
        k.log("KAMER %s" % __version__)
        k.log(fmt(RunCfg, ["bork","console","daemon","debug","verbose","wd"]))
    tbl.scan("kamer")
    if RunCfg.verbose:
        k.log(",".join(tbl.modnames))
    if k.cfg.txt:
        return k.cmd(k.cfg.otxt)
    if RunCfg.daemon:
        daemon()
    if RunCfg.console or k.cfg.mod:
        k.start()
        for mn in spl(k.cfg.mod):
            k.init("kamer.%s" % mn)
        clt.start()
        k.wait()


wrap(main)
