"""Steps for TDD Issue #10507 — get_current_revision() SQLite threading fix."""

from __future__ import annotations

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

from behave import then, when


def _run_get_current_revision_and_capture_kwargs(
    context: Any,
) -> None:
    """Shared helper: call get_current_revision() and capture create_engine kwargs.

    Mocks ``create_engine`` and ``MigrationContext.configure`` so the call
    completes without a real database.  The keyword arguments passed to
    ``create_engine`` are stored on ``context.engine_creation_kwargs`` for
    subsequent assertion steps.
    """
    fake_engine = MagicMock()
    fake_connection = MagicMock()
    fake_connection.__enter__ = MagicMock(return_value=fake_connection)
    fake_connection.__exit__ = MagicMock(return_value=False)
    fake_engine.connect.return_value = fake_connection

    migration_ctx = MagicMock()
    migration_ctx.get_current_revision.return_value = None

    captured_kwargs: list[dict[str, Any]] = []

    def fake_create_engine(url: str, **kwargs: Any) -> MagicMock:
        captured_kwargs.append(kwargs)
        return fake_engine

    with (
        patch(
            "cleveragents.infrastructure.database.migration_runner.create_engine",
            side_effect=fake_create_engine,
        ),
        patch(
            "cleveragents.infrastructure.database.migration_runner.MigrationContext.configure",
            return_value=migration_ctx,
        ),
    ):
        context.revision_result = context.runner.get_current_revision()

    context.engine_creation_kwargs = captured_kwargs


@when("I request the current revision and capture the engine creation args")
def step_when_capture_engine_args(context: Any) -> None:
    """Call get_current_revision and capture the create_engine call arguments."""
    _run_get_current_revision_and_capture_kwargs(context)


@then("the SQLite engine should be created with check_same_thread set to False")
def step_then_sqlite_engine_has_check_same_thread(context: Any) -> None:
    """Verify the SQLite engine was created with check_same_thread=False."""
    assert len(context.engine_creation_kwargs) == 1, (
        f"Expected exactly 1 create_engine call, got {len(context.engine_creation_kwargs)}"
    )
    kwargs = context.engine_creation_kwargs[0]
    assert "connect_args" in kwargs, (
        "Expected connect_args in create_engine kwargs for SQLite, "
        f"but got kwargs: {kwargs}"
    )
    assert kwargs["connect_args"].get("check_same_thread") is False, (
        "Expected check_same_thread=False in connect_args, "
        f"but got: {kwargs['connect_args']}"
    )


@then("the non-SQLite engine should be created without check_same_thread")
def step_then_non_sqlite_engine_no_check_same_thread(context: Any) -> None:
    """Verify non-SQLite engines are not given check_same_thread."""
    assert len(context.engine_creation_kwargs) == 1, (
        f"Expected exactly 1 create_engine call, got {len(context.engine_creation_kwargs)}"
    )
    kwargs = context.engine_creation_kwargs[0]
    connect_args = kwargs.get("connect_args", {})
    assert "check_same_thread" not in connect_args, (
        "Expected check_same_thread to be absent for non-SQLite engine, "
        f"but got connect_args: {connect_args}"
    )
