
    Kik                        d Z ddlmZ ddlZddlmZ ddlmZmZm	Z	m
Z
 ddlmZ dgZ ej                  e      Z G d d      Zy)	u  Scene provenance service — scene_image_service에서 분리된 이력/메타데이터.

W5 F22 Phase B.10 (2026-04-22): scene_image_service.generate_images()의
PNG metadata embedding 로직을 이관.

## 공개 API

| 메서드 | 역할 |
|--------|------|
| `embed_scene_variations_metadata(var_results_list, still_data, still_index_fallback, dep_scene_idx, prev_file)` | N variation PNG에 컨텍스트 metadata embed |
| `compute_and_embed_scene_metadata(var_results_list, still_data, stills, si, scene_paths_by_index, scene_paths_by_index_by_id)` | dep_scene_idx + prev_file 계산 후 embed |
| `embed_fal_angle_metadata(*, file_path, source_image_name, horizontal_angle, vertical_angle, zoom, created_at)` | fal.ai angle-edited PNG에 angle/source metadata embed |

두 메서드는 모두 내부적으로 예외를 포착하여 warning으로 로깅한다 (non-fatal).
embedding 실패가 이미지 생성 파이프라인을 중단시키지 않는다.

향후 확장: GenerationTrace 기록, lineage 필드 빌더 등을 점진 이관 예정.
    )annotationsN)Path)AnyDictListUnion)SessionSceneProvenanceServicec                      e Zd ZdZddZ	 	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 d	dZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 d
dZy)r
   u>   씬 이미지 provenance 전담 서비스 (W5 F22 Phase B.10).c                     || _         || _        y )N)_db_project_id)selfdb
project_ids      [/Users/manta/Documents/Projects/TheRoad-I1/backend/app/services/scene_provenance_service.py__init__zSceneProvenanceService.__init__#   s    %    c                   	 ddl m} t        |      D ]  \  }} ||d   |j                  d      xs ddd |j                  dd      t	        |j                  d	|            |j                  d
d      |j                  dd|       |||j                  dd      |j                  dd      d	        y# t
        $ r }	t        j                  d|	       Y d}	~	yd}	~	ww xY w)u  Embed PNG metadata for each of the N scene variations.

        Each PNG receives: prompt (truncated 2000), scene_description,
        scene_index (still_index with fallback), beat_title, variant_type,
        dependent_scene, previous_scene, model, created_at.
        All exceptions — including `png_metadata` import failure — are
        caught and logged (non-fatal). PNG metadata embedding is strictly
        best-effort and must never break the image pipeline.
        r   embed_png_metadata	file_pathprompt_used Ni  still_frame_promptstill_index
beat_titlevariant_typevar_generation_model
created_at)	promptscene_descriptionscene_indexr   r   dependent_sceneprevious_scenemodelr!   !PNG metadata embedding failed: %s)app.modules.png_metadatar   	enumerategetstr	Exceptionloggerwarning)
r   var_results_list
still_datastill_index_fallbackdep_scene_idx	prev_filer   vivrexcs
             r   embed_scene_variations_metadataz6SceneProvenanceService.embed_scene_variations_metadata'   s    "	E D#$45B"2k?!vvm4:ETB)38Lb)Q#&z~~mEY'Z#[",..r"B$&FF>T";$G'4&/VV$6;"$&&r":
5 
 6  	ENN>DD	Es   B1B4 4	C=CCc                @   d}|j                  d      r;|D ]6  }|j                  d      |d   k(  st        |j                  dd            } n d}	||v r||   j                  }	n%|j                  d      |v r||d      j                  }	| j                  |||||	       y)u  dep_scene_idx + prev_file을 계산한 뒤 N variation PNG에 embed.

        W5 F22 Phase B.22.8 (2026-04-23): scene_image_service.generate_images의
        PNG 메타데이터 컨텍스트 계산 블록(~16 LOC)을 이관.

        dep_scene_idx:
          still_data.dependent_scene_id가 있으면 stills에서 해당 still을 찾아
          still_index를 문자열로. 없으면 "".

        prev_file:
          1순위: scene_paths_by_index[si].name
          2순위: scene_paths_by_index_by_id[still_data.dependent_scene_id].name
          없으면 "".

        계산 후 `embed_scene_variations_metadata`에 위임.
        r   dependent_scene_ididr   N)r+   r,   namer8   )
r   r0   r1   stillssiscene_paths_by_indexscene_paths_by_index_by_idr3   _ssr4   s
             r    compute_and_embed_scene_metadataz7SceneProvenanceService.compute_and_embed_scene_metadataK   s    2 >>./774=J/C$DD$'r(B$CM  	%%,R055I^^015OO2:>R3STYYI,,j"mY	
r   c          
         	 ddl m}  |||t        |      t        |      t        |      d|d       y# t        $ r }t        j                  d|       Y d}~yd}~ww xY w)u   Embed PNG metadata for a fal.ai angle-edited scene image.

        All exceptions — including `png_metadata` import failure — are
        caught and logged (non-fatal).
        r   r   z+fal-ai/qwen-image-edit-2511-multiple-angles)source_imageangle_horizontalangle_vertical
angle_zoomr'   r!   r(   N)r)   r   r,   r-   r.   r/   )	r   r   source_image_namehorizontal_anglevertical_anglezoomr!   r   r7   s	            r   embed_fal_angle_metadataz/SceneProvenanceService.embed_fal_angle_metadatat   sa    	ECy 1$'(8$9"%n"5!$iF(+   	ENN>DD	Es   14 	AAAN)r   
OrmSessionr   r,   returnNone)r0   List[Dict[str, Any]]r1   Dict[str, Any]r2   intr3   r,   r4   r,   rN   rO   )r0   rP   r1   rQ   r=   rP   r>   rR   r?   zDict[int, Path]r@   zDict[str, Path]rN   rO   )r   zUnion[str, Path]rH   r,   rI   floatrJ   rS   rK   rS   r!   r,   rN   rO   )__name__
__module____qualname____doc__r   r8   rB   rL    r   r   r
   r
       s    H&"E."E #"E "	"E
 "E "E 
"EH'
.'
 #'
 %	'

 '
 .'
 %4'
 
'
RE $E 	E
  E E E E 
Er   )rW   
__future__r   loggingpathlibr   typingr   r   r   r   sqlalchemy.ormr	   rM   __all__	getLoggerrT   r.   r
   rX   r   r   <module>r`      sF   $ #   ) ) 0#
$			8	$nE nEr   