#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""P16 Neuroscience refinements — source inspection tests only. No DB calls."""
import re
from pathlib import Path

ROOT = Path(__file__).resolve().parent.parent

# ---------------------------------------------------------------------------
# Helper: read source once per file
# ---------------------------------------------------------------------------
def _read(rel: str) -> str:
    return (ROOT / rel).read_text(encoding="utf-8", errors="replace")


SE = _read("pulse/brain/brain_search/search_engine.py")
JS = _read("pulse/brain/save_writers/jsonl_store.py")
HC = _read("pulse/brain/memory/hot_cache.py")
BR = _read("pulse/brain/brain_query/briefing.py")


# ===========================================================================
# Item 61 — Context-dependent forgetting reinstatement
# ===========================================================================

class TestItem61ContextReinstatement:
    """search_engine.py: items with confidence < 0.2 get +0.2 boost when context matches."""

    def test_reinstated_flag_present_in_source(self):
        assert "_reinstated" in SE

    def test_reinstatement_adds_0_2(self):
        assert 'h["confidence"] += 0.2' in SE

    def test_reinstatement_only_when_low_confidence(self):
        # Must check confidence < 0.2 threshold
        assert 'h.get("confidence", 0.5) < 0.2' in SE

    def test_reinstatement_requires_task_type(self):
        # task_type must be truthy for reinstatement to fire
        assert "task_type" in SE
        idx = SE.find("_reinstated")
        snippet = SE[max(0, idx - 200):idx + 50]
        assert "task_type" in snippet

    def test_reinstatement_checks_domain_in_query(self):
        assert 'h.get("domain", "") in query.lower()' in SE

    def test_reinstatement_wrapped_in_try_except(self):
        idx = SE.find("_reinstated")
        snippet = SE[max(0, idx - 300):idx + 100]
        assert "try:" in snippet
        assert "except Exception" in snippet


# ===========================================================================
# Item 62 — Implementation intentions WHEN/DO templates
# ===========================================================================

class TestItem62WhenDoTemplates:
    """jsonl_store.py: intent-type entries get when_trigger + do_action fields."""

    def test_when_do_regex_defined(self):
        assert "_WHEN_DO_RE" in JS

    def test_when_do_regex_uses_re_ignorecase(self):
        assert "re.IGNORECASE" in JS
        # Check the specific _WHEN_DO_RE definition has IGNORECASE
        idx = JS.find("_WHEN_DO_RE")
        snippet = JS[idx:idx + 200]
        assert "IGNORECASE" in snippet

    def test_when_trigger_field_set(self):
        assert '"when_trigger"' in JS

    def test_do_action_field_set(self):
        assert '"do_action"' in JS

    def test_extraction_only_for_intent_type(self):
        idx = JS.find("when_trigger")
        snippet = JS[max(0, idx - 200):idx + 50]
        assert 'knowledge_type == "intent"' in snippet

    def test_wrapped_in_try_except(self):
        idx = JS.find("when_trigger")
        snippet = JS[max(0, idx - 300):idx + 100]
        assert "try:" in snippet
        assert "except Exception" in snippet

    def test_regex_pattern_captures_two_groups(self):
        # Pattern must have two capture groups for WHEN and DO
        idx = JS.find("_WHEN_DO_RE = re.compile")
        snippet = JS[idx:idx + 200]
        groups = snippet.count("(")
        assert groups >= 2, f"Expected >=2 groups in regex, found {groups}"

    def test_regex_applied_with_search(self):
        assert "_WHEN_DO_RE.search(" in JS


# ===========================================================================
# Item 63 — Superseded items stay searchable with validity filter
# ===========================================================================

class TestItem63SupersededSearchable:
    """search_engine.py: superseded items get [SUPERSEDED] prefix + halved confidence."""

    def test_superseded_prefix_in_source(self):
        assert "[SUPERSEDED]" in SE

    def test_superseded_halves_confidence(self):
        # Confidence multiplied by 0.5
        idx = SE.find("[SUPERSEDED]")
        snippet = SE[idx:idx + 200]
        assert "* 0.5" in snippet

    def test_superseded_not_in_skip_list(self):
        # "superseded" must NOT appear in the same line as "expired", "historical" skip list
        # (it's handled separately, not skipped)
        expired_line_idx = SE.find('"expired", "historical"')
        superseded_not_in_skip = "superseded" not in SE[expired_line_idx:expired_line_idx + 80]
        assert superseded_not_in_skip

    def test_superseded_check_uses_validity_var(self):
        idx = SE.find("[SUPERSEDED]")
        snippet = SE[max(0, idx - 100):idx + 50]
        assert 'validity == "superseded"' in snippet

    def test_superseded_title_uses_fstring(self):
        assert 'f"[SUPERSEDED] {h.get(\'title\'' in SE or 'f"[SUPERSEDED] {h.get("title"' in SE


# ===========================================================================
# Item 64 — Hot cache bypasses epistemic qualification
# ===========================================================================

class TestItem64HotCacheSkipEpistemic:
    """hot_cache.py sets _skip_epistemic=True; search_engine.py checks the flag."""

    def test_hot_cache_sets_skip_epistemic(self):
        assert '_skip_epistemic' in HC

    def test_hot_cache_sets_to_true(self):
        assert '"_skip_epistemic"] = True' in HC or "_skip_epistemic\"] = True" in HC

    def test_search_engine_checks_skip_epistemic(self):
        assert '_skip_epistemic' in SE

    def test_search_engine_skips_qualifier_when_flag_set(self):
        # The check must gate apply_epistemic_qualifiers
        idx = SE.find("_skip_epistemic")
        snippet = SE[idx:idx + 200]
        assert "apply_epistemic_qualifiers" in snippet

    def test_hot_cache_removed_direct_epistemic_call(self):
        # Old code called apply_epistemic_qualifiers directly in hot_cache.py
        # After item 64, that call is removed
        assert "apply_epistemic_qualifiers" not in HC

    def test_skip_epistemic_flag_is_boolean_true(self):
        # Must be literal True, not a string
        idx = HC.find("_skip_epistemic")
        snippet = HC[idx:idx + 30]
        assert "True" in snippet


# ===========================================================================
# Item 65 — Dynamic ignition gap based on cognitive load
# ===========================================================================

class TestItem65DynamicIgnitionGap:
    """briefing.py: ignition threshold varies with agent_load from interoception."""

    def test_ignition_threshold_defined(self):
        assert "ignition_threshold" in BR

    def test_agent_load_used_in_threshold(self):
        idx = BR.find("ignition_threshold")
        snippet = BR[idx:idx + 200]
        assert "agent_load" in snippet

    def test_threshold_formula_adds_load_factor(self):
        # Formula: 0.3 + (load * 0.05)
        assert "0.3 +" in BR
        assert "0.05" in BR

    def test_threshold_capped_at_0_8(self):
        assert "0.8" in BR
        idx = BR.find("ignition_threshold")
        snippet = BR[idx:idx + 200]
        assert "0.8" in snippet

    def test_fallback_is_0_4(self):
        assert "ignition_threshold = 0.4" in BR

    def test_interoception_import_in_try_block(self):
        idx = BR.find("ignition_threshold")
        snippet = BR[max(0, idx - 200):idx + 250]
        assert "try:" in snippet
        assert "interoception" in snippet

    def test_threshold_applied_to_all_hits_flat(self):
        # all_hits_flat must filter by ignition_threshold
        assert "all_hits_flat" in BR
        idx = BR.find("all_hits_flat")
        snippet = BR[idx:idx + 200]
        assert "ignition_threshold" in snippet

    def test_threshold_is_fail_open(self):
        # except block must set a default
        idx = BR.find("ignition_threshold = 0.4")
        assert idx != -1
        snippet = BR[max(0, idx - 50):idx + 30]
        assert "except" in snippet
