"""Tests for 12 Catholic priest scenario workflows — Session 78.

S-FUN-01 through S-CRE-12: covers funeral homily prep (deuterocanonical),
wedding homily (covenant theology), baptism catechesis, first communion
catechesis, Ignatian Examen (Lukan mercy), Stations of the Cross (OT
prefigurement), examination of conscience (Decalogue + Beatitudes),
Holy Spirit novena (Confirmation prep), parish Lenten mission,
prison ministry, parish social justice (encyclical scripture), and
RCIA Apostles' Creed through scripture.

Each scenario tests a multi-tool workflow a Catholic priest would use
in pastoral ministry. Tests verify that tools work together (don't
crash, return expected types) rather than verify specific theological
content.
"""
from __future__ import annotations

import pytest


# =============================================================================
# IMPORT GUARDS — import everything with try/except
# =============================================================================

# --- Canon (local only, always available) ---
try:
    from accordance_parser.canon import (
        parse_reference, resolve_book, CANON_CATHOLIC, chapter_count,
    )
    _has_canon = True
except Exception:
    _has_canon = False

# --- Bible API ---
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, describe_robinson, describe_hebrew_morph,
    )
    _has_morphology = True
except Exception:
    _has_morphology = False

# --- MCP server tools ---
_has_mcp = False
_mcp_import_error = ""
try:
    from accordance_mcp_server import (
        study_strongs_number,
        search_commentaries,
        compare_translations,
        search_all,
    )
    _has_mcp = True
except Exception as e:
    _mcp_import_error = str(e)

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

# --- Strong's search tools ---
try:
    _has_strongs_tools = True
except Exception:
    _has_strongs_tools = False

# --- Acc2 tools ---
try:
    _has_acc2 = True
except Exception:
    _has_acc2 = False

# --- Multi-tools ---
try:
    _has_multi_tools = True
except Exception:
    _has_multi_tools = False

# --- Network detection ---
_has_network = False
if _has_bible_api:
    try:
        r = get_verse("Genesis 1:1", "KJV")
        if r and r.text:
            _has_network = True
    except Exception:
        pass


# =============================================================================
# HELPER
# =============================================================================

def _no_traceback(text: str) -> bool:
    """Ensure the text does not contain a Python traceback."""
    return "Traceback (most recent call last)" not in text


# =============================================================================
# S-FUN-01: Funeral Homily for a Devotee of the Rosary
# =============================================================================

@pytest.mark.skipif(not _has_network, reason="Requires network")
class TestSFun01FuneralHomily:
    """S-FUN-01: Funeral homily — Wisdom 3, Proverbs 31, Revelation 21, John 14."""

    def test_wisdom_3_1_9_nabre(self):
        """Step 1: Wisdom 3:1-9 NABRE — souls of the just."""
        vr = get_verse("Wisdom 3:1-9", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_compare_translations_wisdom_3_1_esv_fallback(self):
        """Step 2: compare_translations Wisdom 3:1 — ESV lacks Wisdom, verify fallback."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = compare_translations("Wisdom 3:1", "NABRE,RSVCE,ESV,KJV")
        assert isinstance(result, str) and len(result) > 20
        assert _no_traceback(result)
        # ESV should show em-dash or fallback marker for absence
        # NABRE and RSVCE should have content

    def test_search_commentaries_wisdom_3(self):
        """Step 3: search_commentaries on Wisdom 3 — Catholic SB-3, JFB."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = search_commentaries("Wisdom 3:1")
        assert isinstance(result, str) and len(result) > 10
        assert _no_traceback(result)

    def test_proverbs_31_10_31_nabre(self):
        """Step 4a: Proverbs 31:10-31 NABRE — virtuous woman."""
        vr = get_verse("Proverbs 31:10-31", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_revelation_21_1_7_nabre(self):
        """Step 4b: Revelation 21:1-7 NABRE — new heaven and new earth."""
        vr = get_verse("Revelation 21:1-7", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_john_14_1_6_nabre(self):
        """Step 4c: John 14:1-6 NABRE."""
        vr = get_verse("John 14:1-6", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_strongs_g1515_eirene(self):
        """Step 5: study_strongs_number G1515 (eirene/peace)."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = study_strongs_number("G1515")
        assert isinstance(result, str) and len(result) > 20
        assert _no_traceback(result)

    def test_fts5_wisdom_deuterocanonical(self):
        """Step 6: FTS5 search for 'Wisdom' content — verify deuterocanonical index."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = search_all("Wisdom", max_results=10)
        assert isinstance(result, str) and len(result) > 5
        assert _no_traceback(result)


# =============================================================================
# S-WED-02: Wedding Homily — Covenantal Theology Chain
# =============================================================================

@pytest.mark.skipif(not _has_network, reason="Requires network")
class TestSWed02WeddingHomily:
    """S-WED-02: Wedding homily — Genesis, Hosea, Song of Songs, Ephesians, John."""

    def test_genesis_2_18_24_nabre(self):
        """Step 1a: Genesis 2:18-24 NABRE."""
        vr = get_verse("Genesis 2:18-24", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_hosea_2_19_20_nabre(self):
        """Step 1b: Hosea 2:19-20 NABRE."""
        vr = get_verse("Hosea 2:19-20", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_compare_hosea_2_19(self):
        """Step 2: compare_translations Hosea 2:19 NABRE, RSVCE, KJVS."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = compare_translations("Hosea 2:19", "NABRE,RSVCE,KJV")
        assert isinstance(result, str) and len(result) > 20
        assert _no_traceback(result)

    def test_hebrew_morphology_hosea_2_19(self):
        """Step 3: get_morphology for Hosea 2:19 — betroth (ארש)."""
        if not _has_morphology:
            pytest.skip("Morphology not available")
        entries = get_morphology("Hosea 2:19")
        assert isinstance(entries, list)
        # Should return morphology entries even if OT module isn't loaded locally;
        # graceful empty list is acceptable

    def test_song_of_songs_8_6_7_nabre(self):
        """Step 4a: Song of Songs 8:6-7 NABRE."""
        vr = get_verse("Song of Songs 8:6-7", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_ephesians_5_25_33_nabre(self):
        """Step 4b: Ephesians 5:25-33 NABRE."""
        vr = get_verse("Ephesians 5:25-33", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_strongs_g25_agapao(self):
        """Step 5: study_strongs_number G25 (agapao/love)."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = study_strongs_number("G25")
        assert isinstance(result, str) and len(result) > 20
        assert _no_traceback(result)

    def test_thayer_lexicon_g25(self):
        """Step 6: study_strongs_number G25 covers Thayer lexicon."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = study_strongs_number("G25")
        assert isinstance(result, str) and len(result) > 20
        # study_strongs_number searches all available lexicons including Thayer
        assert "G25" in result or "G0025" in result

    def test_john_15_12_17_nabre(self):
        """Step 7: John 15:12-17 NABRE."""
        vr = get_verse("John 15:12-17", "NABRE")
        assert vr is not None and len(vr.text) > 20


# =============================================================================
# S-BAP-03: Baptism Preparation Catechesis
# =============================================================================

@pytest.mark.skipif(not _has_network, reason="Requires network")
class TestSBap03BaptismCatechesis:
    """S-BAP-03: Baptism prep — Genesis, Exodus, Ezekiel, NT baptism chain."""

    def test_genesis_1_2_nabre(self):
        """Step 1a: Genesis 1:2 NABRE — Spirit over waters."""
        vr = get_verse("Genesis 1:2", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_genesis_7_17_24_nabre(self):
        """Step 1b: Genesis 7:17-24 — flood waters."""
        vr = get_verse("Genesis 7:17-24", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_fts5_water_in_exodus(self):
        """Step 2: search_all 'water' scoped to Exodus book."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = search_all("water Exodus", max_results=10)
        assert isinstance(result, str) and len(result) > 5
        assert _no_traceback(result)

    def test_exodus_14_21_31_nabre(self):
        """Step 3: Exodus 14:21-31 NABRE — Red Sea crossing."""
        vr = get_verse("Exodus 14:21-31", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_ezekiel_36_25_27_nabre(self):
        """Step 4: Ezekiel 36:25-27 NABRE — water and new heart."""
        vr = get_verse("Ezekiel 36:25-27", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_compare_ezekiel_36_25(self):
        """Step 5: compare_translations for Ezekiel 36:25."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = compare_translations("Ezekiel 36:25", "NABRE,RSVCE,KJV,ESV")
        assert isinstance(result, str) and len(result) > 20
        assert _no_traceback(result)

    def test_hebrew_morphology_ezekiel_36_25(self):
        """Step 6: get_morphology for Ezekiel 36:25 — sprinkle/zarak."""
        if not _has_morphology:
            pytest.skip("Morphology not available")
        entries = get_morphology("Ezekiel 36:25")
        assert isinstance(entries, list)

    def test_baptism_chain_mark_1_9_11(self):
        """Step 7a: Mark 1:9-11 NABRE — Jesus' baptism."""
        vr = get_verse("Mark 1:9-11", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_baptism_chain_romans_6_3_4(self):
        """Step 7b: Romans 6:3-4 NABRE — baptized into Christ's death."""
        vr = get_verse("Romans 6:3-4", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_baptism_chain_1peter_3_20_22(self):
        """Step 7c: 1 Peter 3:20-22 NABRE — baptism through water."""
        vr = get_verse("1 Peter 3:20-22", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_baptism_chain_titus_3_5(self):
        """Step 7d: Titus 3:5 NABRE — washing of regeneration."""
        vr = get_verse("Titus 3:5", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_baptism_chain_john_3_5(self):
        """Step 7e: John 3:5 NABRE — born of water and Spirit."""
        vr = get_verse("John 3:5", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_strongs_g3067_loutron(self):
        """Step 8: study_strongs_number G3067 (washing/laver in Titus 3:5)."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = study_strongs_number("G3067")
        assert isinstance(result, str) and len(result) > 10
        assert _no_traceback(result)


# =============================================================================
# S-COM-04: First Communion Catechesis
# =============================================================================

@pytest.mark.skipif(not _has_network, reason="Requires network")
class TestSCom04FirstCommunion:
    """S-COM-04: First Communion catechesis — Exodus, 1 Kings, John 6, 1 Corinthians."""

    def test_exodus_12_1_14_nabre(self):
        """Step 1a: Exodus 12:1-14 — Passover institution."""
        vr = get_verse("Exodus 12:1-14", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_exodus_16_4_15_nabre(self):
        """Step 1b: Exodus 16:4-15 — manna in the wilderness."""
        vr = get_verse("Exodus 16:4-15", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_1kings_19_4_8_nabre(self):
        """Step 2: 1 Kings 19:4-8 — Elijah fed by angel."""
        vr = get_verse("1 Kings 19:4-8", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_compare_1kings_19_6(self):
        """Step 3: compare_translations 1 Kings 19:6."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = compare_translations("1 Kings 19:6", "NABRE,RSVCE,KJV")
        assert isinstance(result, str) and len(result) > 20
        assert _no_traceback(result)

    def test_john_6_35_58_nabre(self):
        """Step 4: John 6:35-58 NABRE — extended Bread of Life discourse."""
        vr = get_verse("John 6:35-58", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_greek_morphology_john_6_54_trogo(self):
        """Step 5: get_morphology for John 6:54 — 'eats' (trogo)."""
        if not _has_morphology:
            pytest.skip("Morphology not available")
        entries = get_morphology("John 6:54")
        assert isinstance(entries, list)
        if len(entries) > 0:
            entry = entries[0]
            assert hasattr(entry, "word") or hasattr(entry, "lemma")

    def test_strongs_g740_artos(self):
        """Step 6a: study_strongs_number G740 (artos/bread)."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = study_strongs_number("G740")
        assert isinstance(result, str) and len(result) > 20
        assert _no_traceback(result)

    def test_strongs_g5176_trogo(self):
        """Step 6b: study_strongs_number G5176 (trogo/gnaw)."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = study_strongs_number("G5176")
        assert isinstance(result, str) and len(result) > 10
        assert _no_traceback(result)

    def test_1corinthians_11_23_29_nabre(self):
        """Step 7: 1 Corinthians 11:23-29 NABRE — Last Supper institution."""
        vr = get_verse("1 Corinthians 11:23-29", "NABRE")
        assert vr is not None and len(vr.text) > 30


# =============================================================================
# S-EXA-05: Ignatian Examen — Lukan Mercy
# =============================================================================

@pytest.mark.skipif(not _has_network, reason="Requires network")
class TestSExa05IgnatianExamen:
    """S-EXA-05: Ignatian Examen — Psalm 51, Luke 7, 15, 18, 19, 23."""

    def test_psalm_51_3_19_nabre(self):
        """Step 1a: Psalm 51:3-19 — Miserere."""
        vr = get_verse("Psalm 51:3-19", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_luke_7_36_50_nabre(self):
        """Step 1b: Luke 7:36-50 — sinful woman forgiven."""
        vr = get_verse("Luke 7:36-50", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_luke_15_11_32_nabre(self):
        """Step 2: Luke 15:11-32 NABRE — full Prodigal Son."""
        vr = get_verse("Luke 15:11-32", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_mercy_chain_luke_18_9_14(self):
        """Step 3a: Luke 18:9-14 — Pharisee and tax collector."""
        vr = get_verse("Luke 18:9-14", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_mercy_chain_luke_19_1_10(self):
        """Step 3b: Luke 19:1-10 — Zacchaeus."""
        vr = get_verse("Luke 19:1-10", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_mercy_chain_luke_23_39_43(self):
        """Step 3c: Luke 23:39-43 — penitent thief."""
        vr = get_verse("Luke 23:39-43", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_compare_luke_15_17(self):
        """Step 4: compare_translations Luke 15:17 NABRE vs KJV."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = compare_translations("Luke 15:17", "NABRE,KJV")
        assert isinstance(result, str) and len(result) > 20
        assert _no_traceback(result)

    def test_greek_morphology_luke_15_17(self):
        """Step 5: get_morphology for Luke 15:17 — 'came to his senses'."""
        if not _has_morphology:
            pytest.skip("Morphology not available")
        entries = get_morphology("Luke 15:17")
        assert isinstance(entries, list)

    def test_greek_morphology_luke_15_18(self):
        """Step 6: get_morphology for Luke 15:18 — 'I will arise' (anastas)."""
        if not _has_morphology:
            pytest.skip("Morphology not available")
        entries = get_morphology("Luke 15:18")
        assert isinstance(entries, list)

    def test_search_commentaries_luke_15(self):
        """Step 7: search_commentaries on Luke 15:11-32 — JFB, Clarke."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = search_commentaries("Luke 15:11")
        assert isinstance(result, str) and len(result) > 10
        assert _no_traceback(result)


# =============================================================================
# S-STA-06: Stations of the Cross — OT Prefigurement
# =============================================================================

@pytest.mark.skipif(not _has_network, reason="Requires network")
class TestSSta06StationsOT:
    """S-STA-06: Stations — Isaiah 53, Genesis 22, Psalm 22, Zechariah, Wisdom."""

    def test_isaiah_53_8_nabre(self):
        """Step 1: Isaiah 53:8 NABRE — Station 1 (condemned)."""
        vr = get_verse("Isaiah 53:8", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_genesis_22_6_nabre(self):
        """Step 2: Genesis 22:6 — Station 2 (Isaac carries wood)."""
        vr = get_verse("Genesis 22:6", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_fts5_pierce_ot(self):
        """Step 3: search_all 'pierce' in OT scope."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = search_all("pierce", max_results=10)
        assert isinstance(result, str) and len(result) > 5
        assert _no_traceback(result)

    def test_lxx_vs_mt_zechariah_12_10(self):
        """Step 4: compare_translations Zechariah 12:10 — LXX vs MT rendering."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = compare_translations("Zechariah 12:10", "NABRE,KJV,ESV")
        assert isinstance(result, str) and len(result) > 20
        assert _no_traceback(result)

    def test_psalm_22_16_18_nabre(self):
        """Step 5a: Psalm 22:16-18 NABRE — 'pierced my hands and feet'."""
        vr = get_verse("Psalm 22:16-18", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_zechariah_12_10_nabre(self):
        """Step 5b: Zechariah 12:10 NABRE — 'they shall look on him whom they pierced'."""
        vr = get_verse("Zechariah 12:10", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_wisdom_2_12_20_nabre(self):
        """Step 6: Wisdom 2:12-20 NABRE — deuterocanonical passion prefigurement."""
        vr = get_verse("Wisdom 2:12-20", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_jonah_2_1_7_nabre(self):
        """Step 7: Jonah 2:1-7 NABRE — Station 14 type (three days in the fish)."""
        vr = get_verse("Jonah 2:1-7", "NABRE")
        assert vr is not None and len(vr.text) > 10


# =============================================================================
# S-CON-07: Examination of Conscience — Decalogue + Beatitudes
# =============================================================================

@pytest.mark.skipif(not _has_network, reason="Requires network")
class TestSCon07ExaminationConscience:
    """S-CON-07: Examination of conscience — Exodus 20, Matthew 5, 25, James 3."""

    def test_exodus_20_1_17_nabre(self):
        """Step 1a: Exodus 20:1-17 — Decalogue."""
        vr = get_verse("Exodus 20:1-17", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_matthew_5_1_12_nabre(self):
        """Step 1b: Matthew 5:1-12 — Beatitudes."""
        vr = get_verse("Matthew 5:1-12", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_greek_morphology_matthew_5_3(self):
        """Step 2: get_morphology for Matthew 5:3 — makarios (blessed)."""
        if not _has_morphology:
            pytest.skip("Morphology not available")
        entries = get_morphology("Matthew 5:3")
        assert isinstance(entries, list)

    def test_matthew_5_21_24_nabre(self):
        """Step 3a: Matthew 5:21-24 — 'You have heard it said...'"""
        vr = get_verse("Matthew 5:21-24", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_matthew_5_27_30_nabre(self):
        """Step 3b: Matthew 5:27-30 — 'You have heard it said...'"""
        vr = get_verse("Matthew 5:27-30", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_compare_exodus_20_13(self):
        """Step 4: compare_translations Exodus 20:13 — kill vs murder."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = compare_translations("Exodus 20:13", "KJV,ESV,NASB,NABRE")
        assert isinstance(result, str) and len(result) > 20
        assert _no_traceback(result)

    def test_matthew_25_31_46_nabre(self):
        """Step 5: Matthew 25:31-46 — sheep and goats."""
        vr = get_verse("Matthew 25:31-46", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_james_3_5_10_nabre(self):
        """Step 6: James 3:5-10 — the tongue."""
        vr = get_verse("James 3:5-10", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_fts5_tongue_in_proverbs(self):
        """Step 7: search_all 'tongue' in Proverbs."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = search_all("tongue Proverbs", max_results=10)
        assert isinstance(result, str) and len(result) > 5
        assert _no_traceback(result)

    def test_strongs_g3107_makarios(self):
        """Step 8a: study_strongs_number G3107 (makarios/blessed)."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = study_strongs_number("G3107")
        assert isinstance(result, str) and len(result) > 10
        assert _no_traceback(result)

    def test_strongs_h7523_ratsach(self):
        """Step 8b: study_strongs_number H7523 (ratsach/murder)."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = study_strongs_number("H7523")
        assert isinstance(result, str) and len(result) > 10
        assert _no_traceback(result)


# =============================================================================
# S-NOV-08: Holy Spirit Novena — Confirmation Prep
# =============================================================================

@pytest.mark.skipif(not _has_network, reason="Requires network")
class TestSNov08HolySpiritNovena:
    """S-NOV-08: Holy Spirit novena — Isaiah 11, gifts chain, John 14, Acts 2."""

    def test_isaiah_11_1_3_nabre(self):
        """Step 1: Isaiah 11:1-3 — seven gifts of the Holy Spirit."""
        vr = get_verse("Isaiah 11:1-3", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_gifts_chain_1kings_3_5_14(self):
        """Step 2a: 1 Kings 3:5-14 — Solomon's wisdom."""
        vr = get_verse("1 Kings 3:5-14", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_gifts_chain_luke_24_25_32(self):
        """Step 2b: Luke 24:25-32 — understanding on Emmaus road."""
        vr = get_verse("Luke 24:25-32", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_gifts_chain_acts_15_28(self):
        """Step 2c: Acts 15:28 — counsel of the Holy Spirit."""
        vr = get_verse("Acts 15:28", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_gifts_chain_acts_7_54_60(self):
        """Step 2d: Acts 7:54-60 — fortitude of Stephen."""
        vr = get_verse("Acts 7:54-60", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_gifts_chain_philippians_3_8_10(self):
        """Step 2e: Philippians 3:8-10 — knowledge of Christ."""
        vr = get_verse("Philippians 3:8-10", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_gifts_chain_luke_1_46_55(self):
        """Step 2f: Luke 1:46-55 — piety in the Magnificat."""
        vr = get_verse("Luke 1:46-55", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_john_14_15_17_nabre(self):
        """Step 3a: John 14:15-17 — promise of the Paraclete."""
        vr = get_verse("John 14:15-17", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_acts_2_1_4_nabre(self):
        """Step 3b: Acts 2:1-4 — Pentecost."""
        vr = get_verse("Acts 2:1-4", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_strongs_g3875_paracletos(self):
        """Step 4: study_strongs_number G3875 (Paraclete/comforter)."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = study_strongs_number("G3875")
        assert isinstance(result, str) and len(result) > 20
        assert _no_traceback(result)

    def test_compare_john_14_16(self):
        """Step 5: compare_translations John 14:16 NABRE, KJV, DRB."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = compare_translations("John 14:16", "NABRE,KJV,DRB")
        assert isinstance(result, str) and len(result) > 20
        assert _no_traceback(result)


# =============================================================================
# S-MIS-09: Parish Lenten Mission
# =============================================================================

@pytest.mark.skipif(not _has_network, reason="Requires network")
class TestSMis09ParishLentenMission:
    """S-MIS-09: Parish Lenten mission — three nights of repentance themes."""

    def test_night1_genesis_3_1_13(self):
        """Night 1a: Genesis 3:1-13 — the fall."""
        vr = get_verse("Genesis 3:1-13", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_night1_romans_3_23(self):
        """Night 1b: Romans 3:23 — all have sinned."""
        vr = get_verse("Romans 3:23", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_night1_1john_1_8_10(self):
        """Night 1c: 1 John 1:8-10 — confession of sin."""
        vr = get_verse("1 John 1:8-10", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_night2_2samuel_12_1_14(self):
        """Night 2a: 2 Samuel 12:1-14 — Nathan's parable, David's repentance."""
        vr = get_verse("2 Samuel 12:1-14", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_night2_commentaries_2samuel_12(self):
        """Night 2b: search_commentaries on 2 Samuel 12 — JFB, Clarke, Catholic_SB3."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = search_commentaries("2 Samuel 12:1")
        assert isinstance(result, str) and len(result) > 10
        assert _no_traceback(result)

    def test_night2_luke_15_11_24(self):
        """Night 2c: Luke 15:11-24 — Prodigal Son."""
        vr = get_verse("Luke 15:11-24", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_night2_acts_9_1_19(self):
        """Night 2d: Acts 9:1-19 — conversion of Saul."""
        vr = get_verse("Acts 9:1-19", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_hebrew_morphology_ezekiel_18_30(self):
        """Night 2e: get_morphology for Ezekiel 18:30 — shuv/repent."""
        if not _has_morphology:
            pytest.skip("Morphology not available")
        entries = get_morphology("Ezekiel 18:30")
        assert isinstance(entries, list)

    def test_night3_ezekiel_36_24_28(self):
        """Night 3a: Ezekiel 36:24-28 — new heart and spirit."""
        vr = get_verse("Ezekiel 36:24-28", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_night3_john_3_1_8(self):
        """Night 3b: John 3:1-8 — born again."""
        vr = get_verse("John 3:1-8", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_night3_2corinthians_5_17(self):
        """Night 3c: 2 Corinthians 5:17 — new creation."""
        vr = get_verse("2 Corinthians 5:17", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_night3_romans_8_1_2(self):
        """Night 3d: Romans 8:1-2 — no condemnation."""
        vr = get_verse("Romans 8:1-2", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_fts5_new_gospels_paul(self):
        """Night 3e: search_all 'new' in Gospels+Paul scope."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = search_all("new", max_results=10)
        assert isinstance(result, str) and len(result) > 5
        assert _no_traceback(result)


# =============================================================================
# S-PRI-10: Prison Ministry
# =============================================================================

@pytest.mark.skipif(not _has_network, reason="Requires network")
class TestSPri10PrisonMinistry:
    """S-PRI-10: Prison ministry — Psalms, Isaiah, Lamentations, NT prison passages."""

    def test_psalm_139_7_12_nabre(self):
        """Step 1: Psalm 139:7-12 NABRE — God's omnipresence."""
        vr = get_verse("Psalm 139:7-12", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_isaiah_42_6_7_nabre(self):
        """Step 2: Isaiah 42:6-7 — 'to bring out prisoners from the dungeon'."""
        vr = get_verse("Isaiah 42:6-7", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_compare_isaiah_42_7(self):
        """Step 3: compare_translations Isaiah 42:7 across translations."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = compare_translations("Isaiah 42:7", "NABRE,RSVCE,KJV,ESV")
        assert isinstance(result, str) and len(result) > 20
        assert _no_traceback(result)

    def test_strongs_h615_asir(self):
        """Step 4: study_strongs_number H615 (asir/prisoner)."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = study_strongs_number("H615")
        assert isinstance(result, str) and len(result) > 10
        assert _no_traceback(result)

    def test_lamentations_3_19_24_nabre(self):
        """Step 5: Lamentations 3:19-24 NABRE — hope in affliction."""
        vr = get_verse("Lamentations 3:19-24", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_matthew_25_36_nabre(self):
        """Step 6a: Matthew 25:36 — 'I was in prison and you came to me'."""
        vr = get_verse("Matthew 25:36", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_luke_4_16_21_nabre(self):
        """Step 6b: Luke 4:16-21 — 'proclaim liberty to captives'."""
        vr = get_verse("Luke 4:16-21", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_acts_16_22_34_nabre(self):
        """Step 7: Acts 16:22-34 — Paul and Silas in prison."""
        vr = get_verse("Acts 16:22-34", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_hebrews_13_3_nabre(self):
        """Step 8: Hebrews 13:3 — 'Remember those in prison'."""
        vr = get_verse("Hebrews 13:3", "NABRE")
        assert vr is not None and len(vr.text) > 10


# =============================================================================
# S-SOC-11: Parish Social Justice — Encyclical Scripture
# =============================================================================

@pytest.mark.skipif(not _has_network, reason="Requires network")
class TestSSoc11SocialJustice:
    """S-SOC-11: Social justice — Torah, Prophets, Gospels, James."""

    def test_genesis_1_26_28_nabre(self):
        """Step 1: Genesis 1:26-28 — human dignity in imago Dei."""
        vr = get_verse("Genesis 1:26-28", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_torah_chain_exodus_22_21_27(self):
        """Step 2a: Exodus 22:21-27 — protection of aliens, widows, orphans."""
        vr = get_verse("Exodus 22:21-27", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_torah_chain_leviticus_25_8_17(self):
        """Step 2b: Leviticus 25:8-17 — jubilee year."""
        vr = get_verse("Leviticus 25:8-17", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_torah_chain_deuteronomy_15_7_11(self):
        """Step 2c: Deuteronomy 15:7-11 — open hand to the poor."""
        vr = get_verse("Deuteronomy 15:7-11", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_prophets_isaiah_58_6_10(self):
        """Step 3a: Isaiah 58:6-10 — true fasting."""
        vr = get_verse("Isaiah 58:6-10", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_prophets_amos_5_21_24(self):
        """Step 3b: Amos 5:21-24 — 'let justice roll down like waters'."""
        vr = get_verse("Amos 5:21-24", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_compare_amos_5_24(self):
        """Step 4: compare_translations Amos 5:24 across translations."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = compare_translations("Amos 5:24", "NABRE,RSVCE,KJV,ESV")
        assert isinstance(result, str) and len(result) > 20
        assert _no_traceback(result)

    def test_hebrew_morphology_micah_6_8(self):
        """Step 5: get_morphology for Micah 6:8 — mishpat/justice."""
        if not _has_morphology:
            pytest.skip("Morphology not available")
        entries = get_morphology("Micah 6:8")
        assert isinstance(entries, list)

    def test_gospels_matthew_25_34_40(self):
        """Step 6a: Matthew 25:34-40 — 'Whatever you did for the least...'"""
        vr = get_verse("Matthew 25:34-40", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_gospels_luke_4_16_21(self):
        """Step 6b: Luke 4:16-21 — Nazareth manifesto."""
        vr = get_verse("Luke 4:16-21", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_gospels_luke_16_19_31(self):
        """Step 6c: Luke 16:19-31 — Rich man and Lazarus."""
        vr = get_verse("Luke 16:19-31", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_james_2_14_17_nabre(self):
        """Step 7: James 2:14-17 — faith without works."""
        vr = get_verse("James 2:14-17", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_fts5_poor_in_gospels(self):
        """Step 8: search_all 'poor' in Gospels."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = search_all("poor", max_results=10)
        assert isinstance(result, str) and len(result) > 5
        assert _no_traceback(result)


# =============================================================================
# S-CRE-12: RCIA — Apostles' Creed Through Scripture
# =============================================================================

@pytest.mark.skipif(not _has_network, reason="Requires network")
class TestSCre12ApostlesCreed:
    """S-CRE-12: RCIA — Apostles' Creed articles traced through Scripture."""

    def test_article1_genesis_1_1(self):
        """Article 1a: Genesis 1:1 — 'I believe in God, the Father almighty, Creator.'"""
        vr = get_verse("Genesis 1:1", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_article1_isaiah_40_28(self):
        """Article 1b: Isaiah 40:28 — everlasting God, Creator."""
        vr = get_verse("Isaiah 40:28", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_article1_psalm_19_1(self):
        """Article 1c: Psalm 19:1 — heavens declare the glory of God."""
        vr = get_verse("Psalm 19:1", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_article2_john_1_1_14(self):
        """Article 2a: John 1:1-14 — the Word was God."""
        vr = get_verse("John 1:1-14", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_article2_colossians_1_15_20(self):
        """Article 2b: Colossians 1:15-20 — Christ, firstborn of all creation."""
        vr = get_verse("Colossians 1:15-20", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_article2_hebrews_1_1_3(self):
        """Article 2c: Hebrews 1:1-3 — God spoke through His Son."""
        vr = get_verse("Hebrews 1:1-3", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_article3_luke_1_26_38(self):
        """Article 3: Luke 1:26-38 — Annunciation; 'conceived by the Holy Spirit, born of the Virgin Mary.'"""
        vr = get_verse("Luke 1:26-38", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_compare_isaiah_7_14_young_woman_vs_virgin(self):
        """Article 3b/Step 4: compare_translations Isaiah 7:14 — young woman vs virgin."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = compare_translations("Isaiah 7:14", "NABRE,RSVCE,KJV,ESV")
        assert isinstance(result, str) and len(result) > 20
        assert _no_traceback(result)

    def test_lxx_vs_mt_isaiah_7_14(self):
        """Step 5: LXX vs MT on Isaiah 7:14 — compare translations."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = compare_translations("Isaiah 7:14", "NABRE,KJV")
        assert isinstance(result, str) and len(result) > 20
        # NABRE uses MT-based rendering; compare with KJV's LXX-influenced rendering
        assert _no_traceback(result)

    def test_article4_6_luke_23_1_25(self):
        """Articles 4-6a: Luke 23:1-25 — 'suffered under Pontius Pilate, was crucified...'"""
        vr = get_verse("Luke 23:1-25", "NABRE")
        assert vr is not None and len(vr.text) > 30

    def test_article4_6_1peter_3_18_20(self):
        """Articles 4-6b: 1 Peter 3:18-20 — 'He descended into hell.'"""
        vr = get_verse("1 Peter 3:18-20", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_article4_6_1corinthians_15_3_8(self):
        """Articles 4-6c: 1 Corinthians 15:3-8 — resurrection appearances."""
        vr = get_verse("1 Corinthians 15:3-8", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_article7_12_acts_1_9_11(self):
        """Articles 7a: Acts 1:9-11 — 'He ascended into heaven.'"""
        vr = get_verse("Acts 1:9-11", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_article7_12_matthew_25_31_33(self):
        """Articles 7b: Matthew 25:31-33 — 'He will come again to judge the living and the dead.'"""
        vr = get_verse("Matthew 25:31-33", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_article7_12_acts_2_1_4(self):
        """Articles 8: Acts 2:1-4 — 'I believe in the Holy Spirit.'"""
        vr = get_verse("Acts 2:1-4", "NABRE")
        assert vr is not None and len(vr.text) > 20

    def test_article7_12_matthew_16_18(self):
        """Articles 9: Matthew 16:18 — 'the holy catholic Church.'"""
        vr = get_verse("Matthew 16:18", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_article7_12_hebrews_12_1(self):
        """Articles 10: Hebrews 12:1 — 'the communion of saints.'"""
        vr = get_verse("Hebrews 12:1", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_article7_12_john_20_22_23(self):
        """Articles 10b: John 20:22-23 — 'the forgiveness of sins.'"""
        vr = get_verse("John 20:22-23", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_article7_12_1corinthians_15_42_44(self):
        """Articles 11: 1 Corinthians 15:42-44 — 'the resurrection of the body.'"""
        vr = get_verse("1 Corinthians 15:42-44", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_article7_12_revelation_21_1_4(self):
        """Articles 12: Revelation 21:1-4 — 'life everlasting.'"""
        vr = get_verse("Revelation 21:1-4", "NABRE")
        assert vr is not None and len(vr.text) > 10

    def test_strongs_g3933_parthenos(self):
        """Step 8: study_strongs_number G3933 (parthenos/virgin)."""
        if not _has_mcp:
            pytest.skip("MCP server not importable")
        result = study_strongs_number("G3933")
        assert isinstance(result, str) and len(result) > 20
        assert _no_traceback(result)


# =============================================================================
# LOCAL TESTS — Canon reference parsing for all 12 scenarios
# =============================================================================

@pytest.mark.skipif(not _has_canon, reason="Canon not available")
class TestSession78ReferenceParsing:
    """Verify all key references from the 12 scenarios parse correctly."""

    def test_parse_wisdom_3_1(self):
        r = parse_reference("Wisdom 3:1", "catholic")
        assert r is not None

    def test_parse_hosea_2_19(self):
        r = parse_reference("Hosea 2:19", "catholic")
        assert r is not None

    def test_parse_ezekiel_36_25(self):
        r = parse_reference("Ezekiel 36:25", "catholic")
        assert r is not None

    def test_parse_john_6_54(self):
        r = parse_reference("John 6:54", "catholic")
        assert r is not None
        assert r.book_osis == "John"
        assert r.chapter == 6
        assert r.verse == 54

    def test_parse_luke_15_18(self):
        r = parse_reference("Luke 15:18", "catholic")
        assert r is not None

    def test_parse_isaiah_53_8(self):
        r = parse_reference("Isaiah 53:8", "catholic")
        assert r is not None

    def test_parse_exodus_20_13(self):
        r = parse_reference("Exodus 20:13", "catholic")
        assert r is not None

    def test_parse_acts_2_1(self):
        r = parse_reference("Acts 2:1", "catholic")
        assert r is not None

    def test_parse_2samuel_12_1(self):
        r = parse_reference("2 Samuel 12:1", "catholic")
        assert r is not None

    def test_parse_isaiah_42_7(self):
        r = parse_reference("Isaiah 42:7", "catholic")
        assert r is not None

    def test_parse_amos_5_24(self):
        r = parse_reference("Amos 5:24", "catholic")
        assert r is not None

    def test_parse_isaiah_7_14(self):
        r = parse_reference("Isaiah 7:14", "catholic")
        assert r is not None

    def test_deuterocanonical_all_resolve(self):
        """All deuterocanonical books referenced in scenarios should resolve."""
        for book_name in ["Wisdom", "Sirach", "1 Maccabees"]:
            b = resolve_book(book_name)
            assert b is not None, f"Failed to resolve {book_name}"


# =============================================================================
# LOCAL TESTS — Catholic canon structure validation
# =============================================================================

@pytest.mark.skipif(not _has_canon, reason="Canon not available")
class TestSession78CanonStructure:
    """Verify key canon facts that support the 12 priest scenarios."""

    def test_wisdom_is_in_catholic_canon(self):
        names = {b.osis for b in CANON_CATHOLIC.books}
        assert "Wis" in names

    def test_sirach_is_in_catholic_canon(self):
        names = {b.osis for b in CANON_CATHOLIC.books}
        assert "Sir" in names

    def test_hosea_has_14_chapters(self):
        assert chapter_count("Hos", CANON_CATHOLIC) == 14

    def test_psalm_has_150_chapters(self):
        assert chapter_count("Ps", CANON_CATHOLIC) == 150

    def test_matthew_has_28_chapters(self):
        assert chapter_count("Matt", CANON_CATHOLIC) == 28

    def test_john_has_21_chapters(self):
        assert chapter_count("John", CANON_CATHOLIC) == 21


# =============================================================================
# LOCAL TESTS — Morphology description utilities
# =============================================================================

@pytest.mark.skipif(not _has_morphology, reason="Morphology not available")
class TestSession78MorphologyLocal:
    """Verify morphology description utilities work for scenario-related codes."""

    def test_describe_hebrew_qal_imperfect(self):
        """Hebrew Qal imperfect is common in OT verses."""
        desc = describe_hebrew_morph("Vqi3ms")
        assert isinstance(desc, str) and len(desc) > 0

    def test_describe_present_active_indicative(self):
        """Present active indicative is common in NT verses."""
        desc = describe_robinson("V-PAI-3S")
        assert isinstance(desc, str) and len(desc) > 0
        assert "Present" in desc

    def test_describe_aorist_active(self):
        """Aorist active is common in narrative NT passages."""
        desc = describe_robinson("V-AAI-3S")
        assert isinstance(desc, str) and len(desc) > 0

    def test_describe_perfect_passive_participle(self):
        """Perfect passive participle for charitoo/parthenos contexts."""
        desc = describe_robinson("V-XPP-NSF")
        assert isinstance(desc, str) and len(desc) > 0

    def test_describe_unknown_code_returns_string(self):
        """Unknown Robinson codes should not crash."""
        desc = describe_robinson("X-UNKNOWN-XYZ")
        assert isinstance(desc, str) and len(desc) > 0


# =============================================================================
# IMPORTS SMOKE TEST
# =============================================================================

class TestImportAvailability:
    """Document which tools are importable (informational, not failing)."""

    def test_canon_importable(self):
        assert _has_canon, "Canon module should always be available"

    def test_bible_api_importable(self):
        assert _has_bible_api, "Bible API should always be importable"

    def test_morphology_importable(self):
        assert _has_morphology, "Morphology should always be importable"

    def test_mcp_import_status(self):
        if not _has_mcp:
            pytest.skip(f"MCP server not importable: {_mcp_import_error}")

    def test_network_status(self):
        if not _has_network:
            pytest.skip("Network/API not available — bolls.life may be unreachable")


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
