"""ASV benchmarks for hierarchical actor YAML parsing performance.

Measures the performance of:
- Parsing actors with per-node LSP bindings
- Parsing actors with tool-source references
- Parsing actors with subgraph actor_ref
- Parsing actors with full hierarchical features combined
"""

from __future__ import annotations

import importlib
import sys
from pathlib import Path

_SRC = str(Path(__file__).resolve().parents[1] / "src")
if _SRC not in sys.path:
    sys.path.insert(0, _SRC)

import cleveragents  # noqa: E402

importlib.reload(cleveragents)

from cleveragents.actor.schema import ActorConfigSchema  # noqa: E402


def _graph_data(nodes: list[dict], *, skills: list[str] | None = None) -> dict:
    node_ids = [n["id"] for n in nodes]
    edges = []
    for i in range(len(node_ids) - 1):
        edges.append({"from_node": node_ids[i], "to_node": node_ids[i + 1]})
    data: dict = {
        "name": "bench/hierarchy",
        "type": "graph",
        "description": "Benchmark hierarchical actor",
        "model": "gpt-4",
        "route": {
            "nodes": nodes,
            "edges": edges,
            "entry_node": node_ids[0],
            "exit_nodes": [node_ids[-1]],
        },
    }
    if skills:
        data["skills"] = skills
    return data


_AGENT_NODE = {
    "id": "agent",
    "type": "agent",
    "name": "Agent",
    "description": "Agent node",
    "config": {"model": "gpt-4"},
}

_LSP_NODE = {
    "id": "lsp_agent",
    "type": "agent",
    "name": "LSP Agent",
    "description": "Agent with LSP binding",
    "config": {"model": "gpt-4"},
    "lsp_binding": {
        "server": "local/pyright",
        "languages": ["python"],
        "capabilities": ["diagnostics", "hover"],
    },
}

_TS_NODE = {
    "id": "ts_agent",
    "type": "agent",
    "name": "Tool Source Agent",
    "description": "Agent with tool sources",
    "config": {},
    "tool_sources": [
        {"type": "skill", "name": "local/file-ops"},
        {"type": "mcp", "name": "local/filesystem"},
        {"type": "builtin", "group": "git_operations"},
    ],
}

_SUBGRAPH_NODE = {
    "id": "sub",
    "type": "subgraph",
    "name": "Sub",
    "description": "Subgraph node",
    "actor_ref": "local/code-reviewer",
}


class TimeLspBindingParse:
    """Benchmark parsing actors with LSP bindings."""

    def setup(self) -> None:
        self.data = _graph_data([_LSP_NODE])

    def time_parse_lsp_binding(self) -> None:
        ActorConfigSchema.model_validate(self.data)


class TimeToolSourcesParse:
    """Benchmark parsing actors with tool-source references."""

    def setup(self) -> None:
        self.data = _graph_data([_TS_NODE])

    def time_parse_tool_sources(self) -> None:
        ActorConfigSchema.model_validate(self.data)


class TimeSubgraphRefParse:
    """Benchmark parsing actors with subgraph actor_ref."""

    def setup(self) -> None:
        self.data = _graph_data(
            [_AGENT_NODE, _SUBGRAPH_NODE],
        )

    def time_parse_subgraph_ref(self) -> None:
        ActorConfigSchema.model_validate(self.data)


class TimeFullHierarchyParse:
    """Benchmark parsing a full hierarchical actor with all features."""

    def setup(self) -> None:
        self.data = _graph_data(
            [_LSP_NODE, _TS_NODE, _SUBGRAPH_NODE],
            skills=["local/file-ops", "local/git-ops"],
        )
        self.data["lsp"] = ["local/pyright"]
        self.data["lsp_capabilities"] = ["diagnostics"]

    def time_parse_full_hierarchy(self) -> None:
        ActorConfigSchema.model_validate(self.data)


time_lsp = TimeLspBindingParse()
time_ts = TimeToolSourcesParse()
time_sg = TimeSubgraphRefParse()
time_full = TimeFullHierarchyParse()
