# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""Tests for the 5 P0 cognition audit fixes (v10.37.55-56)."""


class TestGroundingColumnFix:
    """P0-1: grounding.py must update source_type COLUMN, not just metadata."""

    def test_promote_updates_column(self):
        """maybe_promote must write source_type='CONFIRMED' to the actual column."""
        from pulse.brain.integrity.grounding import maybe_promote
        from pulse.core.brain_db import get_conn, insert_knowledge
        from pulse.brain.save_writers.jsonl_store import build_jsonl_entry
        entry = build_jsonl_entry("p0 column test promote xyz", "test", "2026-03-19T20:00:00Z", "testing", 0.5, 3.0)
        insert_knowledge("lessons", entry)
        maybe_promote(entry["id"], "lessons", trigger="task_success", evidence={})
        conn = get_conn()
        row = conn.execute("SELECT source_type FROM lessons WHERE id = ?", (entry["id"],)).fetchone()
        assert row["source_type"] == "CONFIRMED", f"Column should be CONFIRMED, got {row['source_type']}"
        conn.execute("DELETE FROM lessons WHERE id = ?", (entry["id"],))
        conn.execute("DELETE FROM knowledge_fts WHERE item_id = ?", (entry["id"],))
        conn.commit()

    def test_demote_updates_column(self):
        """maybe_demote must write source_type='CONTESTED' to the actual column."""
        from pulse.brain.integrity.grounding import maybe_promote, maybe_demote
        from pulse.core.brain_db import get_conn, insert_knowledge
        from pulse.brain.save_writers.jsonl_store import build_jsonl_entry
        entry = build_jsonl_entry("p0 column test demote abc", "test", "2026-03-19T20:00:00Z", "testing", 0.5, 3.0)
        insert_knowledge("lessons", entry)
        maybe_promote(entry["id"], "lessons", trigger="task_success", evidence={})
        maybe_demote(entry["id"], "lessons", reason="test")
        conn = get_conn()
        row = conn.execute("SELECT source_type FROM lessons WHERE id = ?", (entry["id"],)).fetchone()
        assert row["source_type"] == "CONTESTED", f"Column should be CONTESTED, got {row['source_type']}"
        conn.execute("DELETE FROM lessons WHERE id = ?", (entry["id"],))
        conn.execute("DELETE FROM knowledge_fts WHERE item_id = ?", (entry["id"],))
        conn.commit()


class TestConsolidationDedupGate:
    """P0-2: pulse_dedup must skip O(n²) similarity for files > 5000 items."""

    def test_similarity_size_limit_exists(self):
        """Size gate must be in the source code."""
        with open("pulse/daemons/synthesis/pulse_dedup.py") as f:
            source = f.read()
        assert "5000" in source or "_SIMILARITY_SIZE_LIMIT" in source, "Size gate must exist"

    def test_dedup_source_has_size_check(self):
        """dedup_json_file must reference the size limit."""
        import ast
        with open("pulse/daemons/synthesis/pulse_dedup.py") as f:
            source = f.read()
        assert "_SIMILARITY_SIZE_LIMIT" in source, "Size limit must be referenced in dedup code"


class TestStage4bSQLitePromotion:
    """P0-3: stage_promote_to_patterns must target SQLite, not .md file."""

    def test_no_md_reference_in_promotion(self):
        """Promotion stage must not reference .md files."""
        with open("pulse/daemons/consolidation/stages/stage_promotion.py") as f:
            content = f.read()
        assert "auto_patterns.md" not in content, "Should not reference deleted .md file"

    def test_uses_insert_knowledge(self):
        """Promotion must use insert_knowledge for SQLite writes."""
        with open("pulse/daemons/consolidation/stages/stage_promotion.py") as f:
            content = f.read()
        assert "insert_knowledge" in content, "Must use insert_knowledge for SQLite"


class TestReconsolidationTTL:
    """P0-4: Reconsolidation TTL must be 300s (5min), not 30s."""

    def test_ttl_is_300(self):
        from pulse.brain.plasticity.reconsolidation import TTL_SECONDS
        assert TTL_SECONDS >= 300, f"TTL should be >= 300s, got {TTL_SECONDS}"

    def test_ttl_not_30(self):
        from pulse.brain.plasticity.reconsolidation import TTL_SECONDS
        assert TTL_SECONDS != 30, "TTL must not be the old 30s value"


class TestD21Priority:
    """P0-5: Neuroplasticity daemon must be HIGH priority, not LOW."""

    def test_neuroplasticity_is_high_priority(self):
        with open("pulse/daemons/synthesis/homeostatic_scheduler.py") as f:
            content = f.read()
        # Find the neuroplasticity entry in DAEMON_PRIORITY
        assert "neuroplasticity" in content.lower(), "Neuroplasticity must be in scheduler"
        # Check it's high priority
        import re
        match = re.search(r'"neuroplasticity[^"]*":\s*"(\w+)"', content)
        if match:
            assert match.group(1) == "high", f"Priority should be 'high', got '{match.group(1)}'"
