"""ASV benchmarks for retry policy overhead measurement.

Measures the cost of:
- RetryPolicyConfig construction and validation
- CircuitBreakerConfig construction
- ServiceRetryPolicyRegistry lookup and override application
- ServiceRetryWiring.execute() overhead (happy path, no actual retries)
- CircuitBreaker call() overhead in closed state
- retry_service_operation decorator overhead

Based on issue #313 (feat(async): wire retry policies into services).
"""

from __future__ import annotations

import os
import sys

# Ensure the source is on the path for ASV
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src"))


class TimeRetryPolicyConfigCreation:
    """Benchmark RetryPolicyConfig default construction."""

    timeout = 60.0

    def setup(self) -> None:
        from cleveragents.domain.models.core.retry_policy import RetryPolicyConfig

        self.cls = RetryPolicyConfig

    def time_default_construction(self) -> None:
        self.cls()

    def time_custom_construction(self) -> None:
        self.cls(
            max_attempts=5,
            base_delay=2.0,
            max_delay=30.0,
            jitter=True,
            backoff_strategy="exponential",
        )


class TimeCircuitBreakerConfigCreation:
    """Benchmark CircuitBreakerConfig construction."""

    timeout = 60.0

    def setup(self) -> None:
        from cleveragents.domain.models.core.retry_policy import CircuitBreakerConfig

        self.cls = CircuitBreakerConfig

    def time_default_construction(self) -> None:
        self.cls()


class TimeServiceRetryPolicyRegistryLookup:
    """Benchmark ServiceRetryPolicyRegistry get() performance."""

    timeout = 60.0

    def setup(self) -> None:
        from cleveragents.domain.models.core.retry_policy import (
            ServiceRetryPolicyRegistry,
        )

        self.registry = ServiceRetryPolicyRegistry()

    def time_known_service_lookup(self) -> None:
        self.registry.get("plan_service")

    def time_unknown_service_lookup(self) -> None:
        self.registry.get("unknown_service_xyz")

    def time_apply_overrides(self) -> None:
        self.registry.apply_overrides({"plan_service": {"retry": {"max_attempts": 5}}})


class TimeServiceRetryWiringExecute:
    """Benchmark ServiceRetryWiring.execute() happy-path overhead."""

    timeout = 60.0

    def setup(self) -> None:
        os.environ.setdefault("CLEVERAGENTS_ENV", "test")
        os.environ.setdefault("CLEVERAGENTS_MOCK_PROVIDERS", "true")
        from cleveragents.application.services.service_retry_wiring import (
            ServiceRetryWiring,
        )
        from cleveragents.config.settings import Settings

        settings = Settings(
            database_url="sqlite:///bench_retry.db",
            mock_providers=True,
            env="test",
        )
        self.wiring = ServiceRetryWiring(settings)

    def time_execute_idempotent_success(self) -> None:
        """Measure overhead of a successful idempotent call through wiring."""
        self.wiring.execute(
            service_name="plan_service",
            operation_name="bench_op",
            func=lambda: 42,
            idempotent=True,
        )

    def time_execute_non_idempotent(self) -> None:
        """Measure overhead of a non-idempotent call (no retry wrapper)."""
        self.wiring.execute(
            service_name="plan_service",
            operation_name="bench_write",
            func=lambda: 42,
            idempotent=False,
        )


class TimeCircuitBreakerCallOverhead:
    """Benchmark CircuitBreaker.call() in closed state."""

    timeout = 60.0

    def setup(self) -> None:
        from cleveragents.core.retry_patterns import CircuitBreaker

        self.cb = CircuitBreaker(failure_threshold=5, recovery_timeout=60.0)

    def time_successful_call(self) -> None:
        self.cb.call(lambda: 42)
