"""app/ports.py 工厂 Protocol isinstance 检查测试。"""

from __future__ import annotations

from typing import TYPE_CHECKING

from app.ports import (
    PromptBuilderFactory,
    PromptBuilderFn,
    ToolDispatchFactory,
    ToolDispatchFn,
)

if TYPE_CHECKING:
    from pathlib import Path


# ---------------------------------------------------------------------------
# ToolDispatchFn
# ---------------------------------------------------------------------------


class TestToolDispatchFnProtocol:
    """ToolDispatchFn runtime_checkable isinstance 检查。"""

    def test_conforming_async_callable(self) -> None:
        """符合签名的 async callable 通过 isinstance 检查。"""

        async def dispatch(tool_name: str, args: dict, *, context: dict) -> str:
            return "ok"

        assert isinstance(dispatch, ToolDispatchFn)

    def test_non_callable_fails(self) -> None:
        """非 callable 不通过 isinstance 检查。"""
        assert not isinstance("not_a_callable", ToolDispatchFn)


# ---------------------------------------------------------------------------
# ToolDispatchFactory
# ---------------------------------------------------------------------------


class TestToolDispatchFactoryProtocol:
    """ToolDispatchFactory runtime_checkable isinstance 检查。"""

    def test_conforming_factory_class(self) -> None:
        """符合签名的工厂类通过 isinstance 检查。"""

        class _Factory:
            def __call__(self, *, skills_dir: Path | None = None) -> ToolDispatchFn:
                async def _d(tool_name: str, args: dict, *, context: dict) -> str:
                    return "ok"

                return _d  # type: ignore[return-value]

        assert isinstance(_Factory(), ToolDispatchFactory)

    def test_conforming_function(self) -> None:
        """符合签名的普通函数通过 isinstance 检查。"""

        def factory(*, skills_dir: Path | None = None) -> ToolDispatchFn:
            async def _d(tool_name: str, args: dict, *, context: dict) -> str:
                return "ok"

            return _d  # type: ignore[return-value]

        assert isinstance(factory, ToolDispatchFactory)


# ---------------------------------------------------------------------------
# PromptBuilderFn
# ---------------------------------------------------------------------------


class TestPromptBuilderFnProtocol:
    """PromptBuilderFn runtime_checkable isinstance 检查。"""

    def test_conforming_callable(self) -> None:
        """符合签名的 callable 通过 isinstance 检查。"""

        def builder(qa: object) -> tuple[str, str]:
            return ("system", "user")

        assert isinstance(builder, PromptBuilderFn)

    def test_non_callable_fails(self) -> None:
        """非 callable 不通过 isinstance 检查。"""
        assert not isinstance(42, PromptBuilderFn)


# ---------------------------------------------------------------------------
# PromptBuilderFactory
# ---------------------------------------------------------------------------


class TestPromptBuilderFactoryProtocol:
    """PromptBuilderFactory runtime_checkable isinstance 检查。"""

    def test_conforming_factory_class(self) -> None:
        """符合签名的工厂类通过 isinstance 检查。"""

        class _Factory:
            def __call__(
                self,
                *,
                skills_dir: Path | None = None,
                prompts_dir: Path | None = None,
            ) -> PromptBuilderFn:
                def _b(qa: object) -> tuple[str, str]:
                    return ("s", "u")

                return _b  # type: ignore[return-value]

        assert isinstance(_Factory(), PromptBuilderFactory)

    def test_conforming_function(self) -> None:
        """符合签名的普通函数通过 isinstance 检查。"""

        def factory(
            *, skills_dir: Path | None = None, prompts_dir: Path | None = None
        ) -> PromptBuilderFn:
            def _b(qa: object) -> tuple[str, str]:
                return ("s", "u")

            return _b  # type: ignore[return-value]

        assert isinstance(factory, PromptBuilderFactory)
