"""Wave2 B1 — severe-regeneration 탈락 후보(실 바이트) capture 테스트.

_capture_regeneration_loser 는 좁은 scope 로 loser 한 장만 rejected 중간물로
영속화한다(winner 는 caller 가 최종 등록 → 중복 0). project_id 부재 / loser_bytes
부재 시 skip. PG theroad_test, conftest session-autouse 스키마.
"""

import uuid
from datetime import datetime, timezone

from app.core.database import SessionLocal
from app.models.catalog import ProjectRegistry, UserAccount
from app.models.project import Episode, ImageAsset
from app.modules.pipeline.scene_image_pipeline import _capture_regeneration_loser


def _now() -> str:
    return datetime.now(timezone.utc).isoformat()


def _seed(db) -> tuple[str, str]:
    uid = str(uuid.uuid4())
    db.add(UserAccount(
        id=uid, username=f"u_{uid[:8]}", display_name="t", password_hash="x",
        role="admin", created_at=_now(), updated_at=_now(),
    ))
    db.commit()
    pid = str(uuid.uuid4())
    db.add(ProjectRegistry(
        id=pid, name="B1 Test", created_by=uid, created_at=_now(), updated_at=_now(),
    ))
    eid = str(uuid.uuid4())
    db.add(Episode(
        id=eid, project_id=pid, episode_number=1, title="Pilot",
        source_filename="p.pdf", source_path="p.pdf", created_at=_now(), updated_at=_now(),
    ))
    db.commit()
    return pid, eid


def test_loser_captured_as_rejected_intermediate():
    db = SessionLocal()
    try:
        pid, eid = _seed(db)
    finally:
        db.close()

    _capture_regeneration_loser(
        loser_bytes=b"LOSERPNG",
        trace_meta={
            "project_id": pid, "episode_id": eid,
            "still_id": None, "scene_index": 3, "shot_index": 2,
        },
        beat_title="some beat title",
        winner="image_2",
    )

    db = SessionLocal()
    try:
        row = db.query(ImageAsset).filter(
            ImageAsset.project_id == pid, ImageAsset.is_intermediate == True  # noqa: E712
        ).one()
        assert row.pipeline_role == "scene_regeneration_candidate"
        assert row.disposition == "rejected"
        assert row.candidate_index == 1
        assert row.attempt_index == 1
        assert row.asset_type == "generated"
    finally:
        db.close()


def test_no_capture_without_project_id():
    """trace_meta 에 project_id 없으면 scope 불가 → skip(non-fatal)."""
    # raise 안 함, row 도 안 생김(project 부재라 조회 자체가 무의미 → 예외 없이 반환).
    _capture_regeneration_loser(
        loser_bytes=b"X", trace_meta={"episode_id": "e"},
        beat_title="t", winner="image_1",
    )
    _capture_regeneration_loser(
        loser_bytes=b"X", trace_meta=None, beat_title="t", winner="image_1",
    )


def test_no_capture_without_loser_bytes():
    _capture_regeneration_loser(
        loser_bytes=None, trace_meta={"project_id": "p"},
        beat_title="t", winner="image_1",
    )
    _capture_regeneration_loser(
        loser_bytes=b"", trace_meta={"project_id": "p"},
        beat_title="t", winner="image_1",
    )
