"""Tests 4 & 9: Context Engine assembly, truncation, and missing data handling."""
import pytest
from app.services.context_engine import assemble_context, MAX_CONTEXT_CHARS


class TestContextAssemblyFull:
    """Test 4: assemble_context with all inputs produces correct blocks."""

    def test_includes_global_context_block(self):
        result = assemble_context(
            domain="test.com",
            global_context={"master_rules": "Always be concise", "style_prefs": {"tone": "professional"}, "guardrails": {}},
        )
        assert "GLOBAL CONTEXT" in result
        assert "Always be concise" in result
        assert "professional" in result

    def test_includes_project_context_block(self):
        result = assemble_context(
            domain="test.com",
            project_context={
                "context_state": {"selected_niche": "fitness", "template_type": "hero"},
                "event_log": [{"timestamp": "2026-01-01T00:00:00Z", "action": "build_started", "detail": "test"}],
            },
        )
        assert "PROJECT CONTEXT" in result or "fitness" in result

    def test_includes_discovery_answers_block(self):
        result = assemble_context(
            domain="test.com",
            discovery_answers={"project_story": "I want to build a fitness brand", "ideal_audience": "gym goers"},
        )
        assert "DISCOVERY" in result
        assert "fitness brand" in result

    def test_includes_niche_block(self):
        result = assemble_context(
            domain="test.com",
            niche_data={"name": "Fitness Equipment Reviews", "description": "Reviews of home gym equipment"},
        )
        assert "NICHE" in result
        assert "Fitness Equipment" in result

    def test_includes_brandkit_block(self):
        result = assemble_context(
            domain="test.com",
            brandkit_summary={"tone": "energetic", "keywords": ["fitness", "health"]},
        )
        assert "BRAND KIT" in result or "energetic" in result

    def test_includes_profile_block(self):
        result = assemble_context(
            domain="test.com",
            profile_config={"sections": ["hero", "features"], "prompt_overrides": {"global_tone": "authoritative"}},
        )
        assert "PROFILE" in result or "authoritative" in result

    def test_all_blocks_together(self):
        result = assemble_context(
            domain="test.com",
            global_context={"master_rules": "Rule1", "style_prefs": {}, "guardrails": {}},
            project_context={"context_state": {"selected_niche": "tech"}, "event_log": []},
            profile_config={"sections": ["hero"], "prompt_overrides": {}},
            discovery_answers={"project_story": "My tech startup"},
            brandkit_summary={"tone": "modern"},
            niche_data={"name": "Tech Reviews"},
        )
        assert "GLOBAL CONTEXT" in result
        assert "Rule1" in result
        assert "My tech startup" in result
        assert "Tech Reviews" in result

    def test_respects_max_chars(self):
        long_rules = "A" * 15000
        result = assemble_context(
            domain="test.com",
            global_context={"master_rules": long_rules, "style_prefs": {}, "guardrails": {}},
            discovery_answers={"project_story": "B" * 5000},
        )
        assert len(result) <= MAX_CONTEXT_CHARS + 50

    def test_smart_truncation_preserves_priority_blocks(self):
        result = assemble_context(
            domain="test.com",
            global_context={"master_rules": "CRITICAL_RULE_XYZ", "style_prefs": {}, "guardrails": {}},
            discovery_answers={"project_story": "DISCOVERY_CONTENT_ABC"},
            niche_data={"name": "X" * 8000, "description": "Y" * 5000},
        )
        assert "CRITICAL_RULE_XYZ" in result
        assert "DISCOVERY_CONTENT_ABC" in result


class TestContextAssemblyMissingData:
    """Test 9: assemble_context handles missing/empty data gracefully."""

    def test_all_none_returns_empty(self):
        result = assemble_context(domain="test.com")
        assert result == ""

    def test_empty_dicts_returns_empty(self):
        result = assemble_context(
            domain="test.com",
            global_context={},
            project_context={},
            profile_config={},
            discovery_answers={},
            brandkit_summary={},
            niche_data={},
        )
        assert isinstance(result, str)

    def test_partial_global_context(self):
        result = assemble_context(
            domain="test.com",
            global_context={"master_rules": "Be creative", "style_prefs": None, "guardrails": None},
        )
        assert "Be creative" in result

    def test_none_domain_does_not_crash(self):
        result = assemble_context(domain="", global_context={"master_rules": "test"})
        assert isinstance(result, str)

    def test_empty_event_log(self):
        result = assemble_context(
            domain="test.com",
            project_context={"context_state": {"selected_niche": "health"}, "event_log": []},
        )
        assert isinstance(result, str)
