
    >i%                        U d Z ddlZddlZddlZddlZddlmZ ddlmZ ddl	m
Z
mZ  ed      Z	 ddlmZ  e       dgz   Zee   ed	<   d!defdZd!dedededededefdZd!dededee
   fdZd!dedededefdZd!dededee
   fdZd!dededefdZd Zd Zd Zd Z d Z!e"dk(  r7 e#ejH                        dkD  rejH                  d   d k(  r e!        y e         yy# e$ r g d
ZY w xY w)"u@  
Inbox 메시지 시스템
봇 간 inbox 디렉토리를 통해 JSON 메시지를 주고받는 유틸리티.

스펙:
- 파일명: YYYY-MM-DDTHH-MM-SS_from-<team>.json
- JSON 키: from, to, subject, body, timestamp, read
- read_inbox: unread(read=false)만 반환
- CLI: --from, --to, --subject, --body 플래그 방식
    N)datetime)Path)DictListz /home/jay/workspace/memory/inbox)get_dev_team_idsanuVALID_TEAMS)	dev1-team	dev2-team	dev3-teamr   basec                 Z    | xs t         }t        D ]  }||z  j                  dd        y)u1   모든 팀의 inbox 디렉토리를 생성한다.Tparentsexist_okN)
INBOX_BASEr	   mkdir)r   bteams      "/home/jay/workspace/inbox_utils.py_ensure_dirsr      s2    
A 6	
T56    	from_teamto_teamsubjectbodyreturnc                    |xs t         }||z  j                  dd       t        j                         }|j	                  d      }| d|  d}||z  |z  }	|	j                         r5|j	                  d      d|j                  dz  dz   }| d|  d}||z  |z  }	| ||||j                         d	d
}
|	j                  t        j                  |
d	d      d       |S )u<   메시지를 보낸다. 생성된 파일명을 반환한다.Tr   z%Y-%m-%dT%H-%M-%Sz_from-z.json-i  03dF)fromtor   r   	timestampread   ensure_asciiindentutf-8encoding)r   r   r   nowstrftimeexistsmicrosecond	isoformat
write_textjsondumps)r   r   r   r   r   r   r,   r#   filenamefilepathmessages              r   send_messager7   %   s    
A[t4
,,.C01IF9+U3H7{X%HLL!45!COOt<STW;X8YY	[yk7w;)]]_G 

7qIT[\Or   r   c                 :   |xs t         }|| z  }|j                         sg S g }t        |j                  d            D ]Z  }t	        j
                  |j                  d            }|j                  dd      r;|j                  |d<   |j                  |       \ |S )uE   해당 팀의 읽지 않은(unread) 메시지 목록을 반환한다.*.jsonr)   r*   r$   F	_filename)
r   r.   sortedglobr2   loads	read_textgetnameappend)r   r   r   	inbox_dirunreadfdatas          r   
read_inboxrF   >   s    
ADI	FINN8,-  zz!++w+78xx& !DMM$	 
 Mr   r4   c                     |xs t         }|| z  |z  }|j                         syt        j                  |j	                  d            }d|d<   |j                  t        j                  |dd      d       y)u@   메시지를 읽음 처리한다. 성공 여부를 반환한다.Fr)   r*   Tr$   r%   r&   )r   r.   r2   r=   r>   r1   r3   )r   r4   r   r   r5   rE   s         r   	mark_readrH   M   sp    
A4x("H??::h(('(:;DDL

4eAFQXYr   c                    |xs t         }|| z  }|j                         sg S g }t        |j                  d            D ]G  }t	        j
                  |j                  d            }|j                  |d<   |j                  |       I |S )u6   해당 팀의 전체 메시지 목록을 반환한다.r9   r)   r*   r:   )	r   r.   r;   r<   r2   r=   r>   r@   rA   )r   r   r   rB   messagesrD   rE   s          r   get_all_messagesrK   Y   s    
ADI	HINN8,- zz!++w+78FF[ Or   c                     |xs t         }|| z  }|j                         syd}|j                  d      D ]  }|j                          |dz  } |S )ub   해당 팀의 inbox를 비운다 (JSON 파일만 삭제). 삭제된 메시지 수를 반환한다.r   r9      )r   r.   r<   unlink)r   r   r   rB   countrD   s         r   clear_inboxrP   g   sZ    
ADIE^^H% 	

 Lr   c                     t        | j                  | j                  | j                  | j                        }t        t        j                  d|| j                  dd             y )Nsent)statusr4   r"   F)r'   )r7   r   r"   r   r   printr2   r3   )argsr4   s     r   cli_sendrV   w   sA    DNNDGGT\\499MH	$**HDGGL[`
abr   c                 p    t        | j                        }t        t        j                  |dd             y NFr%   r&   )rF   r   rT   r2   r3   rU   rJ   s     r   cli_readrZ   |   s%    $))$H	$**XE!
<=r   c                 p    t        | j                        }t        t        j                  |dd             y rX   )rK   r   rT   r2   r3   rY   s     r   cli_listr\      s%    		*H	$**XE!
<=r   c                     t        j                  d      } | j                  d      }|j                  dd      }|j	                  dd	d
d       |j	                  dd
d       |j	                  dd
d       |j	                  dd
d       |j                  dd      }|j	                  dd
d       |j                  dd      }|j	                  dd
d       | j                         }|j                  dk(  rt        |       y |j                  dk(  rt        |       y |j                  dk(  rt        |       y | j                          t        j                  d       y )Nu   inbox 메시지 시스템)descriptioncommand)destsendu   메시지 보내기)helpz--fromr   Tu   보내는 팀)r`   requiredrb   z--tou
   받는 팀)rc   rb   z	--subjectu   제목z--bodyu   본문r$   u   읽지 않은 메시지 조회z--teamu   팀명listu   전체 메시지 조회rM   )argparseArgumentParseradd_subparsers
add_parseradd_argument
parse_argsr_   rV   rZ   r\   
print_helpsysexit)parsersubp_sendp_readp_listrU   s         r   mainrs      sC   $$1LMF


Y

/C ^^F)>^?F
{TX
LA
dB
4h? ^^F)I^JF
4h? ^^F)B^CF
4h?D||v				r   c                  |   ddl } | j                         5 }t        |      }t        dddd|      }|j	                  d      s
J d	|        d
|v s
J d|        |dz  |z  }|j                         sJ d       t        j                  |j                  d            }|d   dk(  sJ d|d           |d   dk(  sJ d|d           |d   dk(  sJ d|d           |d   dk(  sJ d|d           |d   du sJ d       d|v sJ d       t        d       t        d|      }t        |      dk(  sJ dt        |              |d   d   dk(  sJ d|d   v sJ d        t        d!       t        d||      }|d"u sJ d#       t        j                  |j                  d            }|d   d"u sJ d$       t        d|      }	t        |	      dk(  sJ d%t        |	              t        d&       t        j                  d       t        d'dd(d)|       t        d|      }
t        |
      d*k(  sJ d+t        |
              t!        d, |
D              }|dk(  s
J d-|        t        d.       t#        d|      }|d*k(  s
J d/|        t        d|      }t        |      dk(  sJ d0t        |              t        d1       t        dd2|      }|du sJ d3       t        d4       t        d5dd6d7|       t        d|      }t        |      dk(  sJ d8t        |              |d   d   d6k(  sJ |d   d   d7k(  sJ t        d9       t        d'|      }t        |      dk(  sJ d:       t        d;       t#        d'|      }|dk(  s
J d<|        t        d=       ddd       t        d>       y# 1 sw Y   xY w)?uZ   assert 기반 단위 테스트 (임시 디렉토리 사용, 프로덕션 데이터 안전)r   Nr
   r   u   테스트 제목u   테스트 본문입니다)r   z_from-dev1-team.jsonu   파일명 형식 오류: Tu!   파일명에 T 구분자 없음: u'   메시지 파일이 생성되지 않음r)   r*   r!   u   from 필드 오류: r"   u   to 필드 오류: r   u   subject 오류: r   u   body 오류: r$   Fu!   read 초기값이 False가 아님r#   u   timestamp 필드 없음z[PASS] send_messagerM   u   unread 수 오류: r:   u    _filename 메타데이터 없음z[PASS] read_inbox (unread only)Tu   mark_read 실패u-   read 플래그가 True로 변경되지 않음u-   mark_read 후 unread가 비어있지 않음: z[PASS] mark_readr   u
   두 번째u   내용2r%   u   전체 메시지 수 오류: c              3   ,   K   | ]  }|d    s	d  yw)r$   rM   N ).0ms     r   	<genexpr>zrun_tests.<locals>.<genexpr>   s     :q&	:s   
u   읽은 메시지 수 오류: z[PASS] get_all_messagesu   삭제 수 오류: u   clear 후 메시지 남음: z[PASS] clear_inboxznonexistent.jsonu0   존재하지 않는 파일에 대해 True 반환z[PASS] mark_read (nonexistent)r   u   한글 제목u$   이모지와 한글 본문 테스트u   UTF-8 메시지 수 오류: z[PASS] UTF-8 encodingu#   빈 inbox에서 메시지 반환됨z[PASS] empty inboxu/   빈 inbox clear 시 삭제 수가 0이 아님: z[PASS] clear empty inboxu&   
=== 모든 테스트 통과 (9/9) ===)tempfileTemporaryDirectoryr   r7   endswithr.   r2   r=   r>   rT   rF   lenrH   _timesleeprK   sumrP   )r{   tmpdirr   fnamefpathrE   rC   resultdata2unread2all_msgs
read_countcleared	remainingresult2msgsemptycleared2s                     r   	run_testsr      sq   		$	$	& J*&F| [%1CE`gkl~~45Z9RSXRY7ZZ5e|H@HH|uu$||~HHH~zz%//7/;<F|{*Q.B4<.,QQ*DzU"E&8d$EE"I"44Z8HiHY6ZZ4F|::ZmDQWL><ZZ:F|u$I&II$d"=$=="#$ E-6{aD#6s6{m!DDay#'9999fQi'K)KK'/0 5%d3~111~

5??G?<=V}$U&UU$ U.7|q `$QRUV]R^Q_"``  ! 	A[%ytL#E58}!R%B3x=/#RR!:H::
QL"?
| LL'( e$/!|<27)<<|$U6	9~"S&B3y>BR$SS""# E#5DA%S!SS./ 	[+@fmqr+D14yA~I!=c$i[II~Awy!_444Awv"HHHH%& ;T25zQE EE"# {61}Z OPXzZZ}()UJ*X 

34YJ* J*s   N	N22N;__main__rM   test)N)%__doc__re   r2   rl   timer   r   pathlibr   typingr   r   r   utils.org_loaderr   _get_dev_team_idsr	   rd   str__annotations__ImportErrorr   r7   rF   boolrH   rK   intrP   rV   rZ   r\   rs   r   __name__r~   argvrw   r   r   <module>r      sn  	   
    45
AF.0E7:Kc:
6t 6C #  3 d ^a 2S  T
 	C 	3 	d 	d 	3 d d4j 
c 
 
 
 c
>
>
DP5f z
388}qSXXa[F2	 C  A@KAs   C" "	C.-C.