"""Integration tests for the knowledge plane end-to-end pipeline.

Tests the complete flow: file registration → chunking → embedding → vector store → navigation → semantic search.
"""

from __future__ import annotations

import hashlib
from pathlib import Path

import pytest

from cyberbrain26.data_plane.sqlite_store import SQLiteDatabase
from cyberbrain26.knowledge_plane import (
    MemoryService,
)
from cyberbrain26.knowledge_plane.embedding_config import EmbeddingConfig
from cyberbrain26.security_plane.audit import AuditLog


@pytest.fixture
def tmp_sqlite_db(tmp_path: Path) -> Path:
    """Vytvoří dočasnou SQLite databázi pro test."""
    return tmp_path / "knowledge.sqlite3"


@pytest.fixture
def tmp_lancedb_dir(tmp_path: Path) -> Path:
    """Vytvoří dočasný adresář pro LanceDB."""
    return tmp_path / "lancedb_data"


@pytest.fixture
def memory_service(tmp_sqlite_db: Path, tmp_lancedb_dir: Path) -> MemoryService:
    """Vytvoří MemoryService pro test."""
    config = EmbeddingConfig(vector_dim=1024, lancedb_directory=tmp_lancedb_dir)
    database = SQLiteDatabase(tmp_sqlite_db)
    audit_log = AuditLog(database=database)
    return MemoryService(
        database=database,
        config=config,
        audit_log=audit_log,
    )


@pytest.fixture
def sample_text() -> str:
    """Vzorkový text pro testy."""
    return """CyberBrain26 je lokální, modulární AI prostředí s důrazem na bezpečnost.
Funguje v fázi F2 (minimal complete agent flow) a testuje se 747 testů.
Knowledge plane umožňuje vektorové uložení a sémantické vyhledávání dokumentů.
Embedding model qwen3-embedding:0.6b generuje vektory o rozměru 1024."""


def test_memory_service_file_registration(
    memory_service: MemoryService,
    tmp_path: Path,
    sample_text: str,
) -> None:
    """Test: registrace souboru končí úspěšně a dokument se najde."""
    # Vytvoření vzorkového souboru
    file_path = tmp_path / "test_note.txt"
    file_path.write_text(sample_text, encoding="utf-8")

    # Registrace souboru
    document, created = memory_service.register_file(file_path)
    assert created is True
    assert document is not None
    assert document.document_id is not None
    assert document.status is not None

    # Kontrola, že dokument jde získat zpět
    retrieved = memory_service.get_document(document.document_id)
    assert retrieved is not None
    assert retrieved.document_id == document.document_id


def test_memory_service_semantic_search(
    memory_service: MemoryService,
    tmp_path: Path,
    sample_text: str,
) -> None:
    """Test: sémantické vyhledávání vrátí relevantní výsledky."""
    # Vyřešení: pokud Ollama není dostupné, přeskoč test před jakýchkoli operandy
    if not memory_service.health_check().get("healthy", False):
        pytest.skip("Embedding service (Ollama) not available")
    
    # Registrace vzorkového souboru
    file_path = tmp_path / "test_note.txt"
    file_path.write_text(sample_text, encoding="utf-8")

    memory_service.register_file(file_path)

    # Vyhledávání pomocí textu ze stejného souboru
    results = memory_service.semantic_search("CyberBrain26 modulární AI")
    assert len(results) > 0
    # První výsledek by měl být náš dokument
    # Poznámka: chunker normalizuje whitespace (nové řádky -> mezery),
    # proto porovnáváme normalizovaný text
    assert " ".join(results[0]["text"].split()) == " ".join(sample_text.split())


def test_memory_service_search_by_topic(
    memory_service: MemoryService,
    tmp_path: Path,
    sample_text: str,
) -> None:
    """Test: vyhledávání podle topiku."""
    file_path = tmp_path / "test_note.txt"
    file_path.write_text(sample_text, encoding="utf-8")

    memory_service.register_file(file_path)

    # Nastavení topiku v metadata
    document = memory_service.get_document(next(iter(memory_service._all_document_ids())))
    assert document is not None

    # Vyhledávání podle topiku
    topics = memory_service.get_topics()
    # Dokument by měl být zařazen pod nějaký topic
    assert len(topics) > 0


def test_memory_service_health_check(
    memory_service: MemoryService,
) -> None:
    """Test: health_check vrátí zdravý stav."""
    health = memory_service.health_check()
    # embedding health může být unhealthy pokud Ollama není běžící, to je v pořádku
    # důležité je, že struktura je správná
    assert "embedding" in health
    assert "vector_store_count" in health


def test_memory_service_duplicate_detection(
    memory_service: MemoryService,
    tmp_path: Path,
    sample_text: str,
) -> None:
    """Test: detekce duplicitního obsahu."""
    file_path1 = tmp_path / "test_note1.txt"
    file_path1.write_text(sample_text, encoding="utf-8")

    file_path2 = tmp_path / "test_note2.txt"
    file_path2.write_text(sample_text, encoding="utf-8")  # Identický obsah

    # Registrace obou souborů - druhý by měl být označen jako duplicitní
    _doc1, created1 = memory_service.register_file(file_path1)
    assert created1 is True

    _doc2, _created2 = memory_service.register_file(file_path2)
    # Při registraci stejného obsahu se chování liší podle deduplikace
    # Test ověří že systém pracuje


def test_memory_service_topics_and_tags(
    memory_service: MemoryService,
    tmp_path: Path,
    sample_text: str,
) -> None:
    """Test: topic a tag navigation funguje."""
    file_path = tmp_path / "test_note.txt"
    file_path.write_text(sample_text, encoding="utf-8")

    memory_service.register_file(file_path)

    # Získání topiců a štítků
    topics = memory_service.get_topics()
    tags = memory_service.get_tags()

    # Asertujeme že nějaké topic/štítek existuje (může být "uncategorized")
    assert len(topics) > 0 or len(tags) > 0


def test_end_to_end_pipeline_with_new_file(
    memory_service: MemoryService,
    tmp_path: Path,
) -> None:
    """Komplexní test celého pipeline: soubor → chunk → embed → store → search → retrieve."""
    # Vytvoření více souborů s různými tématy
    file1 = tmp_path / "doc1_ai.txt"
    file1.write_text("Umělá inteligence a strojové učení", encoding="utf-8")

    file2 = tmp_path / "doc2_security.txt"
    file2.write_text("Bezpečnostní protokoly a audit", encoding="utf-8")

    file3 = tmp_path / "doc3_planning.txt"
    file3.write_text("Plánování agentů a workflow", encoding="utf-8")

    # Registrace všech souborů
    memory_service.register_file(file1)
    memory_service.register_file(file2)
    memory_service.register_file(file3)

    if not memory_service.health_check().get("healthy", False):
        pytest.skip("Embedding service (Ollama) not available")
    # Sémantické vyhledávání
    results = memory_service.semantic_search("agent")
    assert len(results) >= 1

    # Vyhledávání podle počtu dokumentů
    topics = memory_service.get_topics()
    assert len(topics) > 0

    # Kontrola počtu vektorů
    count = memory_service.vector_store.count()
    assert count >= 3  # Minimálně 3 dokumenty vloženo


def test_memory_service_with_memory_text(
    memory_service: MemoryService,
) -> None:
    """Test: registrace čistého textu z paměti."""
    content = b"Test content for memory service"
    document, created = memory_service.register_text(
        content=content,
        source_uri="memory://test",
        source_id="test-memory",
        topic="test",
        tags=["test", "memory"],
    )

    assert created is True
    assert document is not None

    # Sémantické vyhledávání
    results = memory_service.semantic_search("test content")
    assert len(results) > 0

    # Získání dokumentu
    retrieved = memory_service.get_document(document.document_id)
    assert retrieved is not None
    assert retrieved.content_sha256 == hashlib.sha256(content).hexdigest()


if __name__ == "__main__":
    pytest.main([__file__, "-v"])