
    Si                         d Z ddlZddlZddlZddlZddlmZmZmZ  ej                  e	      Z
 e ed            Z G d d      Zy)u	  Feature Flag 로더 모듈.

.claude/feature_flags.json을 읽고 플래그 상태를 관리한다.

Usage:
    from utils.feature_flags import FeatureFlagLoader
    flags = FeatureFlagLoader()
    if flags.is_enabled("progressive_disclosure_enabled"):
        ...
    N)datetime	timedeltatimezone	   )hoursc                   n    e Zd ZdZddefdZddZddZdedefd	Z	ded
eddfdZ
deddfdZdefdZy)FeatureFlagLoaderu1   Feature flag 로더. mtime 캐시 + atomic write.pathc                    t         j                  j                  |      s@t         j                  j	                  dd      }t         j                  j                  ||      }|| _        i | _        d| _        | j                          y )NWORKSPACE_ROOTz/home/jay/workspaceg        )
osr
   isabsenvirongetjoin_path_cache_mtime_load)selfr
   	workspaces      D/home/jay/workspace/.worktrees/task-2117-dev1/utils/feature_flags.py__init__zFeatureFlagLoader.__init__   sZ    ww}}T"

'79NOI77<<	40D
 

    returnNc                    	 t        | j                  dd      5 }t        j                  |      | _        ddd       t
        j                  j                  | j                        | _        y# 1 sw Y   8xY w# t        $ r, t        j                  d| j                         di i| _        Y yt        j                  $ r# t        j                  d| j                         Y yw xY w)u/   파일 로드. 실패 시 이전 캐시 유지.rzutf-8)encodingNuA   Feature flags 파일 없음: %s — 모든 플래그 false 처리flagsu=   Feature flags JSON 파싱 실패: %s — 이전 캐시 유지)openr   jsonloadr   r   r
   getmtimer   FileNotFoundErrorloggerwarningJSONDecodeError)r   fs     r   r   zFeatureFlagLoader._load$   s    	hdjj#8 +A"iil+''**4::6DK+ + ! 	(NN^`d`j`jk"B-DK## 	hNNZ\`\f\fg	hs-   A8 A,6A8 ,A51A8 82C!,2C! C!c                     	 t         j                  j                  | j                        }|| j
                  k7  r| j                          yy# t        $ r Y yw xY w)u9   파일 mtime 확인 후 변경된 경우에만 재로드.N)r   r
   r#   r   r$   r   r   )r   current_mtimes     r   reloadzFeatureFlagLoader.reload0   sO    	GG,,TZZ8M DKK'JJL ( ! 		s   )A 	AA	flag_namec                     | j                          | j                  j                  di       }||vrt        j	                  d|       yt        ||         S )uJ   플래그 활성화 여부 반환. 존재하지 않는 플래그는 False.r   u-   알 수 없는 플래그: %s — False 반환F)r+   r   r   r%   r&   bool)r   r,   r   s      r   
is_enabledzFeatureFlagLoader.is_enabled9   sI    ,E!NNJIVE)$%%r   valuec                 ~   | j                          | j                  j                  di       }|||<   || j                  d<   t        j                  t
              j                         | j                  d<   | j                  | j                         t        j                  j                  | j                        | _        y)u?   atomic write로 플래그 값 변경. updated_at 자동 갱신.r   
updated_atN)r+   r   r   r   nowKST	isoformat_atomic_writer   r
   r#   r   r   )r   r,   r0   r   s       r   set_flagzFeatureFlagLoader.set_flagB   s    , i$G$,LL$5$?$?$AL!4;;'gg&&tzz2r   datac                 j   t         j                  j                  | j                        }t        j                  |d       t        j                  d|dd      5 }t        j                  ||dd       |j                  }d	d	d	       t        j                  | j                         y	# 1 sw Y   *xY w)
u-   atomic write: tempfile → os.replace 패턴.T)exist_okwFz.tmp)modedirdeletesuffix   )indentensure_asciiN)r   r
   dirnamer   makedirstempfileNamedTemporaryFiler!   dumpnamereplace)r   r8   dir_pathr(   tmp_paths        r   r6   zFeatureFlagLoader._atomic_writeL   s    77??4::.
Ht,((cxV\] 	abIIdAae<vvH	 	

8TZZ(	 	s   &B))B2c                 l    | j                          t        | j                  j                  di             S )u   모든 플래그 상태 반환.r   )r+   dictr   r   )r   s    r   get_all_flagszFeatureFlagLoader.get_all_flagsU   s%    DKKOOGR011r   )z.claude/feature_flags.json)r   N)__name__
__module____qualname____doc__strr   r   r+   r.   r/   r7   rM   r6   rN    r   r   r	   r	      sh    ;S 
h&C &D &3# 3d 3t 3)$ )4 )2t 2r   r	   )rR   r!   loggingr   rE   r   r   r   	getLoggerrO   r%   r4   r	   rT   r   r   <module>rW      sK   	   	  2 2			8	$yq!"A2 A2r   