"""goal#3 실데이터 검증 — outdoor 체인 lineage resolve + 그래프 엣지 (커밋금지).

7f325c39/fbf15266 의 기존 outdoor asset 4행에 _resolve_outdoor_chain_lineage 를
실행해 input_image_ids 체인을 채우고, pipeline_graph 의 generated_input 엣지로
aerial→blocking→sketch 가 캔버스에 그려지는지 확인한다.
"""
import json
import os
os.chdir(os.path.join(os.path.dirname(__file__), "..", ".."))  # backend cwd (.env)

import sys
sys.path.insert(0, os.getcwd())
from app.core.database import SessionLocal
import app.main  # 전 모델 메타데이터 등록(FK resolve) — standalone 필수
from app.core.steps.outdoor_site_layout_step import _resolve_outdoor_chain_lineage
from app.models.project import ImageAsset
from app.services.pipeline_graph_service import build_pipeline_graph

PID = "7f325c39-7478-4386-a562-27daadd44353"
EID = "fbf15266-989c-4cc8-8d82-699ea5f628aa"

db = SessionLocal()
try:
    print("=== BEFORE ===")
    rows = (db.query(ImageAsset).filter(
        ImageAsset.project_id == PID, ImageAsset.episode_id == EID,
        ImageAsset.pipeline_role.in_([
            "outdoor_aerial_base", "outdoor_shot_blocking", "outdoor_camera_sketch"]))
        .order_by(ImageAsset.created_at).all())
    for r in rows:
        print(f"  {r.pipeline_role:24} {r.id[:8]} input={r.input_image_ids}")

    # composition_guides synthetic — L03 s10 sh8 sketch 회수 확인용.
    cg = {"10:8": {"mode": "sketch", "group_id": "osl-shared-l03-s10"}}
    diag = _resolve_outdoor_chain_lineage(db, PID, EID, cg)

    print("\n=== DIAGNOSTICS ===")
    print(json.dumps(diag, ensure_ascii=False, indent=1))
    print("\n=== composition_guides after ===")
    print(json.dumps(cg, ensure_ascii=False, indent=1))

    print("\n=== AFTER (DB) ===")
    db.expire_all()
    rows = (db.query(ImageAsset).filter(
        ImageAsset.project_id == PID, ImageAsset.episode_id == EID,
        ImageAsset.pipeline_role.in_([
            "outdoor_aerial_base", "outdoor_shot_blocking", "outdoor_camera_sketch"]))
        .order_by(ImageAsset.created_at).all())
    id2role = {r.id: r.pipeline_role for r in rows}
    for r in rows:
        ins = json.loads(r.input_image_ids) if r.input_image_ids else None
        ins_roles = [id2role.get(x, x[:8]) for x in (ins or [])]
        print(f"  {r.pipeline_role:24} {r.id[:8]} input={ins_roles}")

    print("\n=== GRAPH generated_input edges (outdoor chain) ===")
    g = build_pipeline_graph(db, PID, EID)
    nid2role = {n.id: n.pipeline_role for n in g.nodes}
    chain_roles = {"outdoor_aerial_base", "outdoor_shot_blocking",
                   "outdoor_camera_sketch", "scene_still"}
    cnt = 0
    for e in g.edges:
        if e.kind != "generated_input":
            continue
        sr = nid2role.get(e.source); tr = nid2role.get(e.target)
        if sr in chain_roles or tr in chain_roles:
            if sr and sr.startswith("outdoor") or tr and tr.startswith("outdoor"):
                print(f"  {sr} ({e.source[:8]}) --> {tr} ({e.target[:8]})")
                cnt += 1
    print(f"\noutdoor-chain generated_input edges = {cnt}")
    print(f"graph diagnostics dangling_input_refs = {g.diagnostics.get('dangling_input_refs')}")
finally:
    db.close()
