"""Regression coverage for the BaoBao-density `_location_prompt` rewrite.

The prior version was a fixed 6-panel stub (SUBSTRATE_STATUS deferred-#4).
2026-05-28 rewrite gives locations the same 4-section structure characters
already had: coverage / textures / lighting study / palette. Bible can
override each list via `sheet_loc_*` fields; defaults are Tartarus-flavored.
"""

from __future__ import annotations

import pytest

from recoil.pipeline.tools.generate_composite_sheet import _location_prompt


def _bible(**loc_overrides) -> dict:
    base_loc = {
        "display_name": "Lower Decks Corridor",
        "description": "Cramped pipe-lined passage running between salvage bays.",
        "atmosphere": "Damp, claustrophobic, low overhead clearance.",
        "habitat_zone": "industrial",
        "color_palette": ["RUST", "AMBER", "STEEL"],
        "lighting_profile": {
            "primary_source": "overhead industrial sodium lamps",
            "direction": "top-down",
            "quality": "harsh",
            "color_temp": "warm 2700K",
        },
    }
    base_loc.update(loc_overrides)
    return {"locations": {"int_lower_decks_corridor": base_loc}}


def test_unknown_loc_id_raises():
    bible = _bible()
    with pytest.raises(KeyError, match="MISSING"):
        _location_prompt(bible, "MISSING", "16:9")


def test_four_sections_present():
    """All four BaoBao-density sections must appear in the prompt."""
    prompt = _location_prompt(_bible(), "int_lower_decks_corridor", "16:9")
    assert "SECTION 1" in prompt and "COVERAGE" in prompt
    assert "SECTION 2" in prompt and "MATERIALS" in prompt
    assert "SECTION 3" in prompt and "LIGHTING STUDY" in prompt
    assert "SECTION 4" in prompt and "COLOR PALETTE" in prompt


def test_no_characters_directive_present():
    """Location sheets must explicitly forbid figures in the rendered output."""
    prompt = _location_prompt(_bible(), "int_lower_decks_corridor", "16:9")
    assert "NO CHARACTERS" in prompt
    assert "no figures" in prompt.lower()


def test_bible_overrides_coverage_textures_lighting_palette():
    """Each of the four bible override fields wins over the default vocab."""
    bible = _bible(
        sheet_loc_coverage=["WIDE", "MEDIUM", "CLOSE"],
        sheet_loc_textures=["MARBLE", "GOLD LEAF"],
        sheet_loc_lighting=["NOON", "MIDNIGHT"],
        sheet_loc_palette=["WHITE", "GOLD"],
    )
    prompt = _location_prompt(bible, "int_lower_decks_corridor", "16:9")
    assert "MARBLE, GOLD LEAF" in prompt
    assert "NOON, MIDNIGHT" in prompt
    assert "WHITE, GOLD" in prompt
    # Coverage joins with semicolons (the labels contain commas internally).
    assert "WIDE; MEDIUM; CLOSE" in prompt
    # Tartarus-flavored default texture must not leak through.
    assert "RUSTED STEEL" not in prompt


def test_palette_default_falls_back_to_bible_color_palette():
    """When sheet_loc_palette is absent, the legacy color_palette field is used."""
    bible = _bible()  # has color_palette = [RUST, AMBER, STEEL], no sheet_loc_palette
    prompt = _location_prompt(bible, "int_lower_decks_corridor", "16:9")
    assert "RUST, AMBER, STEEL" in prompt


def test_palette_default_falls_back_to_tartarus_flavored_when_both_empty():
    """When neither sheet_loc_palette nor color_palette is set, defaults fire."""
    bible = {"locations": {"loc_x": {"description": "test"}}}
    prompt = _location_prompt(bible, "loc_x", "16:9")
    assert "RUST ORANGE" in prompt
    assert "OIL BLACK" in prompt


def test_lighting_profile_renders_when_present():
    prompt = _location_prompt(_bible(), "int_lower_decks_corridor", "16:9")
    assert "PRIMARY LIGHTING:" in prompt
    assert "overhead industrial sodium lamps" in prompt
    assert "top-down direction" in prompt


def test_lighting_profile_block_omitted_when_empty():
    """Don't render an empty `PRIMARY LIGHTING:` line."""
    bible = _bible(lighting_profile={})
    prompt = _location_prompt(bible, "int_lower_decks_corridor", "16:9")
    assert "PRIMARY LIGHTING:" not in prompt


def test_aspect_ratio_threaded_into_layout_directive():
    prompt = _location_prompt(_bible(), "int_lower_decks_corridor", "1:1")
    assert "1:1 layout" in prompt


def test_display_name_falls_back_to_titled_loc_id():
    """When bible omits display_name, derive from the loc_id slug."""
    bible = {"locations": {"int_lower_decks_corridor": {"description": "x"}}}
    prompt = _location_prompt(bible, "int_lower_decks_corridor", "16:9")
    assert "Int Lower Decks Corridor" in prompt
