#!/opt/synergyos/venv/bin/python3
"""SynergyOS shell — the terminal face of the command center.

Same engine as the desktop Assistant: Claude + SynergyMCP when configured/online,
local model otherwise. Read-only actions run; anything else asks first.

  !<cmd>          run a shell command directly        /bash   plain bash
  /connect <b>    sign in to a Synergy bundle         /bundles  list bundles
  /key            set the Anthropic API key           /model <id>  switch model
  /install        install SynergyOS to disk           /help   /quit
"""
import os, readline, subprocess, sys, webbrowser  # noqa: F401
sys.path.insert(0, "/opt/synergyos/lib")
import synergy_engine as E

HISTORY = os.path.expanduser("~/.synergyos_history")
C = {"g": "\033[32m", "y": "\033[33m", "c": "\033[36m", "d": "\033[90m", "r": "\033[31m", "0": "\033[0m"}

def banner(cfg, brain, mcp):
    print(C["c"] + r"""
  ____                              ___  ____
 / ___| _   _ _ __   ___ _ __ __ _ _   _ / _ \/ ___|
 \___ \| | | | '_ \ / _ \ '__/ _` | | | | | | \___ \
  ___) | |_| | | | |  __/ | | (_| | |_| | |_| |___) |
 |____/ \__, |_| |_|\___|_|  \__, |\__, |\___/|____/
        |___/                |___/ |___/""" + C["0"])
    mode = brain.mode()
    print(f"  {os.uname().nodename} · brain: {('Claude ' + cfg.get('model', E.DEFAULT_MODEL)) if mode == 'claude' else 'local model'}"
          f" · bundles: {', '.join(mcp.connected()) or 'none'}")
    print("  !cmd runs a command · /bash · /connect <bundle> · /key · /install · /help\n")

def on(kind, text):
    if kind == "text": print(f"  {text}\n")
    elif kind == "tool": print(f"  {C['d']}{text}{C['0']}")
    elif kind == "out": print(text)
    elif kind == "err": print(f"  {C['r']}{text}{C['0']}")
    elif kind == "status": pass   # the terminal shows progress through the commands themselves

def confirm(title, detail):
    print(f"\n  {C['y']}{title}{C['0']}")
    for line in detail.splitlines(): print(f"  {line}")
    try: ans = input("  proceed? [y/N] ").strip().lower()
    except EOFError: return False
    return ans in ("y", "yes")

def main():
    cfg = E.load_config()
    mcp = E.MCPManager(cfg, open_url=lambda u: (print(f"\n  open this in a browser to sign in:\n  {u}\n"), webbrowser.open(u)),
                       log=lambda s: print(f"  {C['d']}{s}{C['0']}"))
    brain = E.Brain(cfg, mcp, on, confirm)
    banner(cfg, brain, mcp)
    for b in cfg.get("bundles", []):
        if mcp.has_credentials(b):
            try: mcp.connect(b, interactive=False)
            except Exception as e: print(f"  {C['r']}{b}: {e}{C['0']}")
    if brain.mode() == "local" and not brain.local_model_ready():
        print("  loading local language model", end="", flush=True)
        for _ in range(120):
            if brain.local_model_ready(): break
            print(".", end="", flush=True); __import__("time").sleep(2)
        print()
    try: readline.read_history_file(HISTORY)
    except Exception: pass
    while True:
        try: user = input(f"{C['g']}synergy>{C['0']} ").strip()
        except (EOFError, KeyboardInterrupt): print(); break
        if not user: continue
        try: readline.write_history_file(HISTORY)
        except Exception: pass
        if user in ("/quit", "/exit", "exit", "logout"): break
        if user == "/bash": subprocess.call(["/bin/bash", "-l"]); continue
        if user == "/install": subprocess.call(["sudo", "synergyos-install"]); continue
        if user == "/help": print(__doc__); continue
        if user == "/bundles":
            for b in E.ALL_BUNDLES:
                print(f"  {b:8} {'connected' if b in mcp.sessions else ('signed in' if mcp.has_credentials(b) else '-')}")
            continue
        if user.startswith("/connect"):
            parts = user.split(); write = "--write" in parts
            names = [p for p in parts[1:] if not p.startswith("--")] or cfg.get("bundles", [])
            for b in names:
                try: print(f"  {b}: {mcp.connect(b, write=write)} tools")
                except Exception as e: print(f"  {C['r']}{b}: {e}{C['0']}")
                if b not in cfg["bundles"]: cfg["bundles"].append(b)
            E.save_config(cfg); continue
        if user == "/key":
            import getpass
            cfg["anthropic_api_key"] = getpass.getpass("  Anthropic API key (hidden): ").strip(); E.save_config(cfg)
            brain._client = None; print(f"  saved (0600) · brain now: {brain.mode()}"); continue
        if user.startswith("/model "):
            cfg["model"] = user.split(None, 1)[1].strip(); E.save_config(cfg); print(f"  model: {cfg['model']}"); continue
        if user.startswith("!"):
            rc, out = E.run_shell(user[1:]); print(out, end="" if out.endswith("\n") else "\n"); continue
        brain.ask(user)

if __name__ == "__main__":
    main()
