"""Test session_tools (add_note, get_session)."""
from unittest.mock import MagicMock

import pytest

from mcp.server.fastmcp import FastMCP
from unrealhub.state import StateStore
from unrealhub.tools.session_tools import register_session_tools


def _setup(tmp_home):
    mcp = FastMCP("test")
    store = StateStore()
    store.upsert(port=8422, project_path="G:/Proj/A.uproject", pid=1234)
    register_session_tools(mcp, lambda: store)
    tools = {t.name: t.fn for t in mcp._tool_manager.list_tools()}
    return store, tools


class TestAddNote:
    @pytest.mark.asyncio
    async def test_add_note(self, tmp_home):
        store, tools = _setup(tmp_home)
        result = await tools["add_note"]("Test observation")
        assert "added" in result.lower()
        notes = store.get_notes("A:8422")
        assert len(notes) == 1
        assert notes[0].content == "Test observation"

    @pytest.mark.asyncio
    async def test_add_note_truncation(self, tmp_home):
        store, tools = _setup(tmp_home)
        long = "x" * 200
        result = await tools["add_note"](long)
        assert "..." in result

    @pytest.mark.asyncio
    async def test_add_note_no_instance(self, tmp_home):
        mcp = FastMCP("test")
        store = StateStore()
        register_session_tools(mcp, lambda: store)
        tools = {t.name: t.fn for t in mcp._tool_manager.list_tools()}

        result = await tools["add_note"]("orphan note")
        assert "no instance" in result.lower()


class TestGetSession:
    @pytest.mark.asyncio
    async def test_notes_scope_empty(self, tmp_home):
        store, tools = _setup(tmp_home)
        result = await tools["get_session"]("notes")
        assert "no notes" in result.lower()

    @pytest.mark.asyncio
    async def test_notes_scope_with_content(self, tmp_home):
        store, tools = _setup(tmp_home)
        store.add_note("A:8422", "Note 1")
        store.add_note("A:8422", "Note 2")
        result = await tools["get_session"]("notes")
        assert "Note 1" in result
        assert "Note 2" in result

    @pytest.mark.asyncio
    async def test_history_scope_empty(self, tmp_home):
        store, tools = _setup(tmp_home)
        result = await tools["get_session"]("history")
        assert "no call history" in result.lower()

    @pytest.mark.asyncio
    async def test_history_scope_with_data(self, tmp_home):
        store, tools = _setup(tmp_home)
        store.record_tool_call("A:8422", "run_python", True, 42.0)
        store.record_tool_call("A:8422", "get_dispatch", False, 100.0)
        result = await tools["get_session"]("history")
        assert "run_python" in result
        assert "OK" in result
        assert "FAIL" in result

    @pytest.mark.asyncio
    async def test_full_scope_text(self, tmp_home):
        store, tools = _setup(tmp_home)
        store.add_note("A:8422", "A note")
        store.record_tool_call("A:8422", "test", True, 1.0)
        result = await tools["get_session"]("full")
        assert "Session" in result
        assert "A note" in result
        assert "test" in result

    @pytest.mark.asyncio
    async def test_full_scope_json(self, tmp_home):
        store, tools = _setup(tmp_home)
        import json
        result = await tools["get_session"]("full", "", "json")
        data = json.loads(result)
        assert data["key"] == "A:8422"
        assert "url" in data

    @pytest.mark.asyncio
    async def test_default_scope_is_full(self, tmp_home):
        store, tools = _setup(tmp_home)
        store.add_note("A:8422", "My note")
        result = await tools["get_session"]()
        assert "Session" in result
        assert "My note" in result

    @pytest.mark.asyncio
    async def test_no_instance(self, tmp_home):
        mcp = FastMCP("test")
        store = StateStore()
        register_session_tools(mcp, lambda: store)
        tools = {t.name: t.fn for t in mcp._tool_manager.list_tools()}

        result = await tools["get_session"]()
        assert "no instance" in result.lower()

    @pytest.mark.asyncio
    async def test_only_two_tools_registered(self, tmp_home):
        store, tools = _setup(tmp_home)
        assert set(tools.keys()) == {"add_note", "get_session"}
