"""ASV benchmarks for skeleton compressor overhead.

Measures the time to compress context fragments at various ratios
and fragment counts.  The benchmark covers the hot path that runs
during subplan context inheritance.
"""

from __future__ import annotations

import importlib
import sys
from pathlib import Path

# Ensure the local *source* tree is importable even when ASV has an
# older build of the package installed.
_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.skeleton_compressor import (  # noqa: E402
    SkeletonCompressorService,
)
from cleveragents.domain.models.core.context_fragment import (  # noqa: E402
    ContextFragment,
    FragmentProvenance,
)

# Default provenance for skeleton benchmark fragments.
_SKEL_PROV = FragmentProvenance(resource_uri="bench-skeleton://default")


def _build_fragments(count: int, tokens_each: int = 100) -> list[ContextFragment]:
    """Generate *count* fragments for benchmarking."""
    return [
        ContextFragment(
            fragment_id=f"bench-{i:05d}",
            uko_node=f"bench-skeleton://file/{i}",
            content="x" * tokens_each,
            token_count=tokens_each,
            relevance_score=round(1.0 - (i / max(count, 1)), 4),
            provenance=_SKEL_PROV,
            metadata=(
                {"source_decision_id": f"01HX{'B' * 22}{i:02d}"} if i < 99 else {}
            ),
        )
        for i in range(count)
    ]


class SkeletonCompressorSmallSuite:
    """Benchmark compression of a small fragment set (10 fragments)."""

    def setup(self) -> None:
        self._svc = SkeletonCompressorService()
        self._fragments = _build_fragments(10)

    def time_compress_ratio_0(self) -> None:
        """No compression (pass-through)."""
        self._svc.compress(self._fragments, skeleton_ratio=0.0)

    def time_compress_ratio_03(self) -> None:
        """Default ratio compression."""
        self._svc.compress(self._fragments, skeleton_ratio=0.3)

    def time_compress_ratio_05(self) -> None:
        """Moderate compression."""
        self._svc.compress(self._fragments, skeleton_ratio=0.5)

    def time_compress_ratio_1(self) -> None:
        """Maximum compression."""
        self._svc.compress(self._fragments, skeleton_ratio=1.0)


class SkeletonCompressorMediumSuite:
    """Benchmark compression of a medium fragment set (100 fragments)."""

    def setup(self) -> None:
        self._svc = SkeletonCompressorService()
        self._fragments = _build_fragments(100)

    def time_compress_ratio_03(self) -> None:
        """Default ratio compression."""
        self._svc.compress(self._fragments, skeleton_ratio=0.3)

    def time_compress_ratio_05(self) -> None:
        """Moderate compression."""
        self._svc.compress(self._fragments, skeleton_ratio=0.5)


class SkeletonCompressorLargeSuite:
    """Benchmark compression of a large fragment set (1000 fragments)."""

    def setup(self) -> None:
        self._svc = SkeletonCompressorService()
        self._fragments = _build_fragments(1000)

    def time_compress_ratio_05(self) -> None:
        """Moderate compression over 1000 fragments."""
        self._svc.compress(self._fragments, skeleton_ratio=0.5)

    def time_compress_ratio_08(self) -> None:
        """Heavy compression over 1000 fragments."""
        self._svc.compress(self._fragments, skeleton_ratio=0.8)
