"""obol wrap - run any command under Obol monitoring.

Usage:
    obol wrap -- python my_agent.py
    obol wrap --name "my-bot" -- aider
    obol wrap -- ./run_agent.sh

For Python commands: automatically patches file I/O, subprocess,
and HTTP calls. Every action the agent takes gets logged to Obol.

For non-Python commands: tracks process lifecycle and environment.
"""
import json
import os
import subprocess
import sys
import tempfile


def setup_parser(subparsers):
    p = subparsers.add_parser(
        "wrap",
        help="Run any command under Obol monitoring",
    )
    p.add_argument("--name", "-n", help="Agent name (default: command name)")
    p.add_argument("command", nargs="...", help="Command to run (after --)")
    p.set_defaults(func=cmd_wrap)


def cmd_wrap(args):
    command = args.command
    if not command:
        print("Usage: obol wrap -- <command>", file=sys.stderr)
        print("Example: obol wrap -- python my_agent.py", file=sys.stderr)
        sys.exit(1)

    # Strip leading -- if present
    if command[0] == "--":
        command = command[1:]
    if not command:
        print("Error: no command specified", file=sys.stderr)
        sys.exit(1)

    from obol.cli._base import get_api, error
    from obol.api import ObolAPIError

    api = get_api()

    # Determine agent name
    agent_name = args.name or os.path.basename(command[0])

    # Register or find agent
    agent_id = _get_or_create_agent(api, agent_name)
    if not agent_id:
        error("Could not register agent")

    # Generate session ID
    import secrets
    session_id = secrets.token_hex(8)

    # Record session start
    try:
        api.record_event(
            agent_id=agent_id,
            session_id=session_id,
            action="session.start",
            target=" ".join(command),
            result="success",
            metadata={"command": command, "cwd": os.getcwd()},
        )
    except Exception:
        pass

    print(f"  obol: monitoring '{agent_name}' (agent {agent_id})")
    print(f"  obol: session {session_id}")
    print(f"  obol: dashboard https://obol.grayowlresearch.com/dashboard")
    print()

    # Build environment
    env = os.environ.copy()
    env["OBOL_API_KEY"] = api.api_key
    env["OBOL_API_URL"] = api.base_url
    env["OBOL_AGENT_ID"] = str(agent_id)
    env["OBOL_SESSION_ID"] = session_id
    env["OBOL_WRAP"] = "1"

    # For Python commands: inject interceptors via PYTHONSTARTUP
    _cmd0 = os.path.basename(command[0]).lower()
    _python_names = {"python", "python3", "python.exe", "python3.exe"}
    is_python = _cmd0 in _python_names
    startup_file = None

    if is_python:
        startup_file = _create_python_startup(agent_id, session_id, api.api_key, api.base_url)
        env["PYTHONSTARTUP"] = startup_file

    # Run the command
    exit_code = 1
    try:
        proc = subprocess.run(command, env=env)
        exit_code = proc.returncode
    except KeyboardInterrupt:
        exit_code = 130
    except FileNotFoundError:
        print(f"Error: command not found: {command[0]}", file=sys.stderr)
        exit_code = 127
    finally:
        # Record session end
        try:
            api.record_event(
                agent_id=agent_id,
                session_id=session_id,
                action="session.end",
                result="success" if exit_code == 0 else "error",
                metadata={"exit_code": exit_code},
            )
        except Exception:
            pass

        # Cleanup
        if startup_file and os.path.exists(startup_file):
            os.unlink(startup_file)

        print()
        print(f"  obol: session ended (exit {exit_code})")

    sys.exit(exit_code)


def _get_or_create_agent(api, name):
    """Find existing agent by name or create new one."""
    from obol.api import ObolAPIError

    try:
        result = api.list_agents()
        agents = result.get("agents", [])
        for a in agents:
            if a.get("name") == name:
                return a["id"]
    except Exception:
        pass

    try:
        result = api.register_agent(name=name, platform="custom")
        return result.get("id")
    except ObolAPIError:
        return None


def _create_python_startup(agent_id, session_id, api_key, api_url):
    """Create a PYTHONSTARTUP file that installs Obol interceptors."""
    code = f'''
# Obol auto-monitoring (injected by obol wrap)
import os as _os
_os.environ.setdefault("OBOL_WRAP", "1")

try:
    from obol.interceptors import install_interceptors
    from obol.api import ObolAPI

    _obol_api = ObolAPI("{api_key}", "{api_url}")

    def _obol_callback(action, target, content, result, duration_ms):
        try:
            import hashlib
            target_hash = None
            content_size = None
            if content:
                target_hash = hashlib.sha256(content if isinstance(content, bytes) else content.encode()).hexdigest()[:16]
                content_size = len(content)
            _obol_api.record_event(
                agent_id={agent_id},
                session_id="{session_id}",
                action=action,
                target=str(target)[:2000] if target else None,
                target_hash=target_hash,
                content_size=content_size,
                result=result or "success",
                duration_ms=duration_ms,
            )
        except Exception:
            pass

    install_interceptors(_obol_callback)
except ImportError:
    pass  # obol not in this environment
except Exception:
    pass
'''

    fd, path = tempfile.mkstemp(prefix="obol_startup_", suffix=".py")
    with os.fdopen(fd, "w") as f:
        f.write(code)
    return path
