"""ASV benchmarks for devcontainer handler auto-discovery throughput.

Measures the performance of:
- Devcontainer discovery on projects with many subdirectories
- Handler resolver cache performance for DevcontainerHandler
- Discovery result construction overhead
- is_trigger_type check throughput
"""

from __future__ import annotations

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

try:
    from cleveragents.resource.handlers.discovery import (
        DevcontainerDiscoveryResult,
        discover_devcontainers,
        is_trigger_type,
    )
    from cleveragents.resource.handlers.resolver import (
        clear_handler_cache,
        resolve_handler,
    )
except ModuleNotFoundError:
    sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
    from cleveragents.resource.handlers.discovery import (
        DevcontainerDiscoveryResult,
        discover_devcontainers,
        is_trigger_type,
    )
    from cleveragents.resource.handlers.resolver import (
        clear_handler_cache,
        resolve_handler,
    )

_VALID_DC_JSON: str = json.dumps(
    {"name": "bench-devcontainer", "image": "ubuntu:latest"}
)


class TimeDiscoveryThroughput:
    """Benchmark auto-discovery throughput on projects with many subdirs."""

    timeout = 60
    params: ClassVar[list[int]] = [10, 50, 100]
    param_names: ClassVar[list[str]] = ["num_subdirs"]

    def setup(self, num_subdirs: int) -> None:
        """Create a temp directory with many subdirectories."""
        self.tmp_dir = tempfile.mkdtemp()
        base = Path(self.tmp_dir)
        # Create the devcontainer config
        dc_dir = base / ".devcontainer"
        dc_dir.mkdir()
        (dc_dir / "devcontainer.json").write_text(_VALID_DC_JSON, encoding="utf-8")
        # Create many sibling directories (noise)
        for i in range(num_subdirs):
            (base / f"subdir_{i:04d}").mkdir()

    def teardown(self, num_subdirs: int) -> None:
        """Clean up temp directory."""
        import shutil

        shutil.rmtree(self.tmp_dir, ignore_errors=True)

    def time_discovery_with_subdirs(self, num_subdirs: int) -> None:
        """Time discovery scanning with many peer directories."""
        discover_devcontainers(self.tmp_dir, "git-checkout")


class TimeDiscoveryEmpty:
    """Benchmark discovery on directory with no devcontainer."""

    timeout = 30

    def setup(self) -> None:
        """Create empty temp directory."""
        self.tmp_dir = tempfile.mkdtemp()
        base = Path(self.tmp_dir)
        for i in range(50):
            (base / f"subdir_{i:04d}").mkdir()

    def teardown(self) -> None:
        """Clean up."""
        import shutil

        shutil.rmtree(self.tmp_dir, ignore_errors=True)

    def time_discovery_no_match(self) -> None:
        """Time discovery when no devcontainer exists."""
        discover_devcontainers(self.tmp_dir, "git-checkout")


class TimeHandlerResolver:
    """Benchmark handler resolver cache for DevcontainerHandler."""

    timeout = 30
    _ref = "cleveragents.resource.handlers.devcontainer:DevcontainerHandler"

    def setup(self) -> None:
        """Pre-warm resolver cache."""
        clear_handler_cache()
        resolve_handler(self._ref)

    def time_cached_resolution(self) -> None:
        """Time cached handler resolution (should be near-zero)."""
        resolve_handler(self._ref)

    def time_cold_resolution(self) -> None:
        """Time cold handler resolution (import + instantiate)."""
        clear_handler_cache()
        resolve_handler(self._ref)


class TimeIsTriggerType:
    """Benchmark is_trigger_type check throughput."""

    timeout = 10

    def time_trigger_type_positive(self) -> None:
        """Time is_trigger_type for a trigger type."""
        for _ in range(1000):
            is_trigger_type("git-checkout")

    def time_trigger_type_negative(self) -> None:
        """Time is_trigger_type for a non-trigger type."""
        for _ in range(1000):
            is_trigger_type("devcontainer-instance")


class TimeDiscoveryResult:
    """Benchmark DevcontainerDiscoveryResult construction."""

    timeout = 30

    def setup(self) -> None:
        """Create temp file for result construction."""
        self.tmp_dir = tempfile.mkdtemp()
        self.dc_file = Path(self.tmp_dir) / "devcontainer.json"
        self.dc_file.write_text(_VALID_DC_JSON, encoding="utf-8")
        self.config_data: dict[str, object] = json.loads(_VALID_DC_JSON)

    def teardown(self) -> None:
        """Clean up."""
        import shutil

        shutil.rmtree(self.tmp_dir, ignore_errors=True)

    def time_result_construction(self) -> None:
        """Time DevcontainerDiscoveryResult instantiation."""
        for _ in range(1000):
            DevcontainerDiscoveryResult(
                config_path=self.dc_file,
                config_data=self.config_data,
                parent_location=self.tmp_dir,
            )
