import pytest
from uuid import uuid4
from unittest.mock import MagicMock


@pytest.fixture
def frisk_langchain_instance(monkeypatch: pytest.MonkeyPatch):
    """Create a FriskLangchain without running CoreFrisk.__init__ (avoids Rust/threads)."""

    from frisk_sdk.adapters.langchain.frisk_langchain import FriskLangchain

    def _noop_init(self, *args, **kwargs):
        # Minimal attributes needed by the adapter helpers.
        self.logger_name = "frisk.test"
        # FriskToolMiddleware expects a tracer on the Frisk instance.
        self._tracer = object()

    monkeypatch.setattr(FriskLangchain, "__init__", _noop_init)
    return FriskLangchain(api_key="k")


@pytest.mark.unit
def test_callback_handler_returns_frisk_callback_handler(
    frisk_langchain_instance, monkeypatch: pytest.MonkeyPatch
):
    from frisk_sdk.adapters.langchain.frisk_callback_handler import FriskCallbackHandler

    # FriskCallbackHandler resolves the session from SessionRegistry in __init__.
    # Patch that lookup to avoid needing a real FriskSession.
    import frisk_sdk.adapters.langchain.frisk_callback_handler as cb_module

    registry = MagicMock(name="SessionRegistry")
    registry.get.return_value = MagicMock(name="FriskSession")
    monkeypatch.setattr(cb_module, "SessionRegistry", lambda: registry)

    session_id = uuid4()

    h = frisk_langchain_instance.callback_handler(session_id)
    assert isinstance(h, FriskCallbackHandler)

    # Ensure the registry lookup was performed and the handler is bound to the frisk instance.
    registry.get.assert_called_once_with(session_id)
    assert h._frisk is frisk_langchain_instance


@pytest.mark.unit
def test_tool_middleware_returns_frisk_tool_middleware(frisk_langchain_instance):
    from frisk_sdk.adapters.langchain.frisk_tool_middleware import FriskToolMiddleware

    mw = frisk_langchain_instance.tool_middleware()
    assert isinstance(mw, FriskToolMiddleware)
    assert mw._frisk_handle is frisk_langchain_instance
