import asyncio

import pytest

from mcpbridge.exceptions import SessionLimitError
from mcpbridge.session import SessionManager


class FakeBridge:
    def __init__(self, config):
        self.config = config
        self.connected = False
        self.closed = False
        self.connect_calls = 0
        self.close_calls = 0

    async def connect(self):
        self.connected = True
        self.connect_calls += 1
        return self

    async def close(self):
        self.closed = True
        self.close_calls += 1


def test_session_manager_create_and_reuse(monkeypatch):
    async def _run():
        import mcpbridge.bridge as bridge_mod

        monkeypatch.setattr(bridge_mod, "MCPBridge", FakeBridge)

        mgr = SessionManager({"llm": {"provider": "openai_compatible", "model": "m"}, "mcp": {"url": "http://x"}}, max_sessions=2)
        b1 = await mgr.get_or_create("s1")
        b2 = await mgr.get_or_create("s1")
        assert b1 is b2
        assert b1.connect_calls == 1

    asyncio.run(_run())


def test_session_manager_max_sessions(monkeypatch):
    async def _run():
        import mcpbridge.bridge as bridge_mod

        monkeypatch.setattr(bridge_mod, "MCPBridge", FakeBridge)

        mgr = SessionManager({"llm": {"provider": "openai_compatible", "model": "m"}, "mcp": {"url": "http://x"}}, max_sessions=1)
        await mgr.get_or_create("s1")
        with pytest.raises(SessionLimitError):
            await mgr.get_or_create("s2")

    asyncio.run(_run())


def test_session_manager_destroy(monkeypatch):
    async def _run():
        import mcpbridge.bridge as bridge_mod

        monkeypatch.setattr(bridge_mod, "MCPBridge", FakeBridge)

        mgr = SessionManager({"llm": {"provider": "openai_compatible", "model": "m"}, "mcp": {"url": "http://x"}}, max_sessions=2)
        b1 = await mgr.get_or_create("s1")
        await mgr.destroy("s1")
        assert b1.closed is True

    asyncio.run(_run())


def test_session_manager_cleanup_task(monkeypatch):
    async def _run():
        import mcpbridge.bridge as bridge_mod

        monkeypatch.setattr(bridge_mod, "MCPBridge", FakeBridge)

        mgr = SessionManager({"llm": {"provider": "openai_compatible", "model": "m"}, "mcp": {"url": "http://x"}}, max_sessions=2)
        await mgr.get_or_create("s1")
        await mgr.start_cleanup_task(ttl_seconds=0, interval_seconds=0.05)
        # Give cleanup time to run.
        await asyncio.sleep(0.2)
        assert mgr.active_count() == 0

    asyncio.run(_run())

