"""Known AI agent registry.

Each entry defines how to detect and wrap a known AI agent/tool.
Used by `obol setup` to auto-detect and configure monitoring.
"""
import os
import sys
import shutil

# Each agent has:
#   name:        Human-readable name
#   slug:        Machine identifier (used as agent name in Obol)
#   description: What it is, for users who might not know
#   detect:      Function that returns True if installed
#   wrap_method: "hooks" (config-based) | "interceptors" (python monkey-patch) | "wrap" (obol wrap)
#   config_dir:  Where its config lives (if applicable)
#   platform:    Platform string for agent registration
#   model:       Default model string


def _dir_exists(path):
    return os.path.isdir(os.path.expanduser(path))


def _appdata_dir_exists(name):
    """Check for a config dir in OS-appropriate app data locations."""
    # Linux: ~/.config/<name>
    if sys.platform.startswith("linux"):
        xdg = os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config"))
        if os.path.isdir(os.path.join(xdg, name)):
            return True
    # macOS: ~/Library/Application Support/<name>
    elif sys.platform == "darwin":
        app_support = os.path.expanduser("~/Library/Application Support")
        if os.path.isdir(os.path.join(app_support, name)):
            return True
    # Windows: %APPDATA%/<name> or %LOCALAPPDATA%/<name>
    elif sys.platform == "win32":
        for env_var in ("APPDATA", "LOCALAPPDATA"):
            base = os.environ.get(env_var)
            if base and os.path.isdir(os.path.join(base, name)):
                return True
    # Fallback: ~/.config/<name> (works on all via expanduser)
    return _dir_exists(f"~/.config/{name}")


def _cmd_exists(name):
    return shutil.which(name) is not None


def _pip_has(package):
    """Check if a Python package is importable (without importing it fully)."""
    try:
        import importlib.util
        return importlib.util.find_spec(package) is not None
    except Exception:
        return False


KNOWN_AGENTS = [
    {
        "name": "Claude Code",
        "slug": "claude-code",
        "description": "Anthropic's AI coding agent for the terminal",
        "detect": lambda: _dir_exists("~/.claude"),
        "wrap_method": "hooks",
        "config_dir": "~/.claude",
        "platform": "claude-code",
        "model": "claude-opus-4-5",
        "capabilities": ["bash", "read", "write", "edit", "glob", "grep", "web"],
    },
    {
        "name": "Cursor",
        "slug": "cursor",
        "description": "AI-powered code editor (fork of VS Code)",
        "detect": lambda: _dir_exists("~/.cursor") or _dir_exists("~/.cursor-server"),
        "wrap_method": "hooks",
        "config_dir": "~/.cursor",
        "platform": "cursor",
        "model": "varies",
        "capabilities": ["read", "write", "edit", "terminal"],
    },
    {
        "name": "Windsurf",
        "slug": "windsurf",
        "description": "Codeium's AI-powered code editor",
        "detect": lambda: _dir_exists("~/.codeium") or _cmd_exists("windsurf"),
        "wrap_method": "hooks",
        "config_dir": "~/.codeium",
        "platform": "windsurf",
        "model": "varies",
        "capabilities": ["read", "write", "edit", "terminal"],
    },
    {
        "name": "GitHub Copilot",
        "slug": "github-copilot",
        "description": "GitHub's AI pair programmer (runs inside editors)",
        "detect": lambda: (
            _appdata_dir_exists("github-copilot")
            or _dir_exists("~/.copilot")
        ),
        "wrap_method": "hooks",
        "config_dir": "~/.config/github-copilot",
        "platform": "github-copilot",
        "model": "varies",
        "capabilities": ["code-completion", "chat"],
    },
    {
        "name": "Aider",
        "slug": "aider",
        "description": "AI pair programming in the terminal",
        "detect": lambda: _cmd_exists("aider") or _pip_has("aider"),
        "wrap_method": "wrap",
        "config_dir": None,
        "platform": "aider",
        "model": "varies",
        "capabilities": ["read", "write", "edit", "bash"],
    },
    {
        "name": "Open Interpreter",
        "slug": "open-interpreter",
        "description": "Run code with natural language (terminal agent)",
        "detect": lambda: (
            _appdata_dir_exists("open-interpreter")
            or _cmd_exists("interpreter")
            or _pip_has("interpreter")
        ),
        "wrap_method": "wrap",
        "config_dir": "~/.config/open-interpreter",
        "platform": "open-interpreter",
        "model": "varies",
        "capabilities": ["bash", "python", "read", "write"],
    },
    {
        "name": "Codex CLI",
        "slug": "codex-cli",
        "description": "OpenAI's terminal coding agent",
        "detect": lambda: _cmd_exists("codex"),
        "wrap_method": "wrap",
        "config_dir": None,
        "platform": "codex-cli",
        "model": "codex",
        "capabilities": ["bash", "read", "write", "edit"],
    },
    {
        "name": "LangChain Agent",
        "slug": "langchain-agent",
        "description": "Python framework for building LLM agents",
        "detect": lambda: _pip_has("langchain"),
        "wrap_method": "interceptors",
        "config_dir": None,
        "platform": "langchain",
        "model": "varies",
        "capabilities": ["tools", "chains", "agents"],
    },
    {
        "name": "CrewAI Agent",
        "slug": "crewai-agent",
        "description": "Multi-agent orchestration framework",
        "detect": lambda: _pip_has("crewai"),
        "wrap_method": "interceptors",
        "config_dir": None,
        "platform": "crewai",
        "model": "varies",
        "capabilities": ["tools", "delegation", "multi-agent"],
    },
    {
        "name": "AutoGen Agent",
        "slug": "autogen-agent",
        "description": "Microsoft's multi-agent conversation framework",
        "detect": lambda: _pip_has("autogen") or _pip_has("pyautogen"),
        "wrap_method": "interceptors",
        "config_dir": None,
        "platform": "autogen",
        "model": "varies",
        "capabilities": ["tools", "code-execution", "multi-agent"],
    },
    {
        "name": "OpenAI Agents SDK",
        "slug": "openai-agents",
        "description": "OpenAI's Python SDK with agent capabilities",
        "detect": lambda: _pip_has("openai") and not _pip_has("langchain"),
        "wrap_method": "interceptors",
        "config_dir": None,
        "platform": "openai-sdk",
        "model": "gpt-4",
        "capabilities": ["tools", "code-interpreter"],
    },
]


def detect_installed():
    """Return list of known agents detected on this machine."""
    found = []
    for agent in KNOWN_AGENTS:
        try:
            if agent["detect"]():
                found.append(agent)
        except Exception:
            pass
    return found


def get_agent(slug):
    """Look up an agent by slug."""
    for agent in KNOWN_AGENTS:
        if agent["slug"] == slug:
            return agent
    return None


def all_agents():
    """Return all known agents (for listing)."""
    return KNOWN_AGENTS
