"""ASV benchmarks for built-in context strategies batch 1.

Measures the performance of:
- SimpleKeywordStrategy.assemble at varying fragment counts
- SemanticEmbeddingStrategy.assemble at varying fragment counts
- BreadthDepthNavigatorStrategy.assemble at varying fragment counts
- can_handle() call overhead for each strategy
"""

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.application.services.context_strategies import (  # noqa: E402
    BreadthDepthNavigatorStrategy,
    SemanticEmbeddingStrategy,
    SimpleKeywordStrategy,
)
from cleveragents.domain.models.core.context_fragment import (  # noqa: E402
    ContextBudget,
    ContextFragment,
    FragmentProvenance,
)

_DEFAULT_PROV = FragmentProvenance(resource_uri="bench://default")


def _make_fragments(count: int) -> list[ContextFragment]:
    """Build *count* test fragments with distinct URIs and content."""
    frags: list[ContextFragment] = []
    for i in range(count):
        frags.append(
            ContextFragment(
                uko_node=f"project://app/mod{i}.py",
                content=f"Module {i} with async database connection handler pool",
                token_count=20,
                detail_depth=min(i % 10, 9),
                relevance_score=round(0.1 + (i % 9) * 0.1, 2),
                provenance=_DEFAULT_PROV,
            )
        )
    return frags


class SimpleKeywordSuite:
    """Benchmark SimpleKeywordStrategy assemble throughput."""

    def setup(self) -> None:
        self.strategy = SimpleKeywordStrategy()
        self.strategy.set_query("async database connection")
        self.budget = ContextBudget(max_tokens=50_000, reserved_tokens=0)
        self.frags_10 = _make_fragments(10)
        self.frags_100 = _make_fragments(100)
        self.frags_1000 = _make_fragments(1000)

    def time_assemble_10_fragments(self) -> None:
        """Assemble 10 fragments with SimpleKeywordStrategy."""
        self.strategy.assemble(self.frags_10, self.budget)

    def time_assemble_100_fragments(self) -> None:
        """Assemble 100 fragments with SimpleKeywordStrategy."""
        self.strategy.assemble(self.frags_100, self.budget)

    def time_assemble_1000_fragments(self) -> None:
        """Assemble 1000 fragments with SimpleKeywordStrategy."""
        self.strategy.assemble(self.frags_1000, self.budget)

    def time_can_handle(self) -> None:
        """Benchmark can_handle call overhead."""
        self.strategy.can_handle({"query": "test search"})


class SemanticEmbeddingSuite:
    """Benchmark SemanticEmbeddingStrategy assemble throughput."""

    def setup(self) -> None:
        self.strategy = SemanticEmbeddingStrategy()
        self.strategy.set_query("async database connection")
        self.budget = ContextBudget(max_tokens=50_000, reserved_tokens=0)
        self.frags_10 = _make_fragments(10)
        self.frags_100 = _make_fragments(100)
        self.frags_1000 = _make_fragments(1000)

    def time_assemble_10_fragments(self) -> None:
        """Assemble 10 fragments with SemanticEmbeddingStrategy."""
        self.strategy.assemble(self.frags_10, self.budget)

    def time_assemble_100_fragments(self) -> None:
        """Assemble 100 fragments with SemanticEmbeddingStrategy."""
        self.strategy.assemble(self.frags_100, self.budget)

    def time_assemble_1000_fragments(self) -> None:
        """Assemble 1000 fragments with SemanticEmbeddingStrategy."""
        self.strategy.assemble(self.frags_1000, self.budget)

    def time_can_handle(self) -> None:
        """Benchmark can_handle call overhead."""
        self.strategy.can_handle({"query": "test search"})


class BreadthDepthNavigatorSuite:
    """Benchmark BreadthDepthNavigatorStrategy assemble throughput."""

    def setup(self) -> None:
        self.strategy = BreadthDepthNavigatorStrategy()
        self.strategy.set_focus(["project://app/mod0.py"])
        self.budget = ContextBudget(max_tokens=50_000, reserved_tokens=0)
        self.frags_10 = _make_fragments(10)
        self.frags_100 = _make_fragments(100)
        self.frags_1000 = _make_fragments(1000)

    def time_assemble_10_fragments(self) -> None:
        """Assemble 10 fragments with BreadthDepthNavigatorStrategy."""
        self.strategy.assemble(self.frags_10, self.budget)

    def time_assemble_100_fragments(self) -> None:
        """Assemble 100 fragments with BreadthDepthNavigatorStrategy."""
        self.strategy.assemble(self.frags_100, self.budget)

    def time_assemble_1000_fragments(self) -> None:
        """Assemble 1000 fragments with BreadthDepthNavigatorStrategy."""
        self.strategy.assemble(self.frags_1000, self.budget)

    def time_can_handle(self) -> None:
        """Benchmark can_handle call overhead."""
        self.strategy.can_handle({"focus": ["project://app/mod0.py"]})
