"""Benchmarks for security scan configuration parsing and validation."""

from __future__ import annotations

import ast
from pathlib import Path

import yaml

NOXFILE_PATH = Path("noxfile.py")
PRECOMMIT_PATH = Path(".pre-commit-config.yaml")
SEMGREP_PATH = Path(".semgrep.yml")


class TimeSecurityConfigParsing:
    """Measure security configuration parsing performance."""

    def setup(self) -> None:
        """Read source files once for reuse."""
        if NOXFILE_PATH.exists():
            self.noxfile_text = NOXFILE_PATH.read_text()
        else:
            self.noxfile_text = ""
        if PRECOMMIT_PATH.exists():
            self.precommit_text = PRECOMMIT_PATH.read_text()
        else:
            self.precommit_text = ""
        if SEMGREP_PATH.exists():
            self.semgrep_text = SEMGREP_PATH.read_text()
        else:
            self.semgrep_text = ""

    def time_parse_precommit_yaml(self) -> None:
        """Benchmark YAML parsing of .pre-commit-config.yaml."""
        if self.precommit_text:
            yaml.safe_load(self.precommit_text)

    def time_extract_security_hooks(self) -> None:
        """Benchmark extracting security-related hooks from pre-commit config."""
        if self.precommit_text:
            data = yaml.safe_load(self.precommit_text)
            security_hooks = []
            for repo in data.get("repos", []):
                for hook in repo.get("hooks", []):
                    hook_id = hook.get("id", "")
                    if hook_id in ("bandit", "semgrep-eval-exec"):
                        security_hooks.append(hook)

    def time_parse_semgrep_rules(self) -> None:
        """Benchmark parsing semgrep configuration rules."""
        if self.semgrep_text:
            data = yaml.safe_load(self.semgrep_text)
            _ = data.get("rules", [])

    def time_parse_security_scan_session(self) -> None:
        """Benchmark AST extraction of security_scan session from noxfile."""
        if self.noxfile_text:
            tree = ast.parse(self.noxfile_text)
            for node in ast.walk(tree):
                if isinstance(node, ast.FunctionDef) and node.name == "security_scan":
                    _ = ast.get_source_segment(self.noxfile_text, node)
                    break
