"""ASV benchmarks for action table ORM round-trip performance.

Measures the performance of:
- LifecycleActionModel.from_domain() construction from Action domain objects
- LifecycleActionModel.to_domain() conversion back to domain objects
- Bulk action model construction for migration-volume workloads
"""

from __future__ import annotations

import sys
from pathlib import Path

try:
    from cleveragents.domain.models.core.action import (
        Action,
        ActionArgument,
        ArgumentRequirement,
        ArgumentType,
    )
    from cleveragents.domain.models.core.plan import NamespacedName
    from cleveragents.infrastructure.database.models import LifecycleActionModel
except ModuleNotFoundError:
    sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
    from cleveragents.domain.models.core.action import (
        Action,
        ActionArgument,
        ArgumentRequirement,
        ArgumentType,
    )
    from cleveragents.domain.models.core.plan import NamespacedName
    from cleveragents.infrastructure.database.models import LifecycleActionModel


def _make_action(suffix: str = "bench") -> Action:
    """Create a fully-populated Action for benchmarking."""
    return Action(
        namespaced_name=NamespacedName(
            server=None, namespace="local", name=f"action-{suffix}"
        ),
        description="Benchmark action for ORM round-trip testing",
        long_description="A detailed description for measuring serialization cost.",
        definition_of_done="All benchmarks complete in under 1ms",
        strategy_actor="openai/gpt-4",
        execution_actor="openai/gpt-4",
        review_actor="openai/gpt-4",
        apply_actor="openai/gpt-4",
        estimation_actor="openai/gpt-4",
        invariant_actor="openai/gpt-4",
        automation_profile="org/bench-profile",
        reusable=True,
        read_only=False,
        inputs_schema={"type": "object", "properties": {"name": {"type": "string"}}},
        invariants=["No secrets in code", "All tests must pass"],
        tags=["benchmark", "testing", "ci"],
        created_by="bench-user",
        arguments=[
            ActionArgument(
                name="target",
                arg_type=ArgumentType.INTEGER,
                requirement=ArgumentRequirement.REQUIRED,
                description="Target value",
                min_value=0,
                max_value=100,
            ),
            ActionArgument(
                name="framework",
                arg_type=ArgumentType.STRING,
                requirement=ArgumentRequirement.OPTIONAL,
                description="Framework name",
                default_value="pytest",
            ),
        ],
    )


class ActionModelFromDomainSuite:
    """Benchmark LifecycleActionModel.from_domain() construction."""

    def setup(self) -> None:
        self.action = _make_action()
        self.minimal_action = Action(
            namespaced_name=NamespacedName(
                server=None, namespace="local", name="minimal"
            ),
            description="Minimal action",
            definition_of_done="Done",
            strategy_actor="openai/gpt-4",
            execution_actor="openai/gpt-4",
        )

    def time_from_domain_full(self) -> None:
        """Convert a fully-populated Action to ORM model."""
        LifecycleActionModel.from_domain(self.action)

    def time_from_domain_minimal(self) -> None:
        """Convert a minimal Action to ORM model."""
        LifecycleActionModel.from_domain(self.minimal_action)


class ActionModelToDomainSuite:
    """Benchmark LifecycleActionModel.to_domain() conversion."""

    def setup(self) -> None:
        self.full_model = LifecycleActionModel.from_domain(_make_action())
        self.minimal_model = LifecycleActionModel.from_domain(
            Action(
                namespaced_name=NamespacedName(
                    server=None, namespace="local", name="minimal"
                ),
                description="Minimal action",
                definition_of_done="Done",
                strategy_actor="openai/gpt-4",
                execution_actor="openai/gpt-4",
            )
        )

    def time_to_domain_full(self) -> None:
        """Convert a fully-populated ORM model back to domain."""
        self.full_model.to_domain()

    def time_to_domain_minimal(self) -> None:
        """Convert a minimal ORM model back to domain."""
        self.minimal_model.to_domain()


class ActionModelBulkSuite:
    """Benchmark bulk action model construction for migration volumes."""

    def setup(self) -> None:
        self.actions = [_make_action(str(i)) for i in range(100)]

    def time_bulk_from_domain_100(self) -> None:
        """Convert 100 Action domain objects to ORM models."""
        for action in self.actions:
            LifecycleActionModel.from_domain(action)

    def time_bulk_round_trip_100(self) -> None:
        """Full round-trip: domain -> ORM -> domain for 100 actions."""
        for action in self.actions:
            model = LifecycleActionModel.from_domain(action)
            model.to_domain()
