#!/usr/bin/env python3
"""
First-time bootstrap for claude-code-delegate.
Handles: claude binary dedup, auth verification, user setup, and e2e smoke test.
Run once after unpacking the skill into Skills/.
"""
import json
import os
import shutil
import subprocess
import sys
import time
from pathlib import Path

SKILL_DIR = Path(__file__).resolve().parent.parent
SETUP_SCRIPT = SKILL_DIR / "scripts" / "setup.py"
DELEGATE_SCRIPT = SKILL_DIR / "scripts" / "claude_delegate.py"

RED = "\033[91m"
GREEN = "\033[92m"
YELLOW = "\033[93m"
BOLD = "\033[1m"
RESET = "\033[0m"

def log(msg, color=RESET):
    print(f"{color}{msg}{RESET}")

def run(cmd, check=True, capture=True):
    return subprocess.run(cmd, check=check, text=True, capture_output=capture)


def step_ensure_claude_binary():
    log("\n[1/4] Ensuring claude binary...", BOLD)

    result = run(["which", "-a", "claude"], check=False)
    paths = [p.strip() for p in result.stdout.strip().splitlines() if p.strip()] if result.returncode == 0 else []

    if not paths:
        log("  ERROR: claude CLI not found. Install it first:", RED)
        log("    npm install -g @anthropic-ai/claude-code", RED)
        sys.exit(1)

    version_result = run(["claude", "--version"], check=False)
    version = version_result.stdout.strip() if version_result.returncode == 0 else "unknown"
    log(f"  Found claude at: {paths[0]} (version: {version})")

    if len(paths) > 1:
        log(f"  Multiple claude binaries found: {paths}", YELLOW)
        newest = paths[0]
        for p in paths:
            real = os.path.realpath(p)
            if "/root/.local/" in real or "/.nvm/" in real:
                newest = p
                break

        for p in paths:
            if p != newest and p in ("/usr/bin/claude", "/bin/claude"):
                log(f"  Removing stale binary: {p}")
                try:
                    os.remove(p)
                except OSError:
                    pass

        run(["npm", "uninstall", "-g", "@anthropic-ai/claude-code"], check=False)

        target = "/usr/local/bin/claude"
        real_newest = os.path.realpath(newest)
        if newest != target and os.path.exists(real_newest):
            log(f"  Symlinking {real_newest} -> {target}")
            if os.path.exists(target):
                os.remove(target)
            os.symlink(real_newest, target)

    final_version = run(["claude", "--version"], check=False)
    log(f"  ✓ claude {final_version.stdout.strip()}", GREEN)


def step_check_auth():
    log("\n[2/4] Checking claude auth...", BOLD)
    result = run(["claude", "auth", "status"], check=False)
    if '"loggedIn": true' not in result.stdout:
        log("  Claude is not logged in.", YELLOW)
        log("  ACTION REQUIRED: Run 'claude auth login' in your Zo terminal, then rerun this bootstrap.", RED)
        sys.exit(1)
    log("  ✓ Authenticated", GREEN)


def step_run_setup():
    log("\n[3/4] Running setup (creating claude user, copying creds)...", BOLD)
    result = run([sys.executable, str(SETUP_SCRIPT)], check=False)
    print(result.stdout)
    if result.stderr:
        print(result.stderr, file=sys.stderr)

    try:
        data = json.loads(result.stdout)
    except (json.JSONDecodeError, ValueError):
        log("  ERROR: setup.py did not return valid JSON", RED)
        sys.exit(1)

    if not data.get("logged_in"):
        if data.get("token_expired"):
            log("  Token expired. Run 'claude auth login' in Zo terminal, then rerun bootstrap.", RED)
        else:
            log("  Setup reports not logged in. Run 'claude auth login' in Zo terminal, then rerun bootstrap.", RED)
        sys.exit(1)

    log("  ✓ Setup complete", GREEN)


def step_e2e_test():
    log("\n[4/4] End-to-end smoke test...", BOLD)

    create = run([
        sys.executable, str(DELEGATE_SCRIPT),
        "create-session", "--repo", "/home/workspace"
    ], check=False)
    print(create.stdout)
    if create.returncode != 0:
        log(f"  ERROR creating session: {create.stderr}", RED)
        sys.exit(1)

    session_id = None
    for line in create.stdout.splitlines():
        if line.startswith("SESSION_ID="):
            session_id = line.split("=", 1)[1]
    if not session_id:
        log("  ERROR: could not parse SESSION_ID", RED)
        sys.exit(1)

    test_phrase = "hello from delegate"
    send = run([
        sys.executable, str(DELEGATE_SCRIPT),
        "send", "--session-id", session_id,
        "--text", f"Reply with exactly: {test_phrase}"
    ], check=False)
    if send.returncode != 0:
        log(f"  ERROR sending prompt: {send.stderr}", RED)
        run([sys.executable, str(DELEGATE_SCRIPT), "close-session", session_id], check=False)
        sys.exit(1)

    watch = run([
        sys.executable, str(DELEGATE_SCRIPT),
        "watch", session_id, "--timeout", "120", "--quiet"
    ], check=False)

    output = run([
        sys.executable, str(DELEGATE_SCRIPT),
        "read-output", session_id, "--lines", "500"
    ], check=False)

    run([sys.executable, str(DELEGATE_SCRIPT), "close-session", session_id], check=False)

    ok = "STATUS=idle" in output.stdout and test_phrase in output.stdout.lower()
    if ok:
        log(f"  ✓ Smoke test passed — got '{test_phrase}' back", GREEN)
    else:
        log("  ⚠ Smoke test inconclusive — check output above", YELLOW)
        print(output.stdout[-1000:] if len(output.stdout) > 1000 else output.stdout)


def main():
    log(f"{BOLD}claude-code-delegate bootstrap{RESET}")
    log(f"Skill dir: {SKILL_DIR}")
    step_ensure_claude_binary()
    step_check_auth()
    step_run_setup()
    step_e2e_test()
    log(f"\n{GREEN}{BOLD}✓ Bootstrap complete. Skill is ready to use.{RESET}")
    log("See SKILL.md for usage instructions.")


if __name__ == "__main__":
    main()
