"""Test ConnectionManager CRUD, defaults, and session persistence."""

import json
import pytest
from mcpbundles.connections import ConnectionManager, ConnectionInfo, SESSIONS_DIR


@pytest.fixture
def conn_mgr(tmp_path, monkeypatch):
    sessions = tmp_path / "sessions"
    monkeypatch.setattr("mcpbundles.connections.SESSIONS_DIR", sessions)
    return ConnectionManager()


class TestConnectionManager:
    def test_list_empty(self, conn_mgr):
        assert conn_mgr.list_connections() == []

    def test_create_and_get(self, conn_mgr):
        conn = conn_mgr.create("hub", "https://api.mcpbundles.com", "/hub/")
        assert conn.name == "hub"
        assert conn.url == "https://api.mcpbundles.com"
        assert conn.endpoint == "/hub/"
        assert conn.is_default is False

        retrieved = conn_mgr.get("hub")
        assert retrieved is not None
        assert retrieved.name == "hub"

    def test_create_with_default(self, conn_mgr):
        conn_mgr.create("first", "https://a.com", "/hub/")
        conn_mgr.create("second", "https://b.com", "/hub/", is_default=True)

        default = conn_mgr.get_default()
        assert default is not None
        assert default.name == "second"

    def test_create_default_clears_previous(self, conn_mgr):
        conn_mgr.create("a", "https://a.com", "/hub/", is_default=True)
        conn_mgr.create("b", "https://b.com", "/hub/", is_default=True)

        a = conn_mgr.get("a")
        assert a is not None
        assert a.is_default is False

    def test_get_nonexistent(self, conn_mgr):
        assert conn_mgr.get("nope") is None

    def test_remove(self, conn_mgr):
        conn_mgr.create("test", "https://x.com", "/hub/")
        assert conn_mgr.remove("test") is True
        assert conn_mgr.get("test") is None

    def test_remove_nonexistent(self, conn_mgr):
        assert conn_mgr.remove("nope") is False

    def test_remove_all(self, conn_mgr):
        conn_mgr.create("a", "https://a.com", "/hub/")
        conn_mgr.create("b", "https://b.com", "/hub/")
        removed = conn_mgr.remove_all()
        assert removed == 2
        assert conn_mgr.list_connections() == []

    def test_save_session_id(self, conn_mgr):
        conn_mgr.create("hub", "https://api.mcpbundles.com", "/hub/")
        conn_mgr.save_session_id("hub", "session-abc")
        conn = conn_mgr.get("hub")
        assert conn is not None
        assert conn.session_id == "session-abc"

    def test_invalidate_session(self, conn_mgr):
        conn_mgr.create("hub", "https://api.mcpbundles.com", "/hub/")
        conn_mgr.save_session_id("hub", "session-abc")
        conn_mgr.invalidate_session("hub")
        conn = conn_mgr.get("hub")
        assert conn is not None
        assert conn.session_id is None

    def test_set_default(self, conn_mgr):
        conn_mgr.create("a", "https://a.com", "/hub/")
        conn_mgr.create("b", "https://b.com", "/hub/")
        assert conn_mgr.set_default("b") is True
        assert conn_mgr.get_default().name == "b"

    def test_set_default_nonexistent(self, conn_mgr):
        assert conn_mgr.set_default("nope") is False

    def test_get_default_fallback_to_first(self, conn_mgr):
        conn_mgr.create("alpha", "https://a.com", "/hub/")
        conn_mgr.create("beta", "https://b.com", "/hub/")
        default = conn_mgr.get_default()
        assert default is not None
        assert default.name == "alpha"

    def test_get_default_empty(self, conn_mgr):
        assert conn_mgr.get_default() is None

    def test_list_connections_sorted(self, conn_mgr):
        conn_mgr.create("zebra", "https://z.com", "/hub/")
        conn_mgr.create("alpha", "https://a.com", "/hub/")
        names = [c.name for c in conn_mgr.list_connections()]
        assert names == ["alpha", "zebra"]

    def test_corrupt_session_file_skipped(self, conn_mgr, tmp_path):
        sessions = tmp_path / "sessions"
        (sessions / "bad.json").write_text("not json")
        conns = conn_mgr.list_connections()
        assert len(conns) == 0

    def test_file_permissions(self, conn_mgr, tmp_path):
        conn_mgr.create("secure", "https://s.com", "/hub/")
        sessions = tmp_path / "sessions"
        f = sessions / "secure.json"
        assert f.exists()
        assert oct(f.stat().st_mode & 0o777) == "0o600"


class TestConnectionInfoDisplayTarget:
    def test_display_target(self):
        conn = ConnectionInfo(
            name="hub",
            url="https://api.mcpbundles.com",
            endpoint="/hub/",
            workspace_id=None,
            session_id=None,
            is_default=False,
            created_at="2026-01-01T00:00:00",
        )
        assert conn.display_target == "api.mcpbundles.com/hub/"

    def test_display_target_bundle(self):
        conn = ConnectionInfo(
            name="hubspot",
            url="https://api.mcpbundles.com",
            endpoint="/mcp/bundle/hubspot/",
            workspace_id=None,
            session_id=None,
            is_default=False,
            created_at="2026-01-01T00:00:00",
        )
        assert conn.display_target == "api.mcpbundles.com/mcp/bundle/hubspot/"
