"""
BizNode Node Status Checker
============================
Run this to check registration, trial, license, and Docker status.

    python status.py
"""

import os, sys, json, subprocess
from datetime import datetime

NODE_DIR = os.path.dirname(os.path.abspath(__file__))
REG_FILE   = os.path.join(NODE_DIR, ".registration")
TRIAL_FILE = os.path.join(NODE_DIR, ".trial")
ENV_FILE   = os.path.join(NODE_DIR, ".env")

W = 54

def _bar(): print("=" * W)
def _line(k, v, color=""): print(f"  {k:<22} {v}")

def _env(key):
    if not os.path.exists(ENV_FILE): return ""
    for line in open(ENV_FILE, encoding="utf-8"):
        if line.strip().startswith(f"{key}="):
            return line.strip().split("=", 1)[1]
    return ""

def _docker_services():
    try:
        r = subprocess.run(
            ["docker", "compose", "ps", "--format", "json"],
            capture_output=True, text=True, cwd=NODE_DIR, timeout=8
        )
        lines = [l.strip() for l in r.stdout.strip().splitlines() if l.strip()]
        services = []
        for line in lines:
            try:
                d = json.loads(line)
                services.append((d.get("Service", "?"), d.get("State", "?"), d.get("Status", "")))
            except Exception:
                pass
        return services
    except Exception:
        return []

def check_registration():
    _bar()
    print("  REGISTRATION")
    _bar()
    if not os.path.exists(REG_FILE):
        _line("Status", "[NOT REGISTERED]")
        _line("Action", "Run: python launcher.py")
    else:
        try:
            d = json.load(open(REG_FILE, encoding="utf-8"))
            _line("Status",          "[REGISTERED]")
            _line("Registration ID", d.get("registration_id", "N/A"))
            _line("Business",        d.get("business_name", "N/A"))
            _line("Name",            d.get("your_name", "N/A"))
            _line("Email",           d.get("email", "N/A"))
            _line("Registered on",   d.get("registered_at", "N/A")[:19] if d.get("registered_at") else "N/A")
            exp = d.get("trial_expires_at", "")
            if exp:
                try:
                    exp_dt = datetime.fromisoformat(exp)
                    days   = max(0, (exp_dt - datetime.utcnow()).days)
                    status = f"{exp[:10]}  ({days} day(s) remaining)" if days > 0 else f"{exp[:10]}  [EXPIRED]"
                    _line("Trial expires", status)
                except Exception:
                    _line("Trial expires", exp)
        except Exception as e:
            _line("Status", f"[ERROR reading .registration: {e}]")
    print()

def check_trial():
    _bar()
    print("  LOCAL TRIAL FILE")
    _bar()
    if not os.path.exists(TRIAL_FILE):
        _line("Trial file", "[NOT FOUND] — will be created on first run")
    else:
        try:
            d = json.load(open(TRIAL_FILE, encoding="utf-8"))
            started = d.get("started", "")[:19]
            expires = d.get("expires", "")
            _line("Started",  started)
            if expires:
                exp_dt = datetime.fromisoformat(expires)
                days   = max(0, (exp_dt - datetime.utcnow()).days)
                label  = f"{expires[:10]}  ({days} day(s) left)" if days > 0 else f"{expires[:10]}  [EXPIRED]"
                _line("Expires", label)
            fp = d.get("fingerprint", "")
            _line("Machine ID", fp[:20] + "..." if len(fp) > 20 else fp)
        except Exception as e:
            _line("Error", str(e))
    print()

def check_config():
    _bar()
    print("  NODE CONFIGURATION")
    _bar()
    _line("Telegram Bot", _env("TELEGRAM_BOT_TOKEN")[:12] + "..." if _env("TELEGRAM_BOT_TOKEN") else "[NOT SET]")
    _line("Owner TG ID",  _env("OWNER_TELEGRAM_ID") or "[NOT SET]")
    _line("LLM Model",    _env("LLM_MODEL") or "qwen3.5:4b (default)")
    _line("Ollama URL",   _env("OLLAMA_URL") or "http://localhost:11434")
    _line("Dashboard",    f"http://localhost:{_env('DASHBOARD_PORT') or '7777'}")
    print()

def check_docker():
    _bar()
    print("  DOCKER SERVICES")
    _bar()
    services = _docker_services()
    if not services:
        _line("Docker", "[NOT RUNNING or no compose services]")
    else:
        for name, state, status in services:
            icon = "[UP]  " if state.lower() == "running" else "[DOWN]"
            _line(f"{icon} {name}", status or state)
    print()

def check_server():
    _bar()
    print("  SERVER CONNECTIVITY")
    _bar()
    import urllib.request
    tests = [
        ("Ollama API",      "http://localhost:11434/api/tags"),
        ("Qdrant API",      "http://localhost:6333/healthz"),
        ("Dashboard",       "http://localhost:7777/api/health"),
        ("License Server",  "https://biznode.1bz.biz/api/ping"),
    ]
    for label, url in tests:
        try:
            urllib.request.urlopen(url, timeout=3)
            _line(label, "[OK]  " + url)
        except Exception as e:
            short = str(e)[:40]
            _line(label, f"[FAIL] {short}")
    print()

if __name__ == "__main__":
    print()
    _bar()
    print("  BizNode Node Status")
    print(f"  {NODE_DIR}")
    _bar()
    print()
    check_registration()
    check_trial()
    check_config()
    check_docker()
    check_server()
    _bar()
    print("  Run 'python launcher.py' to start BizNode")
    _bar()
    print()
