"""P17 Neuroscience Refinements: Source Inspection Tests (Items 66-70)."""

ROOT = "C:/Users/ovall/Documents/projects/babel_bot/PULSE"
WM_PATH  = ROOT + "/pulse/brain/working_memory.py"
SE_PATH  = ROOT + "/pulse/brain/brain_search/search_engine.py"
PD_PATH  = ROOT + "/pulse/tasks/pulse_dispatcher.py"


def _src(path):
    with open(path, encoding="utf-8") as f:
        return f.read()


def _lines(path):
    return _src(path).count("\n") + 1


# ===== Item 66: Phonological slot tier =====

class TestItem66PhonologicalBuffer:

    def test_buffer_dict_exists(self):
        assert "_PHONOLOGICAL_BUFFER" in _src(WM_PATH)

    def test_buffer_is_dict_type(self):
        src = _src(WM_PATH)
        assert "_PHONOLOGICAL_BUFFER: dict = {}" in src or "_PHONOLOGICAL_BUFFER = {}" in src

    def test_ttl_constant_exists(self):
        src = _src(WM_PATH)
        assert "_PHONOLOGICAL_TTL" in src

    def test_ttl_is_300(self):
        src = _src(WM_PATH)
        assert "_PHONOLOGICAL_TTL = 300" in src

    def test_add_phonological_function_exists(self):
        assert "_add_phonological" in _src(WM_PATH)

    def test_add_phonological_stores_text(self):
        src = _src(WM_PATH)
        assert '"text"' in src and '"ts"' in src

    def test_add_phonological_evicts_expired(self):
        src = _src(WM_PATH)
        assert "cutoff" in src and "_PHONOLOGICAL_BUFFER" in src

    def test_add_phonological_truncates_at_200(self):
        src = _src(WM_PATH)
        assert "text[:200]" in src

    def test_add_phonological_fail_open(self):
        src = _src(WM_PATH)
        # find the _add_phonological function block
        idx = src.find("def _add_phonological")
        block = src[idx:idx + 600]
        assert "except Exception" in block

    def test_wm_file_under_300_lines(self):
        assert _lines(WM_PATH) <= 300, f"working_memory.py has {_lines(WM_PATH)} lines"


# ===== Item 67: Visuospatial sketchpad =====

class TestItem67VisuospatialSketch:

    def test_sketch_list_exists(self):
        assert "_VISUOSPATIAL_SKETCH" in _src(WM_PATH)

    def test_sketch_is_list_type(self):
        src = _src(WM_PATH)
        assert "_VISUOSPATIAL_SKETCH: list = []" in src or "_VISUOSPATIAL_SKETCH = []" in src

    def test_sketch_max_constant_exists(self):
        assert "_SKETCH_MAX" in _src(WM_PATH)

    def test_sketch_max_is_50(self):
        assert "_SKETCH_MAX = 50" in _src(WM_PATH)

    def test_update_sketch_function_exists(self):
        assert "_update_sketch" in _src(WM_PATH)

    def test_update_sketch_appends_nodes(self):
        src = _src(WM_PATH)
        idx = src.find("def _update_sketch")
        block = src[idx:idx + 400]
        assert "_VISUOSPATIAL_SKETCH.append" in block

    def test_update_sketch_caps_at_max(self):
        src = _src(WM_PATH)
        idx = src.find("def _update_sketch")
        block = src[idx:idx + 400]
        assert "_SKETCH_MAX" in block

    def test_update_sketch_deduplicates(self):
        src = _src(WM_PATH)
        idx = src.find("def _update_sketch")
        block = src[idx:idx + 400]
        assert "not in _VISUOSPATIAL_SKETCH" in block

    def test_update_sketch_fail_open(self):
        src = _src(WM_PATH)
        idx = src.find("def _update_sketch")
        block = src[idx:idx + 400]
        assert "except Exception" in block


# ===== Item 68: Serial vs parallel search =====

class TestItem68SerialParallelSearch:

    def test_is_complex_flag_exists(self):
        assert "_is_complex" in _src(SE_PATH)

    def test_complexity_checks_word_count(self):
        src = _src(SE_PATH)
        assert "len(query.split())" in src and ">= 3" in src

    def test_complexity_checks_operators(self):
        src = _src(SE_PATH)
        assert "'AND'" in src or '"AND"' in src

    def test_simple_query_reduces_sources(self):
        src = _src(SE_PATH)
        assert "not _is_complex" in src

    def test_serial_mode_keeps_core_sources(self):
        src = _src(SE_PATH)
        assert '"wins"' in src and '"fails"' in src and '"anti_patterns"' in src

    def test_serial_mode_uses_five_sources(self):
        src = _src(SE_PATH)
        idx = src.find("not _is_complex")
        block = src[idx:idx + 300]
        # block should reference the 5 core sources
        core = ["wins", "fails", "patterns", "anti_patterns", "decisions"]
        for s in core:
            assert s in block, f"Missing source '{s}' in serial mode block"

    def test_se_file_under_300_lines(self):
        assert _lines(SE_PATH) <= 300, f"search_engine.py has {_lines(SE_PATH)} lines"


# ===== Item 69: Cognitive load-adaptive source pruning =====

class TestItem69CognitiveLoadPruning:

    def test_interoception_import_attempted(self):
        src = _src(SE_PATH)
        assert "interoception" in src

    def test_agent_load_read(self):
        src = _src(SE_PATH)
        assert "agent_load" in src

    def test_high_load_threshold_10(self):
        src = _src(SE_PATH)
        assert "load > 10" in src

    def test_medium_load_threshold_5(self):
        src = _src(SE_PATH)
        assert "load > 5" in src

    def test_max_sources_5_for_high_load(self):
        src = _src(SE_PATH)
        assert "5 if load > 10" in src or "max_sources = 5" in src

    def test_max_sources_8_for_medium_load(self):
        src = _src(SE_PATH)
        assert "8 if load > 5" in src or "max_sources = 8" in src

    def test_priority_source_list_exists(self):
        src = _src(SE_PATH)
        assert "priority" in src and "anti_patterns" in src

    def test_pruning_fail_open(self):
        src = _src(SE_PATH)
        idx = src.find("agent_load")
        # Walk backward to find the try block, forward to find except
        block = src[max(0, idx - 200):idx + 400]
        assert "except Exception" in block


# ===== Item 70: Agent mentalizing =====

class TestItem70AgentMentalizing:

    def test_agent_outcomes_dict_initialized(self):
        src = _src(PD_PATH)
        assert "_AGENT_OUTCOMES" in src

    def test_getattr_pattern_for_module_state(self):
        src = _src(PD_PATH)
        assert 'getattr(sys.modules[__name__], "_AGENT_OUTCOMES"' in src

    def test_domain_task_key_format(self):
        src = _src(PD_PATH)
        assert 'f"{domain}:{task_type}"' in src or '"domain"' in src

    def test_outcome_recorded_per_agent(self):
        src = _src(PD_PATH)
        assert '"agent"' in src and '"outcome"' in src and '"confidence"' in src

    def test_capped_at_20_per_key(self):
        src = _src(PD_PATH)
        assert "[-20:]" in src

    def test_module_state_persisted(self):
        src = _src(PD_PATH)
        assert 'sys.modules[__name__]._AGENT_OUTCOMES = _AGENT_OUTCOMES' in src

    def test_mentalizing_fail_open(self):
        src = _src(PD_PATH)
        # Find the mentalizing try/except block specifically
        idx = src.find("Item 70: mentalizing")
        assert idx != -1, "Item 70 comment not found"
        block = src[idx:idx + 1100]
        assert "except Exception" in block

    def test_recommended_agent_used(self):
        src = _src(PD_PATH)
        assert "recommended_agent" in src

    def test_pd_file_under_300_lines(self):
        assert _lines(PD_PATH) <= 300, f"pulse_dispatcher.py has {_lines(PD_PATH)} lines"
