"""Session 79 — Catholic spiritual director / retreat master scenario tests.

Scenarios:
  S-SD-01 — Emmaus Road Lectio Divina
  S-SD-02 — Ignatian Contemplation: Woman at the Well
  S-SD-03 — Discernment of Spirits: Consolation vs Desolation
  S-SD-04 — Cloud of Unknowing: Moses Enters Darkness
  S-SD-05 — Carmelite Dark Night: Job, Song of Songs
  S-SD-06 — Benedictine Psalm 119 Vigils Meditatio
  S-SD-07 — Franciscan Creation Contemplation
  S-SD-08 — Eucharistic Adoration: Bread of Life
  S-SD-09 — Sacred Heart: Pierced Side (John 19:34)
  S-SD-10 — Marian Consecration: Totus Tuus
  S-SD-11 — Retreat Theme: Come Away and Rest
  S-SD-12 — Spiritual Accompaniment: Scrupulosity

All tests are skippable if required modules/network are not available.
Tests are concrete, callable, and <=15 lines each.
"""
from __future__ import annotations

import pytest


# =============================================================================
# IMPORT GUARDS — import everything with try/except, following project conventions
# =============================================================================

# --- Bible API (local cache for KJV, network for others) ---
try:
    from accordance_parser.bible_api import get_verse
    _has_bible_api = True
except Exception:
    _has_bible_api = False

# --- Morphology (local) ---
try:
    from accordance_parser.morphology import get_morphology
    _has_morphology = True
except Exception:
    _has_morphology = False

# --- Search tools (search_verses_by_term) ---
try:
    _has_search_tools = True
except Exception:
    _has_search_tools = False

# --- MCP server tools (depends on FastMCP/uvicorn) ---
_has_mcp = False
try:
    from accordance_mcp_server import (
        study_strongs_number,
        search_commentaries,
        find_cross_references,
        search_all,
    )
    _has_mcp = True
except Exception:
    pass


# =============================================================================
# NETWORK DETECTION
# =============================================================================

_has_network = False
try:
    from accordance_parser.bible_api import get_verse as _gv
    r = _gv("Genesis 1:1", "KJV")
    if r and r.text:
        _has_network = True
except Exception:
    pass


# =============================================================================
# HELPERS
# =============================================================================

def _str_ok(text: str) -> bool:
    """Return True if text is a non-empty string with no Python traceback."""
    if not isinstance(text, str):
        return False
    if not text.strip():
        return False
    if "Traceback (most recent call last)" in text:
        return False
    return True


# =============================================================================
# S-SD-01: EMMAUS ROAD LECTIO DIVINA
# =============================================================================

@pytest.mark.skipif(not _has_mcp, reason="MCP server not importable")
class TestEmmausRoadLectioDivina:
    """S-SD-01: Emmaus Road — Luke 24:13-35, lectio divina chain."""

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_luke_24_13_35(self):
        """Luke 24:13-35 NABRE — full Emmaus Road passage."""
        result = get_verse("Luke 24:13-35", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["emmaus", "eyes", "opened", "burning", "bread"])

    def test_search_all_heart_kardia(self):
        """search_all('heart kardia', max_results=10) should return cross-module results."""
        result = search_all("heart kardia", max_results=10)
        assert isinstance(result, str)
        assert len(result) > 0

    def test_study_G1272_dianoigo(self):
        """study_strongs_number('G1272') — dianoigo/'opened' in Luke 24:31."""
        result = study_strongs_number("G1272")
        assert _str_ok(result)
        assert "G1272" in result or "1272" in result or "def" in result.lower()

    def test_find_cross_refs_luke_24_32(self):
        """find_cross_references('Luke 24:32') — burning heart motif."""
        result = find_cross_references("Luke 24:32")
        assert isinstance(result, str)
        assert len(result) > 0

    def test_search_commentaries_luke_24_30(self):
        """search_commentaries('Luke 24:30') — Eucharistic recognition."""
        result = search_commentaries("Luke 24:30")
        assert isinstance(result, str)
        assert len(result) > 0


# =============================================================================
# S-SD-02: IGNATIAN CONTEMPLATION — WOMAN AT THE WELL
# =============================================================================

@pytest.mark.skipif(not _has_mcp, reason="MCP server not importable")
class TestWomanAtTheWell:
    """S-SD-02: Ignatian contemplation — John 4:1-42, water, OT well encounters."""

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_john_4_1_42(self):
        """John 4:1-42 NABRE — full pericope, Samaritan woman."""
        result = get_verse("John 4:1-42", "NABRE")
        assert result is not None and result.text
        assert len(result.text) > 20
        assert any(w in result.text.lower() for w in ["jesus", "pharisees", "baptizing", "disciples"])

    def test_search_all_water_john_4(self):
        """search_all('water', max_results=10) — water motif across modules."""
        result = search_all("water", max_results=10)
        assert isinstance(result, str)
        assert len(result) > 0

    @pytest.mark.skipif(not _has_morphology, reason="Morphology module not available")
    def test_morphology_john_4_7(self):
        """get_morphology('John 4:7') — 'give me a drink' grammar."""
        result = get_morphology("John 4:7")
        assert result is not None
        assert len(result) > 0

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_genesis_24_15_20(self):
        """Genesis 24:15-20 NABRE — Rebekah at the well."""
        result = get_verse("Genesis 24:15-20", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["rebekah", "water", "pitcher", "camels"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_genesis_29_9_12(self):
        """Genesis 29:9-12 NABRE — Rachel at the well."""
        result = get_verse("Genesis 29:9-12", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["rachel", "sheep", "water", "well", "stone"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_exodus_2_16_21(self):
        """Exodus 2:16-21 NABRE — Moses and Zipporah at the well."""
        result = get_verse("Exodus 2:16-21", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["priest", "midian", "daughters", "water", "moses", "zipporah"])

    def test_search_commentaries_john_4_7(self):
        """search_commentaries('John 4:7') should return commentary entries."""
        result = search_commentaries("John 4:7")
        assert isinstance(result, str)
        assert len(result) > 0


# =============================================================================
# S-SD-03: DISCERNMENT OF SPIRITS — CONSOLATION VS DESOLATION
# =============================================================================

@pytest.mark.skipif(not _has_mcp, reason="MCP server not importable")
class TestDiscernmentOfSpirits:
    """S-SD-03: Discernment — Romans 8, Galatians 5, 1 John 4, Psalm 42-43."""

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_romans_8_15_17(self):
        """Romans 8:15-17 NABRE — Spirit of adoption, not slavery."""
        result = get_verse("Romans 8:15-17", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["spirit", "adoption", "abba", "father", "children", "heir"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_romans_8_26_39(self):
        """Romans 8:26-39 NABRE — Spirit intercedes, nothing separates."""
        result = get_verse("Romans 8:26-39", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["spirit", "intercedes", "groan", "conqueror", "separate", "love"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_galatians_5_16_26(self):
        """Galatians 5:16-26 NABRE — flesh vs Spirit, fruit of the Spirit."""
        result = get_verse("Galatians 5:16-26", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["spirit", "flesh", "fruit", "love", "joy", "peace"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_1john_4_1_6(self):
        """1 John 4:1-6 NABRE — test the spirits."""
        result = get_verse("1 John 4:1-6", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["spirit", "test", "false", "prophet", "antichrist"])

    def test_search_all_spiritual_warfare(self):
        """search_all('spiritual warfare', max_results=10) — Eph 6, 1 Pet 5, James 4."""
        result = search_all("spiritual warfare", max_results=10)
        assert isinstance(result, str)
        assert len(result) > 0

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_psalm_42_1_5(self):
        """Psalm 42:1-5 NABRE — 'as the deer longs' — lament."""
        result = get_verse("Psalm 42:1-5", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["deer", "soul", "thirsts", "tears", "leader"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_psalm_43_3_5(self):
        """Psalm 43:3-5 NABRE — lament-to-trust, 'hope in God'."""
        result = get_verse("Psalm 43:3-5", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["light", "truth", "altar", "hope", "god"])


# =============================================================================
# S-SD-04: CLOUD OF UNKNOWING — MOSES ENTERS DARKNESS
# =============================================================================

@pytest.mark.skipif(not _has_mcp, reason="MCP server not importable")
class TestCloudOfUnknowing:
    """S-SD-04: Cloud of Unknowing — Exodus 33-34, 1 Kings 19, apophatic theology."""

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_exodus_33_18_23(self):
        """Exodus 33:18-23 NABRE — 'show me your glory', cleft of the rock."""
        result = get_verse("Exodus 33:18-23", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["glory", "back", "face", "rock", "goodness", "cleft"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_exodus_34_5_8(self):
        """Exodus 34:5-8 NABRE — Lord descends in cloud, proclaims name."""
        result = get_verse("Exodus 34:5-8", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["cloud", "lord", "mercy", "gracious", "bowed"])

    def test_search_all_cloud_darkness_presence(self):
        """search_all('cloud darkness God presence', max_results=10) across OT."""
        result = search_all("cloud darkness God presence", max_results=10)
        assert isinstance(result, str)
        assert len(result) > 0

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_1kings_19_11_13(self):
        """1 Kings 19:11-13 NABRE — still small voice."""
        result = get_verse("1 Kings 19:11-13", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["whisper", "wind", "earthquake", "fire", "lord", "cave"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_john_1_18(self):
        """John 1:18 NABRE — 'No one has ever seen God'."""
        result = get_verse("John 1:18", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["seen", "god", "son", "bosom", "revealed"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_1timothy_6_16(self):
        """1 Timothy 6:16 NABRE — 'dwells in unapproachable light'."""
        result = get_verse("1 Timothy 6:16", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["immortality", "light", "unapproachable", "seen", "honor"])


# =============================================================================
# S-SD-05: CARMELITE DARK NIGHT — JOB, SONG OF SONGS
# =============================================================================

@pytest.mark.skipif(not _has_mcp, reason="MCP server not importable")
class TestCarmeliteDarkNight:
    """S-SD-05: Dark Night — Job 23, Song of Songs 3/5, Psalm 42, gold refining."""

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_job_23_1_10(self):
        """Job 23:1-10 NABRE — 'he knows the way I take', gold refining."""
        result = get_verse("Job 23:1-10", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["job", "answered", "gold", "test", "way"])

    def test_study_H974_bachan(self):
        """study_strongs_number('H974') — bachan/test/reveal in Job 23:10."""
        result = study_strongs_number("H974")
        assert _str_ok(result)
        assert "H974" in result or "974" in result or "def" in result.lower()

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_song_of_songs_3_1_4(self):
        """Song of Songs 3:1-4 NABRE — 'I sought him whom my soul loves'."""
        result = get_verse("Song of Songs 3:1-4", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["sought", "soul", "bed", "night", "found"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_song_of_songs_5_2_8(self):
        """Song of Songs 5:2-8 NABRE — nocturnal seeking, withdrawal, wounding."""
        result = get_verse("Song of Songs 5:2-8", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["sleep", "heart", "awake", "beloved", "sought"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_psalm_42_1_5(self):
        """Psalm 42:1-5 NABRE — refrain chain, 'why are you cast down'."""
        result = get_verse("Psalm 42:1-5", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["deer", "soul", "cast", "hope", "leader"])

    def test_search_all_night_seek_soul(self):
        """search_all('night seek soul', max_results=10) across Wisdom/Poetry."""
        result = search_all("night seek soul", max_results=10)
        assert isinstance(result, str)
        assert len(result) > 0


# =============================================================================
# S-SD-06: BENEDICTINE PSALM 119 VIGILS MEDITATIO
# =============================================================================

@pytest.mark.skipif(not _has_mcp, reason="MCP server not importable")
class TestBenedictinePsalm119:
    """S-SD-06: Benedictine vigils — Psalm 119, beatitude chain, torah."""

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_psalm_119_1_8(self):
        """Psalm 119:1-8 NABRE — 'Blessed are those whose way is blameless'."""
        result = get_verse("Psalm 119:1-8", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["blessed", "blameless", "law", "lord", "ways"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_psalm_119_105(self):
        """Psalm 119:105 NABRE — 'a lamp to my feet, a light to my path'."""
        result = get_verse("Psalm 119:105", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["lamp", "feet", "light", "path", "word"])

    def test_search_all_blessed_are_psalms(self):
        """search_all('blessed are those who', max_results=10) across Psalms."""
        result = search_all("blessed are those who", max_results=10)
        assert isinstance(result, str)
        assert len(result) > 0

    def test_study_H8451_torah(self):
        """study_strongs_number('H8451') — torah/law."""
        result = study_strongs_number("H8451")
        assert _str_ok(result)
        assert "H8451" in result or "8451" in result or "def" in result.lower()

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_psalm_1_1_2(self):
        """Psalm 1:1-2 NABRE — beatitude chain: 'blessed is the man'."""
        result = get_verse("Psalm 1:1-2", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["blessed", "wicked", "law", "meditates", "day", "night"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_psalm_32_1_2(self):
        """Psalm 32:1-2 NABRE — beatitude chain: 'blessed is he whose transgression is forgiven'."""
        result = get_verse("Psalm 32:1-2", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["blessed", "forgiven", "transgression", "sin", "guile"])

    def test_search_commentaries_psalm_119_1(self):
        """search_commentaries('Psalm 119:1') should return commentary entries."""
        result = search_commentaries("Psalm 119:1")
        assert isinstance(result, str)
        assert len(result) > 0


# =============================================================================
# S-SD-07: FRANCISCAN CREATION CONTEMPLATION
# =============================================================================

@pytest.mark.skipif(not _has_mcp, reason="MCP server not importable")
class TestFranciscanCreation:
    """S-SD-07: Franciscan contemplation — Genesis 1, Daniel 3, Psalm 148, Matthew 6, Romans 8."""

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_genesis_1_1_31(self):
        """Genesis 1:1-31 NABRE — creation account."""
        result = get_verse("Genesis 1:1-31", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["beginning", "god", "created", "heavens", "earth", "good"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_daniel_3_57_82(self):
        """Daniel 3:57-82 NABRE — Benedicite canticle, all creation blesses the Lord."""
        result = get_verse("Daniel 3:57-82", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["bless", "lord", "angels", "heavens", "waters", "sun"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_psalm_148_1_14(self):
        """Psalm 148:1-14 NABRE — all creation praises the Lord."""
        result = get_verse("Psalm 148:1-14", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["praise", "lord", "heavens", "angels", "sun", "moon", "stars"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_matthew_6_26_30(self):
        """Matthew 6:26-30 NABRE — birds of the air, lilies of the field."""
        result = get_verse("Matthew 6:26-30", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["birds", "sky", "lilies", "field", "splendor", "faith"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_romans_8_19_23(self):
        """Romans 8:19-23 NABRE — creation groaning, awaiting redemption."""
        result = get_verse("Romans 8:19-23", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["creation", "groan", "eager", "bondage", "redemption"])

    def test_search_all_heavens_declare(self):
        """search_all('heavens declare', max_results=10) across Psalms."""
        result = search_all("heavens declare", max_results=10)
        assert isinstance(result, str)
        assert len(result) > 0


# =============================================================================
# S-SD-08: EUCHARISTIC ADORATION — BREAD OF LIFE
# =============================================================================

@pytest.mark.skipif(not _has_mcp, reason="MCP server not importable")
class TestEucharisticAdoration:
    """S-SD-08: Eucharistic Adoration — John 6, manna typology, 'I am', institution."""

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_john_6_22_71(self):
        """John 6:22-71 NABRE — full Bread of Life discourse."""
        result = get_verse("John 6:22-71", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["jesus", "bread", "boat", "disciples", "sea", "crowd"])

    def test_study_G5176_trogo(self):
        """study_strongs_number('G5176') — trogo/gnaw in John 6:54-58."""
        result = study_strongs_number("G5176")
        assert _str_ok(result)
        assert "G5176" in result or "5176" in result or "def" in result.lower()

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_exodus_16_4_15(self):
        """Exodus 16:4-15 NABRE — manna typology."""
        result = get_verse("Exodus 16:4-15", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["bread", "heaven", "manna", "wilderness", "quail"])

    def test_search_all_i_am_john(self):
        """search_all('I am', max_results=10) — 'I am' sayings in John."""
        result = search_all("I am", max_results=10)
        assert isinstance(result, str)
        assert len(result) > 0

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_1cor_11_23_26(self):
        """1 Corinthians 11:23-26 NABRE — institution of the Eucharist."""
        result = get_verse("1 Corinthians 11:23-26", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["lord", "jesus", "bread", "night", "received", "handed"])


# =============================================================================
# S-SD-09: SACRED HEART — PIERCED SIDE (JOHN 19:34)
# =============================================================================

@pytest.mark.skipif(not _has_mcp, reason="MCP server not importable")
class TestSacredHeart:
    """S-SD-09: Sacred Heart — John 19:34, Zechariah 12-13, Ezekiel 36, contrite heart."""

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_john_19_31_37(self):
        """John 19:31-37 NABRE — pierced side, blood and water."""
        result = get_verse("John 19:31-37", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["pierced", "side", "blood", "water", "bone", "broken"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_zechariah_12_10(self):
        """Zechariah 12:10 NABRE — 'they will look on him whom they have pierced'."""
        result = get_verse("Zechariah 12:10", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["pierced", "spirit", "mourn", "grace", "supplication"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_zechariah_13_1(self):
        """Zechariah 13:1 NABRE — fountain opened for sin and uncleanness."""
        result = get_verse("Zechariah 13:1", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["fountain", "sin", "uncleanness", "house", "david"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_ezekiel_36_25_27(self):
        """Ezekiel 36:25-27 NABRE — clean water, new heart, new spirit."""
        result = get_verse("Ezekiel 36:25-27", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["water", "clean", "heart", "spirit", "stone", "flesh"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_psalm_34_18(self):
        """Psalm 34:18 NABRE — 'Lord is close to the brokenhearted'."""
        result = get_verse("Psalm 34:18", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["righteous", "lord", "cry", "afflictions", "rescues", "hears"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_psalm_51_17(self):
        """Psalm 51:17 NABRE — 'a contrite, humbled heart, O God, you will not scorn'."""
        result = get_verse("Psalm 51:17", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["lord", "lips", "mouth", "praise"])

    def test_search_all_mercy_heart(self):
        """search_all('mercy heart', max_results=10) across Psalms/Gospels."""
        result = search_all("mercy heart", max_results=10)
        assert isinstance(result, str)
        assert len(result) > 0


# =============================================================================
# S-SD-10: MARIAN CONSECRATION — TOTUS TUUS
# =============================================================================

@pytest.mark.skipif(not _has_mcp, reason="MCP server not importable")
class TestMarianConsecration:
    """S-SD-10: Marian Consecration — John 19:25-27, protoevangelium, Magnificat, Revelation 12."""

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_john_19_25_27(self):
        """John 19:25-27 NABRE — 'Behold your mother'."""
        result = get_verse("John 19:25-27", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["mother", "disciple", "behold", "son", "woman"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_genesis_3_15(self):
        """Genesis 3:15 NABRE — protoevangelium, enmity between woman and serpent."""
        result = get_verse("Genesis 3:15", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["enmity", "woman", "serpent", "offspring", "crush", "heel"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_luke_1_26_38(self):
        """Luke 1:26-38 NABRE — Annunciation."""
        result = get_verse("Luke 1:26-38", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["gabriel", "mary", "virgin", "spirit", "handmaid", "overshadow"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_luke_1_39_56(self):
        """Luke 1:39-56 NABRE — Visitation and Magnificat."""
        result = get_verse("Luke 1:39-56", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["mary", "judah", "traveled", "haste", "blessed"])

    def test_search_all_woman_john(self):
        """search_all('woman', max_results=10) — gyne across John's Gospel."""
        result = search_all("woman", max_results=10)
        assert isinstance(result, str)
        assert len(result) > 0

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_revelation_12_1_6(self):
        """Revelation 12:1-6 NABRE — woman clothed with the sun."""
        result = get_verse("Revelation 12:1-6", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["woman", "sun", "moon", "crown", "stars", "dragon", "child"])

    def test_search_commentaries_john_19_26(self):
        """search_commentaries('John 19:26') — 'Behold your mother' commentary."""
        result = search_commentaries("John 19:26")
        assert isinstance(result, str)
        assert len(result) > 0


# =============================================================================
# S-SD-11: RETREAT THEME — COME AWAY AND REST
# =============================================================================

@pytest.mark.skipif(not _has_mcp, reason="MCP server not importable")
class TestComeAwayAndRest:
    """S-SD-11: Retreat theme — Mark 6, Matthew 11:28-30, Psalm 23, Exodus 33:14, Hebrews 4."""

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_mark_6_30_32(self):
        """Mark 6:30-32 NABRE — 'Come away... and rest a while'."""
        result = get_verse("Mark 6:30-32", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["away", "rest", "deserted", "apostles", "quiet"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_matthew_11_28_30(self):
        """Matthew 11:28-30 NABRE — 'Come to me... I will give you rest'."""
        result = get_verse("Matthew 11:28-30", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["labor", "burdened", "rest", "yoke", "meek", "humble"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_psalm_23_1_3(self):
        """Psalm 23:1-3 NABRE — 'The Lord is my shepherd... green pastures... restful waters'."""
        result = get_verse("Psalm 23:1-3", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["shepherd", "pastures", "water", "rest", "soul"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_exodus_33_14(self):
        """Exodus 33:14 NABRE — 'My presence will go with you, and I will give you rest'."""
        result = get_verse("Exodus 33:14", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["presence", "rest", "go", "face"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_hebrews_4_1_11(self):
        """Hebrews 4:1-11 NABRE — Sabbath rest for the people of God."""
        result = get_verse("Hebrews 4:1-11", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["rest", "sabbath", "promise", "enter", "works"])

    def test_search_all_desert_rest(self):
        """search_all('desert rest', max_results=10) across Pentateuch."""
        result = search_all("desert rest", max_results=10)
        assert isinstance(result, str)
        assert len(result) > 0


# =============================================================================
# S-SD-12: SPIRITUAL ACCOMPANIMENT — SCRUPULOSITY
# =============================================================================

@pytest.mark.skipif(not _has_mcp, reason="MCP server not importable")
class TestScrupulosity:
    """S-SD-12: Scrupulosity — Romans 8, 1 John 3, Psalm 103, John 8, forgiveness chain."""

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_romans_8_1_4(self):
        """Romans 8:1-4 NABRE — 'no condemnation for those in Christ Jesus'."""
        result = get_verse("Romans 8:1-4", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["condemnation", "spirit", "life", "flesh", "sin", "law"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_1john_3_19_20(self):
        """1 John 3:19-20 NABRE — 'God is greater than our hearts'."""
        result = get_verse("1 John 3:19-20", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["heart", "god", "greater", "condemns", "knows"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_psalm_103_8_14(self):
        """Psalm 103:8-14 NABRE — 'as far as the east is from the west'."""
        result = get_verse("Psalm 103:8-14", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["mercy", "gracious", "east", "west", "transgression", "dust", "children"])

    @pytest.mark.skipif(not _has_network, reason="Requires network for NABRE")
    def test_nabre_john_8_1_11(self):
        """John 8:1-11 NABRE — woman caught in adultery, 'neither do I condemn you'."""
        result = get_verse("John 8:1-11", "NABRE")
        assert result is not None and result.text
        assert any(w in result.text.lower() for w in ["jesus", "house", "went", "adultery", "woman"])

    def test_search_all_forgive_transgression(self):
        """search_all('forgive transgression', max_results=10) across Prophets."""
        result = search_all("forgive transgression", max_results=10)
        assert isinstance(result, str)
        assert len(result) > 0

    def test_search_commentaries_romans_8_1(self):
        """search_commentaries('Romans 8:1') should return commentary entries."""
        result = search_commentaries("Romans 8:1")
        assert isinstance(result, str)
        assert len(result) > 0
