"""ASV benchmarks for SEC1 config security scanner.

Measures performance of the security scanner across varying content sizes
and numbers of violations to establish a baseline for config parsing
performance.
"""

from __future__ import annotations

import contextlib
import sys
from pathlib import Path

try:
    from cleveragents.config.security_scanner import (
        scan_content,
        scan_file,
        validate_config_safety,
    )
except ModuleNotFoundError:
    sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
    from cleveragents.config.security_scanner import (
        scan_content,
        scan_file,
        validate_config_safety,
    )

# ---------------------------------------------------------------------------
# Fixtures
# ---------------------------------------------------------------------------

_CLEAN_SMALL = "name: project\nversion: 1.0.0\ndescription: safe\n"

_CLEAN_LARGE = "\n".join(f"key_{i}: value_{i}" for i in range(500))

_DIRTY_SMALL = "safe: true\ntransform: eval('1+1')\nrunner: exec('import os')\n"

_DIRTY_LARGE = "\n".join(
    f"item_{i}: eval('x')" if i % 50 == 0 else f"item_{i}: safe" for i in range(500)
)


# ---------------------------------------------------------------------------
# Benchmark suites
# ---------------------------------------------------------------------------


class TimeScanContent:
    """Benchmark scan_content on in-memory strings."""

    def time_clean_small(self) -> None:
        """Scan a small clean config string."""
        scan_content(_CLEAN_SMALL, "<bench>")

    def time_clean_large(self) -> None:
        """Scan a large clean config string (500 lines)."""
        scan_content(_CLEAN_LARGE, "<bench>")

    def time_dirty_small(self) -> None:
        """Scan a small config with violations."""
        scan_content(_DIRTY_SMALL, "<bench>")

    def time_dirty_large(self) -> None:
        """Scan a large config with scattered violations."""
        scan_content(_DIRTY_LARGE, "<bench>")


class TimeValidateConfigSafety:
    """Benchmark validate_config_safety (raises on violations)."""

    def time_clean_content(self) -> None:
        """Validate clean content (no exception)."""
        validate_config_safety(_CLEAN_SMALL, "<bench>")

    def time_dirty_content_caught(self) -> None:
        """Validate dirty content (exception caught)."""
        with contextlib.suppress(Exception):
            validate_config_safety(_DIRTY_SMALL, "<bench>")


class TimeScanFile:
    """Benchmark scan_file on actual project files."""

    def setup(self) -> None:
        """Locate a real config file for benchmarking."""
        self.pyproject_path = Path("pyproject.toml")
        if not self.pyproject_path.exists():
            self.pyproject_path = Path(__file__).resolve().parents[1] / "pyproject.toml"
        if not self.pyproject_path.exists():
            raise FileNotFoundError(
                "pyproject.toml not found — TimeScanFile benchmark cannot run"
            )

    def time_scan_pyproject_toml(self) -> None:
        """Scan pyproject.toml for violations."""
        scan_file(self.pyproject_path)
