"""Tests for Self-Model section in timeline CLI output."""
import pytest
from unittest.mock import MagicMock, patch


class TestSelfModelSection:
    """Timeline CLI emits ## [Self-Model] when metacognitive memories exist."""

    def test_self_model_section_included_when_metacognitive_exist(self):
        from neo_cortex.timeline_cli import _build_self_model_section

        memories = [
            {
                "id": "v3_meta_abc_1",
                "summary": "I debug systematically using Protocol D",
                "energy": 0.9,
                "stability": 0.7,
                "observation_level": "metacognitive",
                "evidence_ids": "m1,m2,m3",
            },
            {
                "id": "v3_meta_def_2",
                "summary": "I prefer TDD approach for new features",
                "energy": 0.85,
                "stability": 0.6,
                "observation_level": "metacognitive",
                "evidence_ids": "m4,m5",
            },
        ]
        section = _build_self_model_section(memories)
        assert "## [Self-Model]" in section
        assert "Protocol D" in section
        assert "TDD" in section

    def test_self_model_empty_when_no_metacognitive(self):
        from neo_cortex.timeline_cli import _build_self_model_section

        section = _build_self_model_section([])
        assert section == ""

    def test_self_model_limited_to_ten_insights(self):
        from neo_cortex.timeline_cli import _build_self_model_section

        memories = [
            {
                "id": f"v3_meta_{i}",
                "summary": f"Insight number {i}",
                "energy": 0.9 - i * 0.01,
                "stability": 0.7,
                "observation_level": "metacognitive",
                "evidence_ids": f"m{i}",
            }
            for i in range(15)
        ]
        section = _build_self_model_section(memories)
        # Count @learned:: lines
        learned_lines = [l for l in section.splitlines() if l.startswith("@learned::")]
        assert len(learned_lines) <= 10

    def test_self_model_sorted_by_energy_times_stability(self):
        from neo_cortex.timeline_cli import _build_self_model_section

        memories = [
            {
                "id": "v3_meta_low",
                "summary": "Low score insight",
                "energy": 0.3,
                "stability": 0.2,
                "observation_level": "metacognitive",
                "evidence_ids": "m1",
            },
            {
                "id": "v3_meta_high",
                "summary": "High score insight",
                "energy": 0.95,
                "stability": 0.9,
                "observation_level": "metacognitive",
                "evidence_ids": "m2,m3,m4",
            },
        ]
        section = _build_self_model_section(memories)
        lines = section.strip().splitlines()
        # High score should appear before low score
        high_idx = next(i for i, l in enumerate(lines) if "High score" in l)
        low_idx = next(i for i, l in enumerate(lines) if "Low score" in l)
        assert high_idx < low_idx


class TestTimelineFetchesMetacognitive:
    """Timeline CLI queries metacognitive memories from index."""

    def test_get_metacognitive_memories_queries_sqlite(self):
        from neo_cortex.timeline_cli import _get_metacognitive_memories

        conn = MagicMock()
        conn.execute.return_value.fetchall.return_value = [
            ("v3_meta_1", "I debug with Protocol D", 0.9, 0.7, "metacognitive", "m1,m2"),
            ("v3_meta_2", "I prefer TDD", 0.8, 0.6, "metacognitive", "m3"),
        ]
        result = _get_metacognitive_memories(conn, limit=10)
        assert len(result) == 2
        assert result[0]["observation_level"] == "metacognitive"
        # Verify SQL was called with observation_level filter
        sql_call = conn.execute.call_args[0][0]
        assert "metacognitive" in sql_call.lower() or "observation_level" in sql_call.lower()
