import pytest

from navi.core.session import InMemorySessionStore
from navi.tools._internal.base import ToolContext
from navi.tools.spawn_agent import SpawnAgentTool
from tests.conftest_factory import (
    FakeLLMBackend,
    make_profile_registry,
    make_registry_with_tools,
)
from navi.core.registry import BackendRegistry


@pytest.fixture
def spawn_tool():
    profiles = make_profile_registry()
    tools = make_registry_with_tools()
    backends = BackendRegistry()
    backends.register("ollama", FakeLLMBackend(responses=["done"]))
    store = InMemorySessionStore()
    tool = SpawnAgentTool(profiles, tools, backends, store)
    return tool, profiles, store


@pytest.mark.anyio
async def test_spawn_agent_uses_explicit_profile(monkeypatch, spawn_tool):
    tool, _, _ = spawn_tool
    captured = {}

    async def fake_run_ephemeral(self, **kwargs):
        captured.update(kwargs)
        return "developer result", True

    monkeypatch.setattr("navi.core.agent.Agent.run_ephemeral", fake_run_ephemeral)

    result = await tool.execute({
        "task": "inspect code",
        "profile_id": "developer",
    }, ctx=ToolContext())

    assert result.success is True
    assert captured["profile_id"] == "developer"
    assert "developer result" in result.output


@pytest.mark.anyio
async def test_spawn_agent_defaults_to_parent_profile(monkeypatch, spawn_tool):
    tool, _, store = spawn_tool
    session = await store.create("secretary")
    captured = {}

    async def fake_run_ephemeral(self, **kwargs):
        captured.update(kwargs)
        return "secretary result", True

    monkeypatch.setattr("navi.core.agent.Agent.run_ephemeral", fake_run_ephemeral)

    result = await tool.execute({"task": "research this"}, ctx=ToolContext(session_id=session.id))

    assert result.success is True
    assert captured["profile_id"] == "secretary"


@pytest.mark.anyio
async def test_spawn_agent_rejects_unknown_profile(spawn_tool):
    tool, _, _ = spawn_tool

    result = await tool.execute({
        "task": "do work",
        "profile_id": "missing_profile",
    }, ctx=ToolContext())

    assert result.success is False
    assert result.error == "unknown_profile:missing_profile"
    assert "Available profiles" in result.output
