"""Phase 5 neuro refinements: tag-capture, diversity, temporal-salience, flashbulb."""
import inspect, sys
from datetime import datetime, timezone, timedelta
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT))


# ===== Item 6: Tag-capture =====

def test_tag_capture_source_present():
    import pulse.core.reward.reward_signal as mod
    src = inspect.getsource(mod.propagate_reward)
    assert chr(84)+chr(97)+chr(103)+"-and-capture" in src
    assert chr(48)+chr(46)+chr(49)+chr(53) in src
    assert "confidence < 0.4" in src


def test_tag_capture_covers_all_tables():
    import pulse.core.reward.reward_signal as mod
    src = inspect.getsource(mod.propagate_reward)
    for tbl in ("lessons", "failures", "patterns"):
        assert tbl in src, f"tag-capture missing table {tbl}"


def test_tag_capture_fail_open():
    import pulse.core.reward.reward_signal as mod
    src = inspect.getsource(mod.propagate_reward)
    marker = chr(84)+chr(97)+chr(103)+"-and-capture"
    idx = src.index(marker)
    snip = src[idx:]
    assert "except Exception:" in snip
    assert snip.index("pass") > 0


def test_tag_capture_only_on_positive_reward():
    import pulse.core.reward.reward_signal as mod
    src = inspect.getsource(mod.propagate_reward)
    marker = chr(84)+chr(97)+chr(103)+"-and-capture"
    assert src.index(marker) > src.index("if credit > 0:")


# ===== Item 7: Diversity bonus =====

def test_diversity_bonus_source_present():
    import pulse.core.reward.reward_signal as mod
    src = inspect.getsource(mod.assign_credit)
    assert "diversity" in src.lower()
    assert "1.5" in src


def test_diversity_bonus_underdog_condition():
    import pulse.core.reward.reward_signal as mod
    src = inspect.getsource(mod.assign_credit)
    assert "access_count" in src
    assert "evidence_count" in src


def test_diversity_bonus_fail_open():
    import pulse.core.reward.reward_signal as mod
    src = inspect.getsource(mod.assign_credit)
    assert ".get(" in src, "must use .get() for safe dict access"


def test_diversity_bonus_metadata_aware():
    import pulse.core.reward.reward_signal as mod
    src = inspect.getsource(mod.assign_credit)
    assert "item_metadata" in src or "access_count" in src


# ===== Item 9: Temporal salience =====

def test_temporal_salience_exists():
    from pulse.core.temporal import temporal_salience
    assert callable(temporal_salience)


def test_temporal_salience_decays():
    from pulse.core.temporal import temporal_salience
    recent = datetime.now(timezone.utc).isoformat()
    old = (datetime.now(timezone.utc) - timedelta(days=10)).isoformat()
    assert temporal_salience(3.0, old) < temporal_salience(3.0, recent)


def test_temporal_salience_floor():
    from pulse.core.temporal import temporal_salience
    ancient = (datetime.now(timezone.utc) - timedelta(days=3650)).isoformat()
    assert temporal_salience(3.0, ancient) >= 0.1


def test_temporal_salience_fail_open():
    from pulse.core.temporal import temporal_salience
    assert temporal_salience(2.5, "bad-ts") == 2.5


def test_temporal_salience_half_life_param():
    from pulse.core.temporal import temporal_salience
    import inspect as ins2
    assert "half_life_hours" in ins2.signature(temporal_salience).parameters


def test_temporal_salience_math():
    from pulse.core.temporal import temporal_salience
    ts = (datetime.now(timezone.utc) - timedelta(hours=48)).isoformat()
    r = temporal_salience(2.0, ts, half_life_hours=48.0)
    assert 0.8 <= r <= 1.2, f"expected ~1.0, got {r}"


def test_temporal_salience_in_search_engine():
    import pulse.brain.brain_search.search_engine as mod
    assert "temporal_salience" in inspect.getsource(mod)


# ===== Item 10: Flashbulb memory =====

def test_flashbulb_source_present():
    import pulse.brain.save_writers.jsonl_store as mod
    src = inspect.getsource(mod.build_jsonl_entry)
    assert "flashbulb" in src.lower()
    assert "permanent" in src


def test_flashbulb_conditions():
    import pulse.brain.save_writers.jsonl_store as mod
    src = inspect.getsource(mod.build_jsonl_entry)
    assert "0.8" in src
    assert "3.0" in src
    assert "emotional_intensity" in src


def test_flashbulb_sets_permanent():
    import pulse.brain.save_writers.jsonl_store as mod
    src = inspect.getsource(mod.build_jsonl_entry)
    assert "permanent" in src
    assert "emotional_intensity" in src


def test_flashbulb_not_triggered_low_salience():
    from pulse.brain.save_writers.jsonl_store import build_jsonl_entry
    now = datetime.now(timezone.utc).isoformat()
    entry = build_jsonl_entry(
        "Minor helper refactor utility wrapper description text",
        "test", now, "code", 0.6, 1.0, "lesson")
    assert entry.get("validity") != "permanent"


def test_flashbulb_not_triggered_low_emotion():
    from pulse.brain.save_writers.jsonl_store import build_jsonl_entry
    now = datetime.now(timezone.utc).isoformat()
    entry = build_jsonl_entry(
        "Async retry backoff exponential pattern standard logic",
        "test", now, "arch", 0.8, 4.0, "pattern")
    assert entry.get("validity") != "permanent"


def test_flashbulb_fail_open():
    import pulse.brain.save_writers.jsonl_store as mod
    src = inspect.getsource(mod.build_jsonl_entry)
    assert "except Exception:" in src
