"""Tests for the Knowledge Store system."""

import sys
import pytest
import tempfile
from pathlib import Path

from vastian.knowledge.documents import DocumentStore
from vastian.knowledge.structured import StructuredStore


@pytest.fixture
def temp_dir():
    # ignore_cleanup_errors added in Python 3.10
    kwargs = {"ignore_cleanup_errors": True} if sys.version_info >= (3, 10) else {}
    with tempfile.TemporaryDirectory(**kwargs) as d:
        yield Path(d)


class TestDocumentStore:
    def test_initialize(self, temp_dir: Path) -> None:
        docs = DocumentStore(docs_dir=temp_dir / "docs")
        docs.initialize()
        assert (temp_dir / "docs").exists()

    def test_write_and_read(self, temp_dir: Path) -> None:
        docs = DocumentStore(docs_dir=temp_dir / "docs")
        docs.initialize()

        docs.write("liam/test-doc.md", "# Test Document\n\nHello world.", "liam")
        content = docs.read("liam/test-doc.md")
        assert "Test Document" in content
        assert "Hello world" in content
        assert "author: liam" in content  # frontmatter added

    def test_read_not_found(self, temp_dir: Path) -> None:
        docs = DocumentStore(docs_dir=temp_dir / "docs")
        docs.initialize()
        result = docs.read("nonexistent.md")
        assert "not found" in result.lower()

    def test_list_docs(self, temp_dir: Path) -> None:
        docs = DocumentStore(docs_dir=temp_dir / "docs")
        docs.initialize()

        docs.write("liam/doc1.md", "# Doc 1", "liam")
        docs.write("liam/doc2.md", "# Doc 2", "liam")
        docs.write("elias/doc3.md", "# Doc 3", "elias")

        all_docs = docs.list_docs()
        assert len(all_docs) == 3

        liam_docs = docs.list_docs("liam")
        assert len(liam_docs) == 2

    def test_delete(self, temp_dir: Path) -> None:
        docs = DocumentStore(docs_dir=temp_dir / "docs")
        docs.initialize()

        docs.write("test/deleteme.md", "# Delete Me", "test")
        assert docs.exists("test/deleteme.md")
        assert docs.delete("test/deleteme.md")
        assert not docs.exists("test/deleteme.md")


class TestStructuredStore:
    @pytest.mark.asyncio
    async def test_initialize(self, temp_dir: Path) -> None:
        store = StructuredStore(db_path=temp_dir / "test.db", state_dir=temp_dir)
        await store.initialize()
        assert store._db is not None
        await store.close()

    @pytest.mark.asyncio
    async def test_insert_and_get_entry(self, temp_dir: Path) -> None:
        store = StructuredStore(db_path=temp_dir / "test.db", state_dir=temp_dir)
        await store.initialize()

        await store.insert_entry(
            entry_id="test-001",
            content="This is a test knowledge entry",
            author="elias",
            tags=["test", "knowledge"],
            metadata={"source": "unit_test"},
        )

        results = await store.get_by_tags(["test"])
        assert len(results) > 0
        assert results[0]["content"] == "This is a test knowledge entry"
        await store.close()

    @pytest.mark.asyncio
    async def test_log_and_get_events(self, temp_dir: Path) -> None:
        store = StructuredStore(db_path=temp_dir / "test.db", state_dir=temp_dir)
        await store.initialize()

        await store.log_event(
            event_type="test_event",
            agent_id="liam",
            content="Something happened",
            metadata={},
        )

        events = await store.get_events(agent_id="liam")
        assert len(events) == 1
        assert events[0]["event_type"] == "test_event"
        await store.close()

    @pytest.mark.asyncio
    async def test_tasks(self, temp_dir: Path) -> None:
        store = StructuredStore(db_path=temp_dir / "test.db", state_dir=temp_dir)
        await store.initialize()

        task_id = await store.create_task(
            title="Write documentation",
            assigned_to="theo",
            created_by="dominic",
            priority="high",
        )
        assert task_id

        tasks = await store.get_tasks(assigned_to="theo")
        assert len(tasks) == 1
        assert tasks[0]["title"] == "Write documentation"

        await store.update_task_status(task_id, "completed")
        tasks = await store.get_tasks(assigned_to="theo", status="completed")
        assert len(tasks) == 1
        await store.close()
