"""Tests for the Knowledge Manager tool."""

import pytest
from datetime import datetime, UTC, timedelta
from pathlib import Path
import tempfile
import shutil

from multi_swarm.tools.knowledge_manager import (
    KnowledgeManager,
    KnowledgeCategory,
    KnowledgeQuality,
    KnowledgeGap
)
from multi_swarm.core.rag import RAGSystem, Document

@pytest.fixture
def temp_dir():
    """Create a temporary directory for testing."""
    temp_path = Path(tempfile.mkdtemp())
    yield temp_path
    shutil.rmtree(temp_path)

@pytest.fixture
def manager(temp_dir):
    """Create a knowledge manager for testing."""
    return KnowledgeManager(storage_path=temp_dir)

@pytest.fixture
def rag_system(temp_dir):
    """Create a RAG system for testing."""
    return RAGSystem(storage_path=temp_dir / "rag")

def test_category_management(manager):
    """Test category creation and retrieval."""
    # Add root category
    tech = manager.add_category(
        "technical",
        "Technical documentation"
    )
    assert tech.name == "technical"
    assert tech.parent is None
    
    # Add child category
    python = manager.add_category(
        "python",
        "Python documentation",
        parent="technical"
    )
    assert python.name == "python"
    assert python.parent == "technical"
    
    # Get category
    retrieved = manager.get_category("python")
    assert retrieved.name == "python"
    assert retrieved.parent == "technical"
    
    # List categories
    all_cats = manager.list_categories()
    assert len(all_cats) == 2
    
    tech_cats = manager.list_categories(parent="technical")
    assert len(tech_cats) == 1
    assert tech_cats[0].name == "python"
    
    # Try to add duplicate
    with pytest.raises(ValueError):
        manager.add_category("technical", "Duplicate")
        
    # Try to add with invalid parent
    with pytest.raises(ValueError):
        manager.add_category("invalid", "Invalid", parent="nonexistent")

def test_quality_assessment(manager, rag_system):
    """Test document quality assessment."""
    manager.rag_system = rag_system
    
    # Add a document
    doc = rag_system.add_document(
        "Test document content",
        metadata={"category": "technical"}
    )
    
    # Create quality assessment
    quality = KnowledgeQuality(
        completeness=0.8,
        accuracy=0.9,
        relevance=0.7,
        timeliness=0.6,
        confidence=0.8
    )
    
    # Assess document
    manager.assess_quality(doc, quality)
    
    # Get assessment
    retrieved = manager.get_quality(doc.id)
    assert retrieved.completeness == 0.8
    assert retrieved.accuracy == 0.9
    
    # Check overall score
    score = retrieved.overall_score()
    assert 0.0 <= score <= 1.0
    
    # Invalid scores should raise validation error
    with pytest.raises(ValueError):
        KnowledgeQuality(completeness=1.5)

def test_knowledge_gaps(manager):
    """Test knowledge gap tracking."""
    # Add a gap
    gap = manager.add_knowledge_gap(
        "Testing",
        "Need more testing documentation",
        priority=4
    )
    
    assert gap.topic == "Testing"
    assert gap.priority == 4
    assert gap.status == "open"
    
    # List gaps
    gaps = manager.list_knowledge_gaps()
    assert len(gaps) == 1
    
    high_priority = manager.list_knowledge_gaps(min_priority=4)
    assert len(high_priority) == 1
    
    low_priority = manager.list_knowledge_gaps(min_priority=5)
    assert len(low_priority) == 0
    
    # Update gap status
    manager.update_gap_status(
        "Testing",
        "closed",
        resolution="Added comprehensive testing docs"
    )
    
    gaps = manager.list_knowledge_gaps(status="closed")
    assert len(gaps) == 1
    assert gaps[0].status == "closed"
    assert gaps[0].metadata["resolution"] == "Added comprehensive testing docs"

def test_coverage_analysis(manager, rag_system):
    """Test knowledge coverage analysis."""
    manager.rag_system = rag_system
    
    # Add documents
    doc1 = rag_system.add_document(
        "Technical document",
        metadata={"category": "technical"}
    )
    doc2 = rag_system.add_document(
        "Python document",
        metadata={"category": "python"}
    )
    
    # Add quality assessments
    quality1 = KnowledgeQuality(
        completeness=0.8,
        accuracy=0.9,
        relevance=0.7,
        timeliness=0.6,
        confidence=0.8
    )
    quality2 = KnowledgeQuality(
        completeness=0.6,
        accuracy=0.7,
        relevance=0.8,
        timeliness=0.9,
        confidence=0.7
    )
    
    manager.assess_quality(doc1, quality1)
    manager.assess_quality(doc2, quality2)
    
    # Analyze coverage
    coverage = manager.analyze_coverage()
    assert coverage["total_documents"] == 2
    assert coverage["assessed_documents"] == 2
    assert 0.0 <= coverage["average_quality"] <= 1.0
    assert coverage["coverage_ratio"] == 1.0
    
    # Analyze specific category
    tech_coverage = manager.analyze_coverage(category="technical")
    assert tech_coverage["total_documents"] == 1
    assert tech_coverage["assessed_documents"] == 1

def test_improvement_suggestions(manager, rag_system):
    """Test improvement suggestions."""
    manager.rag_system = rag_system
    
    # Add old document
    old_doc = rag_system.add_document(
        "Old document",
        metadata={"created_at": (datetime.now(UTC) - timedelta(days=200)).isoformat()}
    )
    
    # Add low quality document
    low_quality_doc = rag_system.add_document("Low quality document")
    manager.assess_quality(
        low_quality_doc,
        KnowledgeQuality(
            completeness=0.5,
            accuracy=0.6,
            relevance=0.4,
            timeliness=0.3,
            confidence=0.5
        )
    )
    
    # Add high priority gap
    manager.add_knowledge_gap(
        "Important Topic",
        "Missing critical information",
        priority=5
    )
    
    # Get suggestions
    suggestions = manager.suggest_improvements()
    
    # Should have suggestions for:
    # 1. Low quality documents
    # 2. Outdated documents
    # 3. High priority gaps
    assert len(suggestions) == 3
    
    types = [s["type"] for s in suggestions]
    assert "quality_improvement" in types
    assert "content_refresh" in types
    assert "knowledge_gaps" in types

def test_state_persistence(temp_dir):
    """Test state saving and loading."""
    # Create first instance
    manager1 = KnowledgeManager(storage_path=temp_dir)
    
    # Add some data
    manager1.add_category("test", "Test category")
    manager1.add_knowledge_gap("test gap", "Test description")
    
    # Create second instance (should load state)
    manager2 = KnowledgeManager(storage_path=temp_dir)
    
    # Verify state was loaded
    assert "test" in manager2.categories
    assert len(manager2.knowledge_gaps) == 1
    assert manager2.knowledge_gaps[0].topic == "test gap"

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