
    mj                        d Z ddlmZ ddl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dlmZ ddlmZ  ej&                  e      Z G d	 d
      Zy)u  씬 이미지 검증 서비스 — W5 F22 Phase B.6.

SceneImageService에서 T2I 검증 로직을 이관. 공개 API는 facade가 유지하고
본 서비스는 구현을 담당.

Phase 4 iter 7 follow-up B1 (cost policy): scene_lvm_validation_mode
default = "off" 라 본 서비스의 legacy validator (LVM 2) 도 default disabled.
mode == "full" 일 때만 ImageValidator 인스턴스 생성. 이 정책은 자동 batch
경로 (SceneGenerationCoordinator) 에 적용되며, image_review_service 등
운영자가 명시적으로 trigger 하는 review API 는 별도 (cost policy 범위 밖).

공개 API (SceneImageService facade가 delegation):
- `create_validator()` — mode/key 가드 통과 시 ImageValidator, 아니면 None.
- `validate_scene(validator, file_path, scene_info, entity_names, status, review_notes)`
  T2I로 생성된 씬 이미지가 visible_entities를 실제 포함하는지 OpenAI LVM으로 검증.
  score < 60이면 status='needs_fix'로 마킹.
    )annotationsN)Path)AnyDictListOptional)Session)settings)ImageValidatorc                  D    e Zd ZdZddZddZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZy)	SceneValidationServiceu9   T2I 이미지 검증 전담 서비스 (W5 F22 Phase B.6).c                     || _         || _        y )N)_db_project_id)selfdb
project_ids      [/Users/manta/Documents/Projects/TheRoad-I1/backend/app/services/scene_validation_service.py__init__zSceneValidationService.__init__$   s    %    c                    t         j                  }|dk7  rt        j                  d|       yddlm}  |       st        j                  d       yt               S )u  ImageValidator 생성. None 반환 조건:
        1) openai_api_key 미설정.
        2) scene_lvm_validation_mode != "full" (Phase 4 iter 7 follow-up B1).

        W5 F22 Phase B.7: scene_image_service._create_validator에서 이관됨.

        Phase 4 iter 7 follow-up B1: scene_image_pipeline 의 _call_gpt_lvm
        (LVM 1) 외에 SceneGenerationCoordinator 가 별도 ImageValidator (LVM 2,
        image_validator.py) 를 호출하는 경로가 있어, mode="off" 인데도 OpenAI
        vision 호출이 모든 shot 마다 일어나 cost policy 가 절반만 적용됐음
        (Codex review B1 + 사용자 cost 정책). LVM 1 과 같은 mode 로 통합.
        mode="full" 만 legacy validator 활성. targeted/sample 에서도 deactivate
        — 운영자가 LVM 을 "선택적 활성" 하려는 의도이지 legacy 까지 항상 켜는
        것이 아님 (cost 절감 정합).
        fullu   Skipping legacy scene image validation — scene_lvm_validation_mode=%s (LVM 2 disabled by cost policy; only mode='full' enables it).Nr   )has_openai_keyz;Skipping image validation -- OpenAI API key not configured.)r
   scene_lvm_validation_modeloggerinfoapp.core.openai_keysr   r   )r   moder   s      r   create_validatorz'SceneValidationService.create_validator(   sR      116>KKP
 7KKUVr   c                   	 t        |      }|j                         sdd||fS |j                         }|j                  |||      }	|	j	                  dd      }
t        j                  |	d      }|
dk  r1|	j	                  dg       }|rdj                  |      nd	}d
}d|
 d| }t        j                  d|
|	j	                  d             |
|||fS # t        $ r&}t        j                  d|       dd||fcY d}~S d}~ww xY w)uD  T2I 씬 이미지 LVM 검증.

        Returns: (score, result_json, updated_status, updated_review_notes)
        - 파일 미존재: (None, None, status, review_notes)
        - score < 60: status='needs_fix', review_notes에 이슈 삽입
        - 예외 발생: (None, None, status, review_notes) + warning log
        Nscorer   F)ensure_ascii<   issuesz; zLow validation score	needs_fixz[auto-validation] score=z: z*Scene image validated: score=%d, passed=%spassedz!Scene image validation failed: %s)r   exists
read_bytesvalidate_scene_imagegetjsondumpsjoinr   r   	Exceptionwarning)r   	validator	file_path
scene_infoentity_namesstatusreview_notesfpimage_bytesresultr!   result_jsonr$   
issue_textexcs                  r   validate_scenez%SceneValidationService.validate_sceneF   s     	4iB99;T6<77--/K33K\ZFJJw*E**V%@KrzHb128TYYv.>T
$!9%:,OKKDeVZZX`Mab+v|;; 	4NN>Dv|33	4s#    C B-C 	D C;5D ;D N)r   
OrmSessionr   strreturnNone)r?   zOptional[ImageValidator])r0   r   r1   r>   r2   zDict[str, Any]r3   z	List[str]r4   r>   r5   r>   r?   tuple)__name__
__module____qualname____doc__r   r   r<    r   r   r   r   !   sX    C& <!4!!4 !4 #	!4
  !4 !4 !4 
!4r   r   )rE   
__future__r   r+   loggingpathlibr   typingr   r   r   r   sqlalchemy.ormr	   r=   app.core.configr
   app.modules.image_validatorr   	getLoggerrB   r   r   rF   r   r   <module>rO      sE   " #    , , 0 $ 6			8	$F4 F4r   