"""Tool definitions — auto-loaded from turnstone/tools/*.json."""

from __future__ import annotations

import json
from pathlib import Path
from typing import Any

_TOOLS_DIR = Path(__file__).resolve().parent.parent / "tools"
_META_KEYS = {"agent", "task_agent", "coordinator", "auto_approve", "primary_key"}


def _load_tools() -> tuple[list[dict[str, Any]], dict[str, Any]]:
    """Load all .json files from the tools directory.

    Returns (tool_defs, metadata) where:
      - tool_defs: list of OpenAI function-calling dicts
      - metadata: dict mapping tool_name -> {agent, task_agent, coordinator,
                  auto_approve, primary_key}
    """
    tools = []
    meta = {}
    for path in sorted(_TOOLS_DIR.glob("*.json")):
        with open(path) as f:
            raw = json.load(f)
        name = raw["name"]
        # Extract turnstone metadata, leave only OpenAI schema fields
        tool_meta = {k: raw.pop(k) for k in list(raw) if k in _META_KEYS}
        meta[name] = tool_meta
        tools.append({"type": "function", "function": raw})
    return tools, meta


TOOLS, _META = _load_tools()

AGENT_TOOLS = [t for t in TOOLS if _META[t["function"]["name"]].get("agent")]
TASK_AGENT_TOOLS = [t for t in TOOLS if _META[t["function"]["name"]].get("task_agent")]
COORDINATOR_TOOLS = [t for t in TOOLS if _META[t["function"]["name"]].get("coordinator")]
# Interactive sessions — the default session kind — must NOT see coordinator
# tools (``spawn_workstream`` et al.) in their tool set.  Coordinator tools
# require a ``coord_client`` that only console-hosted coordinator sessions
# have, and exposing them to interactive sessions also pollutes the
# tool-search threshold count.  ``TOOLS`` stays as the union for
# introspection / schema docs / eval catalogs.
INTERACTIVE_TOOLS = [t for t in TOOLS if not _META[t["function"]["name"]].get("coordinator")]
INTERACTIVE_TOOL_NAMES = frozenset(t["function"]["name"] for t in INTERACTIVE_TOOLS)
AGENT_AUTO_TOOLS = {n for n, m in _META.items() if m.get("auto_approve")}
TASK_AUTO_TOOLS = {n for n, m in _META.items() if m.get("auto_approve")}
PRIMARY_KEY_MAP = {n: m["primary_key"] for n, m in _META.items() if "primary_key" in m}
BUILTIN_TOOL_NAMES = frozenset(_META)


def merge_mcp_tools(
    builtin: list[dict[str, Any]], mcp_tools: list[dict[str, Any]]
) -> list[dict[str, Any]]:
    """Merge built-in tools with MCP tools.

    Built-in tools come first so the LLM sees them with natural priority.
    Returns a new list; neither input is mutated.
    """
    return builtin + mcp_tools
