"""Step definitions for TDD: DI container resolution in _get_tool_registry_service.

These steps verify that ``_get_tool_registry_service`` in
``cleveragents.cli.commands.validation`` delegates to
``container.tool_registry_service()`` rather than manually constructing
the service with ``create_engine`` / ``sessionmaker`` / repositories.

The first scenario is a TDD scenario: it FAILS before the fix is applied
and PASSES after.
"""

from __future__ import annotations

from typing import Any
from unittest.mock import MagicMock, patch

from behave import given, then, when
from behave.runner import Context

# ---------------------------------------------------------------------------
# Patch targets
# ---------------------------------------------------------------------------

_PATCH_GET_CONTAINER = "cleveragents.application.container.get_container"


# ---------------------------------------------------------------------------
# Background
# ---------------------------------------------------------------------------


@given("a tdd di tool registry test runner")
def step_tdd_di_background(context: Context) -> None:
    context.tdd_di_returned_service: Any = None
    context.tdd_di_mock_container: MagicMock | None = None
    context.tdd_di_mock_service: MagicMock | None = None
    context.tdd_di_container_instance: Any = None


# ---------------------------------------------------------------------------
# Scenario 1: _get_tool_registry_service delegates to container
# ---------------------------------------------------------------------------


@given("the DI container has a tool_registry_service provider")
def step_tdd_di_container_has_provider(context: Context) -> None:
    """Set up a mock container with a tool_registry_service() callable."""
    mock_service = MagicMock(name="MockToolRegistryService")
    mock_container = MagicMock(name="MockContainer")
    mock_container.tool_registry_service.return_value = mock_service
    context.tdd_di_mock_container = mock_container
    context.tdd_di_mock_service = mock_service


@when("_get_tool_registry_service is called with the mocked container")
def step_tdd_di_call_function(context: Context) -> None:
    """Call _get_tool_registry_service with the mocked container injected."""
    from cleveragents.cli.commands.validation import _get_tool_registry_service

    with patch(_PATCH_GET_CONTAINER, return_value=context.tdd_di_mock_container):
        context.tdd_di_returned_service = _get_tool_registry_service()


@then("the returned service should be the one from container.tool_registry_service")
def step_tdd_di_verify_service_identity(context: Context) -> None:
    """The returned service must be exactly what container.tool_registry_service() returns."""
    assert context.tdd_di_returned_service is context.tdd_di_mock_service, (
        f"Expected the service from container.tool_registry_service(), "
        f"but got {type(context.tdd_di_returned_service)}. "
        "This means _get_tool_registry_service is NOT delegating to the container."
    )


@then("no manual engine or sessionmaker construction should have occurred")
def step_tdd_di_verify_no_manual_construction(context: Context) -> None:
    """Verify that container.database_url() was NOT called (manual DI pattern)."""
    mock_container = context.tdd_di_mock_container
    assert not mock_container.database_url.called, (
        "container.database_url() was called, which means _get_tool_registry_service "
        "is still using the manual DI pattern instead of delegating to "
        "container.tool_registry_service()."
    )


# ---------------------------------------------------------------------------
# Scenario 2: ToolRegistryService is registered in the DI container
# ---------------------------------------------------------------------------


@given("the application DI container is initialised")
def step_tdd_di_init_container(context: Context) -> None:
    """Initialise the real application DI container."""
    from cleveragents.application.container import Container, reset_container

    reset_container()
    context.tdd_di_container_instance = Container()


@when("the tool_registry_service provider is accessed on the container")
def step_tdd_di_access_provider(context: Context) -> None:
    """Access the tool_registry_service attribute on the container."""
    container = context.tdd_di_container_instance
    context.tdd_di_provider = getattr(container, "tool_registry_service", None)


@then("the container should expose a tool_registry_service provider")
def step_tdd_di_verify_provider_exists(context: Context) -> None:
    """The container must have a tool_registry_service provider attribute."""
    assert context.tdd_di_provider is not None, (
        "Container does not have a 'tool_registry_service' provider. "
        "ToolRegistryService must be registered in the DI container."
    )
