"""tests/test_peer_promotion.py — Tests for peer promotion migration v22 (#932)."""

from __future__ import annotations

import pytest
import aiosqlite

from cortex.storage import SQLiteAdapter


@pytest.fixture
async def adapter():
    """Create a fresh in-memory adapter with all migrations applied."""
    a = SQLiteAdapter(db_path=":memory:", busy_timeout_ms=1000, enable_wal=False)
    await a.initialize()
    yield a
    await a.close()


class TestPeerPromotionMigration:
    """Verify v22 migration adds peer promotion columns."""

    async def test_schema_version_is_22(self, adapter: SQLiteAdapter):
        version = await adapter.get_config("schema_version")
        assert version == "30"  # v30: source_session index

    async def test_peer_type_column_exists(self, adapter: SQLiteAdapter):
        peer = await adapter.create_peer(
            owner_id="test",
            display_name="Alice",
            peer_type="agent",
        )
        assert peer.peer_type == "agent"

    async def test_peer_type_default(self, adapter: SQLiteAdapter):
        peer = await adapter.create_peer(
            owner_id="test",
            display_name="Bob",
        )
        assert peer.peer_type == "person"

    async def test_status_column(self, adapter: SQLiteAdapter):
        peer = await adapter.create_peer(
            owner_id="test",
            display_name="Charlie",
            status="inactive",
        )
        assert peer.status == "inactive"

    async def test_status_default(self, adapter: SQLiteAdapter):
        peer = await adapter.create_peer(
            owner_id="test",
            display_name="Dave",
        )
        assert peer.status == "active"

    async def test_connection_count(self, adapter: SQLiteAdapter):
        peer = await adapter.create_peer(
            owner_id="test",
            display_name="Eve",
            connection_count=42,
        )
        assert peer.connection_count == 42

    async def test_connection_count_default(self, adapter: SQLiteAdapter):
        peer = await adapter.create_peer(
            owner_id="test",
            display_name="Frank",
        )
        assert peer.connection_count == 0

    async def test_promoted_at_and_reason(self, adapter: SQLiteAdapter):
        peer = await adapter.create_peer(
            owner_id="test",
            display_name="Grace",
            promoted_at="2026-03-16T00:00:00Z",
            promotion_reason="frequent interaction",
        )
        assert peer.promoted_at == "2026-03-16T00:00:00Z"
        assert peer.promotion_reason == "frequent interaction"

    async def test_description_and_permissions(self, adapter: SQLiteAdapter):
        peer = await adapter.create_peer(
            owner_id="test",
            display_name="Heidi",
            description="Test peer",
            permissions_json='{"read": true}',
        )
        assert peer.description == "Test peer"
        assert peer.permissions_json == '{"read": true}'

    async def test_roundtrip_all_fields(self, adapter: SQLiteAdapter):
        """Create with all new fields, retrieve, verify roundtrip."""
        peer = await adapter.create_peer(
            owner_id="test",
            display_name="Ivan",
            peer_type="system",
            status="archived",
            permissions_json='{"admin": true}',
            description="System peer",
            promoted_at="2026-01-01T00:00:00Z",
            promotion_reason="auto-promoted",
            connection_count=99,
        )
        fetched = await adapter.get_peer(peer.id)
        assert fetched is not None
        assert fetched.peer_type == "system"
        assert fetched.status == "archived"
        assert fetched.permissions_json == '{"admin": true}'
        assert fetched.description == "System peer"
        assert fetched.promoted_at == "2026-01-01T00:00:00Z"
        assert fetched.promotion_reason == "auto-promoted"
        assert fetched.connection_count == 99

    async def test_update_peer_new_fields(self, adapter: SQLiteAdapter):
        peer = await adapter.create_peer(
            owner_id="test",
            display_name="Judy",
        )
        updated = await adapter.update_peer(
            peer.id,
            peer_type="agent",
            status="inactive",
            connection_count=10,
        )
        assert updated.peer_type == "agent"
        assert updated.status == "inactive"
        assert updated.connection_count == 10

    async def test_list_peers_filter_by_type(self, adapter: SQLiteAdapter):
        await adapter.create_peer(owner_id="test", display_name="Person1", peer_type="person")
        await adapter.create_peer(owner_id="test", display_name="Agent1", peer_type="agent")
        await adapter.create_peer(owner_id="test", display_name="Agent2", peer_type="agent")

        agents = await adapter.list_peers(owner_id="test", peer_type="agent")
        assert len(agents) == 2
        assert all(p.peer_type == "agent" for p in agents)

    async def test_list_peers_filter_by_status(self, adapter: SQLiteAdapter):
        await adapter.create_peer(owner_id="test", display_name="Active1", status="active")
        await adapter.create_peer(owner_id="test", display_name="Inactive1", status="inactive")

        active = await adapter.list_peers(owner_id="test", status="active")
        assert len(active) == 1
        assert active[0].display_name == "Active1"
