"""ASV benchmarks for the semantic validation service.

Measures the performance of:
- Individual rule checks (syntax, import, reference, cycle, misuse, symbol)
- Rule registry operations (register, lookup, list)
- Validation cache operations (put, get, compute_hash)
- Service orchestration (check_file, as_pipeline_results)
"""

from __future__ import annotations

import sys
from pathlib import Path

_SRC = str(Path(__file__).resolve().parents[1] / "src")
if _SRC not in sys.path:
    sys.path.insert(0, _SRC)

from cleveragents.application.services.semantic_validation_rules import (  # noqa: E402
    APIMisuseRule,
    BrokenReferenceRule,
    DuplicateImportRule,
    MissingImportRule,
    MissingSymbolRule,
    SemanticCheckResult,
    SemanticValidationSeverity,
    SyntaxCheckRule,
)
from cleveragents.application.services.semantic_validation_service import (  # noqa: E402
    SemanticValidationCache,
    SemanticValidationService,
    create_default_registry,
)

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

VALID_PYTHON = """\
import os
import sys
import json

x = 10

def hello():
    return x

class Greeter:
    def greet(self):
        return hello()

def compute():
    return x + 1
"""

LARGE_PYTHON = VALID_PYTHON * 50  # ~800 lines


# ---------------------------------------------------------------------------
# Rule benchmark suites
# ---------------------------------------------------------------------------


class SyntaxCheckRuleSuite:
    """Benchmarks for SyntaxCheckRule."""

    timeout = 60

    def setup(self) -> None:
        self.rule = SyntaxCheckRule()
        self.source = VALID_PYTHON
        self.large = LARGE_PYTHON

    def time_syntax_check_small(self) -> None:
        self.rule.check(self.source, "test.py")

    def time_syntax_check_large(self) -> None:
        self.rule.check(self.large, "test.py")


class MissingImportRuleSuite:
    """Benchmarks for MissingImportRule."""

    timeout = 60

    def setup(self) -> None:
        self.rule = MissingImportRule()
        self.source = VALID_PYTHON

    def time_import_check(self) -> None:
        self.rule.check(self.source, "test.py")


class BrokenReferenceRuleSuite:
    """Benchmarks for BrokenReferenceRule."""

    timeout = 60

    def setup(self) -> None:
        self.rule = BrokenReferenceRule()
        self.source = VALID_PYTHON

    def time_reference_check(self) -> None:
        self.rule.check(self.source, "test.py")


class APIMisuseRuleSuite:
    """Benchmarks for APIMisuseRule."""

    timeout = 60

    def setup(self) -> None:
        self.rule = APIMisuseRule()
        self.source = VALID_PYTHON

    def time_api_misuse_check(self) -> None:
        self.rule.check(self.source, "test.py")


class DuplicateImportRuleSuite:
    """Benchmarks for DuplicateImportRule."""

    timeout = 60

    def setup(self) -> None:
        self.rule = DuplicateImportRule()
        self.source = VALID_PYTHON

    def time_duplicate_import_check(self) -> None:
        self.rule.check(self.source, "test.py")


class MissingSymbolRuleSuite:
    """Benchmarks for MissingSymbolRule."""

    timeout = 60

    def setup(self) -> None:
        self.rule = MissingSymbolRule()
        self.source = VALID_PYTHON

    def time_symbol_check(self) -> None:
        self.rule.check(self.source, "test.py")


# ---------------------------------------------------------------------------
# Registry benchmarks
# ---------------------------------------------------------------------------


class RegistrySuite:
    """Benchmarks for SemanticRuleRegistry."""

    timeout = 60

    def setup(self) -> None:
        self.registry = create_default_registry()

    def time_list_rules(self) -> None:
        self.registry.list_rules()

    def time_lookup_rule(self) -> None:
        self.registry.get("syntax_error")

    def time_all_rules(self) -> None:
        self.registry.all_rules()


# ---------------------------------------------------------------------------
# Cache benchmarks
# ---------------------------------------------------------------------------


class CacheSuite:
    """Benchmarks for SemanticValidationCache."""

    timeout = 60

    def setup(self) -> None:
        self.cache = SemanticValidationCache()
        self.result = SemanticCheckResult(
            passed=True,
            message="ok",
            severity=SemanticValidationSeverity.INFO,
        )
        self.cache.put("rule", "hash1", self.result)

    def time_compute_hash(self) -> None:
        SemanticValidationCache.compute_hash(VALID_PYTHON)

    def time_cache_get_hit(self) -> None:
        self.cache.get("rule", "hash1")

    def time_cache_get_miss(self) -> None:
        self.cache.get("rule", "missing")

    def time_cache_put(self) -> None:
        self.cache.put("rule", "hash2", self.result)


# ---------------------------------------------------------------------------
# Service benchmarks
# ---------------------------------------------------------------------------


class ServiceSuite:
    """Benchmarks for SemanticValidationService orchestration."""

    timeout = 120

    def setup(self) -> None:
        self.service = SemanticValidationService()
        self.source = VALID_PYTHON
        self.large = LARGE_PYTHON

    def time_check_file_small(self) -> None:
        # Clear cache to measure full check cost
        self.service.cache.clear()
        self.service.check_file(self.source, "test.py")

    def time_check_file_large(self) -> None:
        self.service.cache.clear()
        self.service.check_file(self.large, "test.py")

    def time_check_file_cached(self) -> None:
        # First call populates cache, second uses it
        self.service.check_file(self.source, "test.py")
        self.service.check_file(self.source, "test.py")

    def time_pipeline_results(self) -> None:
        self.service.cache.clear()
        self.service.as_pipeline_results(self.source, "test.py")
