"""Unit tests for context file template content verification.

Verifies that all context file templates in ``backend/context/`` contain
the required markers, sections, directives, and that removed content is
absent. Also checks that the total system-default token count stays
within the 3,000-token budget.

Testing methodology: unit tests with direct file reads.
Key invariants:
- Each template preserves its correct marker (⚙️/👤/🤖)
- Required Chinese directives are present where specified
- Removed legacy content is absent
- System-default files fit within token budget
"""
import pytest
from pathlib import Path


TEMPLATES_DIR = Path(__file__).parent.parent / "context"


def _read_template(filename: str) -> str:
    """Read a template file and return its content."""
    path = TEMPLATES_DIR / filename
    assert path.is_file(), f"Template {filename} not found at {path}"
    return path.read_text(encoding="utf-8")


# ---------------------------------------------------------------------------
# Marker verification
# ---------------------------------------------------------------------------

class TestTemplateMarkers:
    """Verify each template contains its correct inline comment marker."""

    @pytest.mark.parametrize("filename", [
        "SWARMAI.md", "IDENTITY.md", "SOUL.md", "AGENT.md",
    ])
    def test_system_default_marker(self, filename: str):
        content = _read_template(filename)
        assert "⚙️ SYSTEM DEFAULT" in content, (
            f"{filename} missing ⚙️ SYSTEM DEFAULT marker"
        )

    @pytest.mark.parametrize("filename", [
        "USER.md", "STEERING.md", "TOOLS.md", "KNOWLEDGE.md", "PROJECTS.md",
    ])
    def test_user_customized_marker(self, filename: str):
        content = _read_template(filename)
        assert "✏️ YOUR FILE" in content, (
            f"{filename} missing ✏️ YOUR FILE marker"
        )

    def test_memory_agent_managed_marker(self):
        content = _read_template("MEMORY.md")
        assert "⚠️ AGENT-OWNED" in content, (
            "MEMORY.md missing ⚠️ AGENT-OWNED marker"
        )


# ---------------------------------------------------------------------------
# SOUL.md content verification
# ---------------------------------------------------------------------------

class TestSoulTemplate:
    """Verify SOUL.md has required OpenClaw-inspired content."""

    def test_chinese_framing(self):
        content = _read_template("SOUL.md")
        assert "You're not a chatbot" in content
        assert "becoming someone" in content

    def test_good_bad_examples(self):
        content = _read_template("SOUL.md")
        assert "Good:" in content
        assert "Bad:" in content

    def test_continuity_section(self):
        content = _read_template("SOUL.md")
        assert "## 🚨 CRITICAL: Continuity" in content
        assert "context files ARE your memory" in content


# ---------------------------------------------------------------------------
# IDENTITY.md content verification
# ---------------------------------------------------------------------------

class TestIdentityTemplate:
    """Verify IDENTITY.md has avatar field and evolving identity guidance."""

    def test_avatar_field(self):
        content = _read_template("IDENTITY.md")
        assert "Avatar:" in content or "avatar" in content.lower()

    def test_evolving_identity(self):
        content = _read_template("IDENTITY.md")
        assert "Evolving Identity" in content or "evolving" in content.lower()


# ---------------------------------------------------------------------------
# AGENT.md content verification
# ---------------------------------------------------------------------------

class TestAgentTemplate:
    """Verify AGENT.md has core governance structure, safety rules, and principles."""

    def test_files_over_brain_directive(self):
        content = _read_template("AGENT.md")
        assert "Files > Brain" in content

    def test_trash_over_rm_rule(self):
        content = _read_template("AGENT.md")
        assert "trash > rm" in content

    def test_has_rules_section(self):
        content = _read_template("AGENT.md")
        # Three-Layer Governance: rules tagged with parent principle
        assert "## Rules" in content

    def test_has_intake_gate(self):
        content = _read_template("AGENT.md")
        assert "Intake Gate" in content

    def test_has_coding_rules(self):
        content = _read_template("AGENT.md")
        assert "Coding" in content

    def test_has_safety_section(self):
        content = _read_template("AGENT.md")
        assert "Safety" in content

    def test_memory_writing_rules(self):
        content = _read_template("AGENT.md")
        assert "DailyActivity" in content
        assert "MEMORY.md" in content


# ---------------------------------------------------------------------------
# USER.md content verification
# ---------------------------------------------------------------------------

class TestUserTemplate:
    """Verify USER.md has Background section and humanistic footer."""

    def test_background_section(self):
        content = _read_template("USER.md")
        assert "## Background" in content

    def test_humanistic_footer(self):
        content = _read_template("USER.md")
        assert "getting to know a person" in content
        assert "not building a dossier" in content


# ---------------------------------------------------------------------------
# STEERING.md content verification
# ---------------------------------------------------------------------------

class TestSteeringTemplate:
    """Verify STEERING.md is a clean user-editable file (system content moved to AGENT.md)."""

    def test_write_it_down_directive(self):
        """Memory protocol details now live in AGENT.md, not STEERING.md."""
        content = _read_template("AGENT.md")
        assert "memory" in content.lower() or "MEMORY.md" in content

    def test_no_mental_notes(self):
        content = _read_template("STEERING.md")
        assert "note important discoveries mentally" not in content

    def test_two_tier_model(self):
        """Two-tier memory model is documented in AGENT.md."""
        content = _read_template("AGENT.md")
        assert "DailyActivity" in content
        assert "MEMORY.md" in content

    def test_distillation_rules(self):
        """Distillation rules are documented in AGENT.md."""
        content = _read_template("AGENT.md")
        assert "distill" in content.lower() or "MEMORY.md" in content

    def test_updated_directory_structure(self):
        """Session start references key files."""
        content = _read_template("AGENT.md")
        # New AGENT.md references DailyActivity in Session Start
        assert "DailyActivity" in content
        assert "MEMORY.md" in content
        assert "STEERING.md" in content

    def test_no_knowledge_base_reference(self):
        content = _read_template("STEERING.md")
        assert "Knowledge Base/" not in content

    def test_file_saving_rules(self):
        """AGENT.md references Knowledge directory via DDD enrichment."""
        content = _read_template("AGENT.md")
        # New AGENT.md references Knowledge in DDD enrichment and self-enhancement
        assert "Knowledge" in content
        assert "KNOWLEDGE.md" in content


# ---------------------------------------------------------------------------
# MEMORY.md content verification
# ---------------------------------------------------------------------------

class TestMemoryTemplate:
    """Verify MEMORY.md has two-tier model guidance and distillation."""

    def test_two_tier_guidance(self):
        content = _read_template("MEMORY.md")
        assert "DailyActivity" in content
        assert "two-tier" in content.lower() or "Two-tier" in content

    def test_distillation_instructions(self):
        content = _read_template("MEMORY.md")
        assert "distill" in content.lower()


# ---------------------------------------------------------------------------
# KNOWLEDGE.md content verification
# ---------------------------------------------------------------------------

class TestKnowledgeTemplate:
    """Verify KNOWLEDGE.md is restructured as Knowledge Directory index."""

    def test_no_old_sections(self):
        content = _read_template("KNOWLEDGE.md")
        assert "## Tech Stack" not in content
        assert "## Coding Conventions" not in content
        assert "## Architecture Notes" not in content
        assert "## Reference" not in content

    def test_subfolder_sections(self):
        content = _read_template("KNOWLEDGE.md")
        assert "Notes" in content
        assert "Reports" in content
        assert "Meetings" in content
        assert "Library" in content
        assert "Archives" in content
        assert "DailyActivity" in content

    def test_index_guidance(self):
        content = _read_template("KNOWLEDGE.md")
        assert "index" in content.lower() or "Index" in content


# ---------------------------------------------------------------------------
# PROJECTS.md content verification
# ---------------------------------------------------------------------------

class TestProjectsTemplate:
    """Verify PROJECTS.md has project folder linking guidance."""

    def test_folder_linking(self):
        content = _read_template("PROJECTS.md")
        assert "SwarmWS/Projects/" in content or "Projects/" in content
        assert "Folder:" in content or "folder" in content.lower()


# ---------------------------------------------------------------------------
# Token budget verification — REMOVED
# ---------------------------------------------------------------------------
# Hardcoded token budget tests removed (2026-03-23).  System-default files
# evolve frequently; static thresholds (4000/3500) produced false failures
# without catching real regressions.  Token budgets are enforced dynamically
# by ContextDirectoryLoader's budget tiers, not by unit-test constants.


# ---------------------------------------------------------------------------
# Session-start Open Threads verification (Req 5.2, 5.3)
# ---------------------------------------------------------------------------

SKILLS_DIR = Path(__file__).parent.parent / "skills"


class TestSessionStartOpenThreads:
    """Verify AGENT.md and STEERING.md use session-start Open Threads review."""

    def test_agent_md_session_start_open_threads(self):
        """Req 5.2: AGENT.md contains Session Start section referencing open threads."""
        content = _read_template("AGENT.md")
        assert "Session Start" in content, (
            "AGENT.md missing 'Session Start' section"
        )
        assert "open threads" in content.lower(), (
            "AGENT.md missing open threads reference"
        )

    def test_agent_md_no_session_end_open_threads(self):
        """Req 5.2: AGENT.md should NOT have 'At session end' for Open Threads."""
        content = _read_template("AGENT.md")
        assert "At session end" not in content, (
            "AGENT.md still contains 'At session end' directive"
        )

    def test_steering_md_extended_memory_protocol(self):
        """Req 5.3: Memory protocol details now live in AGENT.md (STEERING.md is user-editable)."""
        content = _read_template("AGENT.md")
        assert "memory" in content.lower() or "MEMORY.md" in content, (
            "AGENT.md missing memory protocol content"
        )

    def test_steering_md_no_session_end_block(self):
        """Req 5.3: STEERING.md should NOT have 'At session end (if asked)' block."""
        content = _read_template("STEERING.md")
        assert "At session end (if asked)" not in content, (
            "STEERING.md still contains 'At session end (if asked)' block"
        )

    def test_steering_md_distillation_in_place(self):
        """Req 5.5: Distillation rules now live in AGENT.md (STEERING.md is user-editable)."""
        content = _read_template("AGENT.md")
        assert "distill" in content.lower() or "MEMORY.md" in content, (
            "AGENT.md missing distillation directive"
        )


# ---------------------------------------------------------------------------
# Distillation skill verification (Req 3.1, 3.6)
# ---------------------------------------------------------------------------

class TestDistillationSkill:
    """Verify s_memory-distill/SKILL.md exists and contains required content."""

    def test_skill_file_exists(self):
        """Req 3.1: SKILL.md exists at the expected path."""
        skill_path = SKILLS_DIR / "s_memory-distill" / "SKILL.md"
        assert skill_path.is_file(), (
            f"Distillation skill not found at {skill_path}"
        )

    def test_skill_has_yaml_frontmatter(self):
        """SKILL.md has YAML frontmatter with name and description."""
        content = (SKILLS_DIR / "s_memory-distill" / "SKILL.md").read_text()
        assert content.startswith("---"), "SKILL.md missing YAML frontmatter"
        assert "name: memory-distill" in content

    def test_skill_has_detection_section(self):
        """Req 3.2/3.3: SKILL.md has Detection section with threshold."""
        content = (SKILLS_DIR / "s_memory-distill" / "SKILL.md").read_text()
        assert "Detection" in content
        assert "≤ 3" in content or "<= 3" in content or "≤3" in content

    def test_skill_has_extraction_section(self):
        """Req 3.4: SKILL.md has Extraction section."""
        content = (SKILLS_DIR / "s_memory-distill" / "SKILL.md").read_text()
        assert "Extraction" in content
        assert "key decisions" in content.lower()
        assert "lessons" in content.lower()

    def test_skill_has_writing_section(self):
        """Req 3.5/3.8: SKILL.md has Writing section with locked_write."""
        content = (SKILLS_DIR / "s_memory-distill" / "SKILL.md").read_text()
        assert "Writing" in content or "MEMORY.md" in content
        assert "locked_write" in content

    def test_skill_has_marking_section(self):
        """Req 3.6: SKILL.md references distilled: true frontmatter marking."""
        content = (SKILLS_DIR / "s_memory-distill" / "SKILL.md").read_text()
        assert "distilled: true" in content
        assert "distilled_date" in content

    def test_skill_has_archiving_section(self):
        """Req 3.7: SKILL.md has Archiving section with age thresholds."""
        content = (SKILLS_DIR / "s_memory-distill" / "SKILL.md").read_text()
        assert "Archiving" in content or "Archives" in content
        assert "30" in content  # 30-day threshold
        assert "90" in content  # 90-day threshold

    def test_skill_has_open_threads_section(self):
        """Req 5.4: SKILL.md has Open Threads cross-reference."""
        content = (SKILLS_DIR / "s_memory-distill" / "SKILL.md").read_text()
        assert "Open Threads" in content

    def test_skill_is_silent(self):
        """Req 3.9: SKILL.md specifies silent operation."""
        content = (SKILLS_DIR / "s_memory-distill" / "SKILL.md").read_text()
        assert "silent" in content.lower()

    def test_skill_has_fallback_section(self):
        """Req 3.5: SKILL.md has fallback ## Distilled section."""
        content = (SKILLS_DIR / "s_memory-distill" / "SKILL.md").read_text()
        assert "Distilled" in content
        assert "fallback" in content.lower()
