"""ASV benchmarks for M5 ACMS pipeline and context smoke suite runtime.

Measures the performance of:
- Context policy resolution across ACMS phases
- Budget enforcement checks (file size and total size)
- Fixture loading overhead
- Context view construction with various configurations
"""

from __future__ import annotations

import importlib
import json
import sys
from pathlib import Path
from typing import ClassVar

_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.domain.models.core.context_policy import (  # noqa: E402
    ContextView,
    ProjectContextPolicy,
)

_FIXTURES_DIR = Path(__file__).resolve().parents[1] / "features" / "fixtures" / "m5"


def _load_fixture(name: str) -> dict:
    """Load a fixture JSON file."""
    return json.loads((_FIXTURES_DIR / name).read_text(encoding="utf-8"))


def _make_policy_with_overrides() -> ProjectContextPolicy:
    """Create a policy with all phase overrides."""
    return ProjectContextPolicy(
        default_view=ContextView(
            include_paths=["src/**/*.py"],
            exclude_paths=["**/__pycache__/**"],
            max_file_size=524288,
            max_total_size=10485760,
        ),
        strategize_view=ContextView(
            include_paths=["src/**/*.py", "docs/**/*.md"],
            max_file_size=262144,
            max_total_size=5242880,
        ),
        execute_view=ContextView(
            include_paths=["src/**/*.py"],
            max_file_size=524288,
        ),
        apply_view=ContextView(
            include_paths=["src/**/*.py", "tests/**/*.py"],
        ),
    )


class PolicyResolutionSuite:
    """Benchmark context policy view resolution across phases."""

    params: ClassVar[list[str]] = ["default", "strategize", "execute", "apply"]
    param_names: ClassVar[list[str]] = ["phase"]

    def setup(self, phase: str) -> None:
        self.policy = _make_policy_with_overrides()

    def time_resolve_view(self, phase: str) -> None:
        self.policy.resolve_view(phase)


class BudgetEnforcementSuite:
    """Benchmark budget enforcement checks."""

    params: ClassVar[list[int]] = [100, 1000, 10000]
    param_names: ClassVar[list[str]] = ["file_count"]

    def setup(self, file_count: int) -> None:
        self.view = ContextView(max_file_size=8192, max_total_size=1048576)
        self.files = [
            {"path": f"src/file_{i}.py", "size": (i % 20) * 1024}
            for i in range(file_count)
        ]

    def time_check_file_budget(self, file_count: int) -> None:
        max_size = self.view.max_file_size
        assert max_size is not None
        for f in self.files:
            _ = f["size"] <= max_size

    def time_check_total_budget(self, file_count: int) -> None:
        total = sum(f["size"] for f in self.files)
        max_total = self.view.max_total_size
        assert max_total is not None
        _ = total <= max_total


class FixtureLoadSuite:
    """Benchmark fixture file loading."""

    def time_load_policy_fixture(self) -> None:
        _load_fixture("acms_context_policy.json")

    def time_load_large_project_fixture(self) -> None:
        _load_fixture("large_project_context.json")

    def time_load_analysis_fixture(self) -> None:
        _load_fixture("context_analysis_results.json")

    def time_load_all_fixtures(self) -> None:
        _load_fixture("acms_context_policy.json")
        _load_fixture("large_project_context.json")
        _load_fixture("context_analysis_results.json")


class ContextViewConstructionSuite:
    """Benchmark ContextView and ProjectContextPolicy construction."""

    params: ClassVar[list[int]] = [1, 10, 50]
    param_names: ClassVar[list[str]] = ["path_count"]

    def setup(self, path_count: int) -> None:
        self.include_paths = [f"src/module_{i}/**/*.py" for i in range(path_count)]
        self.exclude_paths = [f"**/__cache_{i}__/**" for i in range(path_count)]

    def time_construct_view(self, path_count: int) -> None:
        ContextView(
            include_paths=self.include_paths,
            exclude_paths=self.exclude_paths,
            max_file_size=524288,
            max_total_size=10485760,
        )

    def time_construct_full_policy(self, path_count: int) -> None:
        view = ContextView(
            include_paths=self.include_paths,
            exclude_paths=self.exclude_paths,
        )
        ProjectContextPolicy(
            default_view=view,
            strategize_view=view,
            execute_view=view,
            apply_view=view,
        )
