"""file_path 일관성 — production reality mirror 회귀 가드.

PID 0bb48ebf E2E false-positive partial 사고 재발 방지:

레거시 ImageAsset row는 floor_plan/chain_bg가 ``projects/...`` 상대 경로로
저장됐고 reference/scene/composite는 절대 경로로 저장됐다. ``Path(rel).exists()``
는 cwd 의존이라 verify_completion이 재실행 시점 cwd가 PROJECT_ROOT가 아니면
항상 False를 반환했다.

본 테스트는 verify_completion 5곳이 상대 경로로 저장된 row를 정확히 hit
시키는지 검증한다. 새 production code는 절대 경로를 저장하지만, 이미 DB에
누적된 legacy row 호환은 ``resolve_image_path``가 책임진다.
"""
from __future__ import annotations

from pathlib import Path

import pytest


def _make_relative_path(tmp_path: Path, project_id: str, name: str) -> tuple[str, Path]:
    """PROJECT_ROOT(=tmp_path) 기준 ``projects/{pid}/{name}`` 상대 경로 + 파일 생성.

    Returns (rel_path_for_db, abs_path_actual).
    """
    rel = f"projects/{project_id}/{name}"
    abs_path = tmp_path / rel
    abs_path.parent.mkdir(parents=True, exist_ok=True)
    abs_path.write_bytes(b"\x89PNG")
    return rel, abs_path


def test_floor_plan_verify_resolves_relative_path(
    seed_episode_with_floor_plans, tmp_path, monkeypatch,
):
    """legacy floor_plan row(상대 경로 + cwd != PROJECT_ROOT)도 verify에서 hit.

    이전 ``Path(file_path).exists()``는 cwd 의존 → 거의 항상 False 반환.
    helper 적용 후 PROJECT_ROOT join → 절대 경로로 변환되어 정확히 hit.
    """
    monkeypatch.setattr("app.core.file_paths.PROJECT_ROOT", tmp_path)
    runner = seed_episode_with_floor_plans(
        master_plan_fps=[("L01", "fp_main")],
        prompt_status={"fp_main": "ok"},
        background_mode="on",
    )
    rel, _abs = _make_relative_path(tmp_path, runner.project_id, "fp_main.png")
    runner._add_floor_plan_asset(loc_short="L01", fp_id="fp_main", file_path=rel)

    # cwd를 일부러 다른 디렉토리로 → 직접 Path(rel)은 False가 되는 환경
    other = tmp_path / "elsewhere"
    other.mkdir()
    monkeypatch.chdir(other)

    report = runner.verify_completion()
    assert report.is_complete is True, (
        f"legacy 상대 경로 row가 hit돼야 함 (cwd 의존 회귀 가드) — meta={report.metadata}"
    )
    assert report.metadata["floor_plan_found"] == 1


def test_chain_bg_planner_verify_resolves_relative_path(
    seed_episode_with_chain_bg_planner, tmp_path, monkeypatch,
):
    """legacy chain_bg row(상대 경로) verify hit 가드 (planner path)."""
    monkeypatch.setattr("app.core.file_paths.PROJECT_ROOT", tmp_path)
    runner = seed_episode_with_chain_bg_planner(chain_order=["g1"])
    rel, _abs = _make_relative_path(tmp_path, runner.project_id, "chain_g1.png")
    runner._add_chain_bg_asset(group_id="g1", file_path=rel)

    other = tmp_path / "elsewhere"
    other.mkdir()
    monkeypatch.chdir(other)

    report = runner.verify_completion()
    assert report.is_complete is True
    assert report.metadata["chain_bg_found"] == 1


def test_chain_bg_legacy_verify_resolves_relative_path(
    seed_episode_with_chain_bg_legacy, tmp_path, monkeypatch,
):
    """legacy background_chain_node row(상대 경로) verify hit 가드 (legacy path)."""
    monkeypatch.setattr("app.core.file_paths.PROJECT_ROOT", tmp_path)
    runner = seed_episode_with_chain_bg_legacy(
        nodes_by_location={"L01": ["n1"]},
    )
    rel, _abs = _make_relative_path(tmp_path, runner.project_id, "node_n1.png")
    runner._add_chain_node_asset(node_id="n1", file_path=rel, location_short_id="L01")

    other = tmp_path / "elsewhere"
    other.mkdir()
    monkeypatch.chdir(other)

    report = runner.verify_completion()
    assert report.is_complete is True
    assert report.metadata["chain_bg_found"] == 1


def test_ref_image_gen_verify_resolves_relative_path(
    seed_episode_with_chars, tmp_path, monkeypatch,
):
    """RefImageGen verify도 상대 경로 row 보호 (cross-step 일관)."""
    monkeypatch.setattr("app.core.file_paths.PROJECT_ROOT", tmp_path)
    runner = seed_episode_with_chars(["C01"], skip=[])
    rel, _abs = _make_relative_path(tmp_path, runner.project_id, "ref_C01.png")
    runner._add_ref_asset(short_id="C01", file_path=rel)

    other = tmp_path / "elsewhere"
    other.mkdir()
    monkeypatch.chdir(other)

    report = runner.verify_completion()
    assert report.is_complete is True
    assert report.metadata["found"] == 1
