"""
Tests for SummaryStore — summaries, context items, and large files.

Issues: #801, #1170
"""

from __future__ import annotations

import pytest
import pytest_asyncio

from cortex.hippo.config import HippoConfig
from cortex.hippo.db.connection import HippoDatabase
from cortex.hippo.store.summary_store import SummaryStore
from cortex.hippo.store.conversation_store import ConversationStore


@pytest_asyncio.fixture
async def stores():
    """Provide SummaryStore + ConversationStore backed by in-memory DB."""
    config = HippoConfig(db_path=":memory:")
    db = HippoDatabase(config)
    await db.initialize()
    ss = SummaryStore(db.conn)
    cs = ConversationStore(db.conn)
    yield ss, cs, db
    await db.close()


# ── Large Files ────────────────────────────────────────────────────


@pytest.mark.asyncio
async def test_insert_and_get_large_file(stores):
    ss, cs, db = stores
    conv = await cs.get_or_create_conversation("owner1", "sess1")

    row_id = await ss.insert_large_file(
        file_id="file_abc123def456",
        conversation_id=conv.conversation_id,
        owner_id="owner1",
        file_name="big_data.json",
        mime_type="application/json",
        byte_size=500_000,
        content='{"large": true}',
        exploration_summary="A large JSON file with config data.",
    )
    assert row_id > 0

    fetched = await ss.get_large_file("file_abc123def456")
    assert fetched is not None
    assert fetched["file_id"] == "file_abc123def456"
    assert fetched["conversation_id"] == conv.conversation_id
    assert fetched["owner_id"] == "owner1"
    assert fetched["file_name"] == "big_data.json"
    assert fetched["mime_type"] == "application/json"
    assert fetched["byte_size"] == 500_000
    assert fetched["content"] == '{"large": true}'
    assert fetched["exploration_summary"] == "A large JSON file with config data."


@pytest.mark.asyncio
async def test_get_large_file_not_found(stores):
    ss, cs, db = stores
    result = await ss.get_large_file("file_nonexistent")
    assert result is None


@pytest.mark.asyncio
async def test_get_large_files_by_conversation(stores):
    ss, cs, db = stores
    conv1 = await cs.get_or_create_conversation("owner1", "sess1")
    conv2 = await cs.get_or_create_conversation("owner1", "sess2")

    await ss.insert_large_file(
        file_id="file_001",
        conversation_id=conv1.conversation_id,
        owner_id="owner1",
        file_name="a.txt",
        byte_size=100,
    )
    await ss.insert_large_file(
        file_id="file_002",
        conversation_id=conv1.conversation_id,
        owner_id="owner1",
        file_name="b.txt",
        byte_size=200,
    )
    await ss.insert_large_file(
        file_id="file_003",
        conversation_id=conv2.conversation_id,
        owner_id="owner1",
        file_name="c.txt",
        byte_size=300,
    )

    files_conv1 = await ss.get_large_files_by_conversation(conv1.conversation_id)
    assert len(files_conv1) == 2
    assert files_conv1[0]["file_id"] == "file_001"
    assert files_conv1[1]["file_id"] == "file_002"

    files_conv2 = await ss.get_large_files_by_conversation(conv2.conversation_id)
    assert len(files_conv2) == 1
    assert files_conv2[0]["file_id"] == "file_003"


@pytest.mark.asyncio
async def test_large_file_unique_file_id(stores):
    ss, cs, db = stores
    conv = await cs.get_or_create_conversation("owner1", "sess1")

    await ss.insert_large_file(
        file_id="file_dup",
        conversation_id=conv.conversation_id,
        owner_id="owner1",
        byte_size=100,
    )

    with pytest.raises(Exception):
        await ss.insert_large_file(
            file_id="file_dup",
            conversation_id=conv.conversation_id,
            owner_id="owner1",
            byte_size=200,
        )


@pytest.mark.asyncio
async def test_get_large_files_empty_conversation(stores):
    ss, cs, db = stores
    conv = await cs.get_or_create_conversation("owner1", "sess1")
    files = await ss.get_large_files_by_conversation(conv.conversation_id)
    assert files == []


# ── Summaries (existing functionality sanity check) ────────────────


@pytest.mark.asyncio
async def test_create_and_get_summary(stores):
    ss, cs, db = stores
    conv = await cs.get_or_create_conversation("owner1", "sess1")

    summary = await ss.create_summary(
        conversation_id=conv.conversation_id,
        owner_id="owner1",
        kind="leaf",
        depth=0,
        content="A test summary.",
        token_count=10,
    )
    assert summary.summary_id.startswith("sum_")
    assert summary.kind == "leaf"

    fetched = await ss.get_summary("owner1", summary.summary_id)
    assert fetched is not None
    assert fetched.content == "A test summary."
