"""Fake provider stubs for BDD and benchmark tests.

These lightweight stand-ins avoid importing the real ``ProviderInfo`` (which
pulls in heavy dependencies) while satisfying ``ActorRegistry``'s duck-typed
contract for provider discovery.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any
from unittest.mock import MagicMock

from cleveragents.actor.registry import ActorRegistry
from cleveragents.providers.registry import ProviderCapabilities


@dataclass
class FakeProviderInfo:
    """Minimal stand-in for ``ProviderInfo``."""

    name: str
    default_model: str
    provider_type: Any = None
    capabilities: Any = None
    api_key_env_var: str = ""

    def __post_init__(self) -> None:
        if self.provider_type is None:
            self.provider_type = MagicMock(value=self.name)
        if self.capabilities is None:
            self.capabilities = ProviderCapabilities()


@dataclass
class FakeProviderRegistry:
    """Stand-in for ``ProviderRegistry``."""

    providers: list[FakeProviderInfo] = field(default_factory=list)

    def get_configured_providers(self) -> list[FakeProviderInfo]:
        return self.providers


def make_registry(
    providers: list[FakeProviderInfo] | None = None,
) -> tuple[MagicMock, ActorRegistry]:
    """Build a real ``ActorRegistry`` with mocked service/settings.

    The ``ActorService`` is mocked so there is no database dependency, but
    the ``ActorRegistry`` code (including ``_actor_name()``) runs for real.

    After the virtual built-in refactor (issue #10923), built-in actors are
    resolved in-memory from the provider registry and are never upserted.
    The mock service's ``list_actors`` returns an empty list (no custom actors
    in DB); virtual built-ins are produced by the registry itself.
    """
    provider_reg = FakeProviderRegistry(providers=providers or [])

    mock_service = MagicMock()
    mock_service.list_actors.return_value = []
    mock_service.get_default_actor.return_value = None
    mock_service.get_default_actor_name.return_value = None

    mock_settings = MagicMock()
    mock_settings.resolve_provider_defaults.return_value = MagicMock(
        provider=None, model=None
    )

    registry = ActorRegistry(
        actor_service=mock_service,
        provider_registry=provider_reg,
        settings=mock_settings,
    )
    return mock_service, registry
