# tests/test_toolset.py
import pytest

# Only run if pydantic-ai is installed
pydantic_ai = pytest.importorskip("pydantic_ai")

from unittest.mock import AsyncMock, MagicMock  # noqa: E402

from agentsh_secure_sandbox.toolset.pydantic_ai import SecureSandboxToolset  # noqa: E402


async def test_toolset_requires_context():
    adapter = MagicMock()
    toolset = SecureSandboxToolset(adapter)
    with pytest.raises(RuntimeError, match="not provisioned"):
        _ = toolset.sandbox


async def test_toolset_has_three_tools():
    """Toolset should define run_command, write_file, read_file."""
    defs = SecureSandboxToolset._TOOL_DEFS
    assert "run_command" in defs
    assert "write_file" in defs
    assert "read_file" in defs


async def test_toolset_id():
    adapter = MagicMock()
    toolset = SecureSandboxToolset(adapter, toolset_id="custom-id")
    assert toolset.id == "custom-id"


async def test_toolset_get_tools_returns_three(monkeypatch):
    mock_secure = AsyncMock(return_value=AsyncMock())
    monkeypatch.setattr(
        "agentsh_secure_sandbox.toolset._base.secure_sandbox", mock_secure,
    )
    toolset = SecureSandboxToolset(MagicMock())
    async with toolset:
        ctx = MagicMock()
        tools = await toolset.get_tools(ctx)
    assert len(tools) == 3
    assert set(tools.keys()) == {"run_command", "write_file", "read_file"}


async def test_toolset_call_tool_run_command(monkeypatch):
    mock_sandbox = AsyncMock()
    mock_sandbox.exec = AsyncMock(return_value=MagicMock(
        exit_code=0, stdout="hello\n", stderr="",
    ))
    mock_secure = AsyncMock(return_value=mock_sandbox)
    monkeypatch.setattr(
        "agentsh_secure_sandbox.toolset._base.secure_sandbox", mock_secure,
    )
    toolset = SecureSandboxToolset(MagicMock())
    async with toolset:
        result = await toolset.call_tool(
            "run_command",
            {"command": "echo hello"},
            ctx=MagicMock(),
            tool=MagicMock(),
        )
    assert result == "hello\n"


async def test_toolset_call_tool_write_file(monkeypatch):
    mock_sandbox = AsyncMock()
    mock_sandbox.write_file = AsyncMock(return_value=MagicMock(
        success=True, path="/workspace/test.txt",
    ))
    mock_secure = AsyncMock(return_value=mock_sandbox)
    monkeypatch.setattr(
        "agentsh_secure_sandbox.toolset._base.secure_sandbox", mock_secure,
    )
    toolset = SecureSandboxToolset(MagicMock())
    async with toolset:
        result = await toolset.call_tool(
            "write_file",
            {"path": "/workspace/test.txt", "content": "hi"},
            ctx=MagicMock(),
            tool=MagicMock(),
        )
    assert "Written to" in result


async def test_toolset_call_tool_read_file(monkeypatch):
    mock_sandbox = AsyncMock()
    mock_sandbox.read_file = AsyncMock(return_value=MagicMock(
        success=True, content="file content",
    ))
    mock_secure = AsyncMock(return_value=mock_sandbox)
    monkeypatch.setattr(
        "agentsh_secure_sandbox.toolset._base.secure_sandbox", mock_secure,
    )
    toolset = SecureSandboxToolset(MagicMock())
    async with toolset:
        result = await toolset.call_tool(
            "read_file",
            {"path": "/workspace/test.txt"},
            ctx=MagicMock(),
            tool=MagicMock(),
        )
    assert result == "file content"
