
    (<iW7                        d Z ddl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	  e	ej                  j                  dd            ZdZdej                  d	efd
Zdej                  dee   d	efdZde	d	efdZde	d	efdZde	d	efdZde	deded	efdZde	deded	efdZde	deded	efdZde	deded	efdZde	d	e	fdZefde	ded	ee	   fdZddZe dk(  r e        yy)uh  대용량 파일 요약 생성 스크립트.

지정된 파일 또는 자동 감지된 25KB+ 파일에 대해 *.summary.md 파일을 생성합니다.

사용법:
    python3 scripts/generate_file_summaries.py /path/to/file.py
    python3 scripts/generate_file_summaries.py --auto
    python3 scripts/generate_file_summaries.py --auto --dir /home/jay/workspace
    N)date)PathWORKSPACE_ROOTz/home/jay/workspacei d  nodereturnc                 &   t        | t        j                  t        j                  t        j                  f      sy| j
                  rt        | j
                  d   t        j                        rt        | j
                  d   j                  t        j                        rst        | j
                  d   j                  j                  t              rB| j
                  d   j                  j                  j                         j                         d   S y)u5   AST 노드에서 docstring 첫줄을 추출합니다. r   )
isinstanceastFunctionDefAsyncFunctionDefClassDefbodyExprvalueConstantstrstrip
splitlines)r   s    P/home/jay/workspace/.worktrees/task-2057-dev2/scripts/generate_file_summaries.py_get_docstring_first_liner      s    dS__c.B.BCLLQR		tyy|SXX.tyy|))3<<8tyy|))//5yy|!!''--/::<Q??    _source_linesc                 >    t        | dd      }||S t        | dd      S )u6   AST 노드의 마지막 줄 번호를 반환합니다.
end_linenoNlineno   )getattr)r   r   ends      r   _node_end_liner    )   s)    
$d
+C

41%%r   filepathc           
         | j                  dd      }|j                         }	 t        j                  |      }g }g }t        j                  |      D ]I  }t        |t        j                        rg }t        j                  |      D ]j  }	t        |	t        j                  t        j                  f      s.|j                  |	j                  |	j                  t        |	|      t        |	      d       l |j                  |j                  |j                  t        ||      t        |      |d       t        |t        j                  t        j                  f      s|j                  |j                  |j                  t        ||      t        |      d       L ||dS # t        $ r}t        |      g g dcY d}~S d}~ww xY w)	uP   Python 파일을 ast로 파싱하여 클래스/함수 구조를 반환합니다.utf-8replaceencodingerrors)errorclasses	functionsN)namestartr   doc)r+   r,   r   r-   methods)r)   r*   )	read_textr   r   parseSyntaxErrorr   iter_child_nodesr
   r   r   r   appendr+   r   r    r   )
r!   sourcesource_linestreeer)   top_functionsr   r.   childs
             r   parse_python_filer:   1   s   CF$$&LAyy  GM$$T* dCLL)G--d3 ecoos7K7K%LMNN %

!&-e\B8?	$  NN		%dL906"  s0D0DEF  		%dL906	" '4 ];;A  AQBR@@As   F% %	G.G<GGc                 *   | j                  dd      }|j                         }g }g }g }t        j                  d      }t        j                  d      }t        j                  d      }t        j                  d      }	t	        |d	      D ]   \  }
}|j                         }|j                  |      }|r2|j                  |j                  d      j                         |
d
       \|j                  |      }|r$|j                  |j                  d      |
d
       |j                  |      }|r$|j                  |j                  d      |
d
       |	j                  |      }|s|j                  |j                  d      |
d
        |||dS )ub   JS/TS 파일을 정규식으로 파싱하여 컴포넌트/함수/섹션 구조를 반환합니다.r#   r$   r%   u@   (?:/\*|//)\s*[─\-─━]+\s*(.+?)\s*[─\-─━]+\s*(?:\*/)?$zN^(?:export\s+)?(?:default\s+)?(?:const|function)\s+([A-Z][a-zA-Z0-9_]*)\s*[=(]zA^(?:export\s+)?(?:async\s+)?function\s+([a-z_][a-zA-Z0-9_]*)\s*\(zB^(?:export\s+)?const\s+([a-z_][a-zA-Z0-9_]*)\s*=\s*(?:async\s+)?\(r   r,   )r+   line)
componentsr*   sections)
r/   r   recompile	enumerater   searchr3   groupmatch)r!   r4   linesr>   r*   r?   section_patterncomponent_patternfunc_patternarrow_func_patternir=   strippedms                 r   parse_js_filerN   ]   sp   CFEJIH jj!deO

#tu::bcL$ijU!, >4::<""8,OOQWWQZ%5%5%7CD##H-qwwqz1=>x(aggaj!<=$$X.aggaj!<=!>$ %9(SSr   c                 d   | j                  dd      }|j                         }g }t        j                  d      }t	        |d      D ]c  \  }}|j                  |      }|s|j                  t        |j                  d            |j                  d      j                         |d       e d	|iS )
u9   Markdown 파일에서 # 헤딩 구조를 추출합니다.r#   r$   r%   z^(#{1,6})\s+(.+)$r   r<      )leveltitler=   headings)
r/   r   r@   rA   rB   rE   r3   lenrD   r   )r!   r4   rF   rS   heading_patternrK   r=   rM   s           r   parse_md_filerV      s    CFEHjj!56OU!, 4!!$'OOQWWQZ))+  !!r   size_kbtotal_linesc                    t        |       }t        j                         j                         }d| j                   dd| d| d| dddg}|j                  d	      r|j                  d
|d	           n|j                  dg       }|j                  dg       }|r|j                  d       |D ]  }|d   rd|d    nd}	|j                  d|d    d|d    d|d    d|	        |j                  dg       D ]7  }
|
d   rd|
d    nd}|j                  d|
d    d|
d    d|
d    d|        9  |rM|j                  d       |D ]7  }|d   rd|d    nd}|j                  d|d    d|d    d|d    d|        9 |j                  d       |j                  d       |j                  d      rA|d   d d D ]6  }|j                  d|d    d |d    dt        |d   d!z   |d          d"       8 |j                  d      r1|d   d d D ]&  }|j                  d|d    d#|d    d|d    d"       ( d$j                  |      d$z   S )%N#     요약   > 자동 생성:     | 원본: KB,    줄r	   	   ## 구조r(   u   
> 파싱 오류: r)   r*   u   
### 클래스r-   u    — - **r+   	** (line r,   -r   )r.   z  - `` (line u   
### 독립 함수- `   
## 참조 가이드ut   _아래 항목은 키워드로 내용 찾기 예시입니다. offset/limit으로 해당 줄 범위만 읽으세요._   -     관련: line 2   u    읽기u   ` 함수: line 
)	r:   r   today	isoformatr+   getr3   minjoin)r!   rW   rX   datarm   rF   r)   r*   clsdoc_partmethodmdocfnfdocs                 r   _make_summary_pythonry      s   X&DJJL""$E
X]]O7#
E7+gYd;-sK
	E xx*4=/:;((9b)HH["-	LL*+ k36u:U3u:,/2tCK=	#g,qUTUV^U_`a!ggi4 kF6<UmU6%=/2DLL5(8@QQRSYZ_S`Raabcgbh!ijkk LL./ Y.0ir%yk*Rs2f:,hr'{m1RYKqQUPVWXY 
LL()	LL  H  Ixx		?2A& 	uCLL2c&k].WaCPWL[]L]_bch_iHjGkkrst	uxx{#BQ' 	\BLL3r&zl/"W+a5	{RYZ[	\ 99Ud""r   c                    t        |       }t        j                         j                         }d| j                   dd| d| d| dddg}|j                  d	g       }|j                  d
g       }|j                  dg       }|r6|j                  d       |D ]   }	|j                  d|	d    d|	d    d       " |r6|j                  d       |D ]   }
|j                  d|
d    d|
d    d       " |r6|j                  d       |D ]   }|j                  d|d    d|d    d       " |j                  d       |j                  d       |d d D ]   }	|j                  d|	d    d|	d    d       " dj                  |      dz   S )NrZ   r[   r\   r]   r^   r_   r	   r`   r?   r>   r*   u   
### 섹션 마커ri   r+    (line r=   rd   u   
### 컴포넌트ra   rb   u   
### 함수rf   re   rg   u7   _offset/limit으로 해당 줄 범위만 읽으세요._rh   rj   u    부근 읽기rl   )rN   r   rm   rn   r+   ro   r3   rq   )r!   rW   rX   rr   rm   rF   r?   r>   r*   scrw   s               r   _make_summary_jsr~      s   "DJJL""$E
X]]O7#
E7+gYd;-sK
	E xx
B'H,+Jb)I*+ 	>ALL2ai[&	{!<=	> )* 	BALL4&	{)AfI;a@A	B ^$ 	BBLL3r&zl(2f:,a@A	B 
LL()	LLJKbq\ Nr!F)N1V9+^LMN 99Ud""r   c                 V   t        |       }t        j                         j                         }d| j                   dd| d| d| dddg}|j                  d	g       D ]6  }d
|d   dz
  z  }|j                  | dd|d   z   d|d    d|d    d       8 dj                  |      dz   S )NrZ   r[   r\   r]   r^   r_   r	   u   ## 헤딩 구조rS   z  rQ   r   ri   # rR   r{   r=   rd   rl   )rV   r   rm   rn   r+   ro   r3   rq   )r!   rW   rX   rr   rm   rF   hindents           r   _make_summary_mdr      s    "DJJL""$E
X]]O7#
E7+gYd;-sK
	E XXj"% V7a(xr#'
"2!31QwZL&	{RSTUV 99Ud""r   c           	      x    t        j                         j                         }d| j                   d| d| d| d	S )NrZ   u    요약
> 자동 생성: r]   r^   uf   줄

## 참고
지원되지 않는 파일 형식입니다. offset/limit으로 분할 읽기하세요.
)r   rm   rn   r+   )r!   rW   rX   rm   s       r   _make_summary_genericr      sI    JJL""$E
X]]O !7+gYd;- Hc	dr   c           
      Z   | j                         } | j                         st        d|        | j                         j                  }t        |dz  d      }| j                  dd      }|j                  d      dz   }| j                  j                         }|dk(  rt        | ||      }n2|d	v rt        | ||      }n |d
k(  rt        | ||      }nt        | ||      }| j                  | j                  dz   z  }|j!                  |d       t#        d| d| dt%        |       d       |S )uE   파일 요약을 생성하고 *.summary.md 경로를 반환합니다.u#   파일을 찾을 수 없습니다:    r   r#   r$   r%   rl   z.py)z.jsz.tsz.jsxz.tsxz.md.summary.md)r&   z[OK] z (u   KB → z chars))resolveis_fileFileNotFoundErrorstatst_sizeroundr/   countsuffixlowerry   r~   r   r   parentr+   
write_textprintrT   )r!   
size_bytesrW   r4   rX   r   contentsummary_paths           r   generate_summaryr     s+   !H"EhZ PQQ((JJ%q)GCF,,t$q(K__""$F&x+F	1	1"8WkB	5"8WkB'';G??hmmm&CDLGg6	E,r''#g,w
GHr   root	min_bytesc                 z   g }h d}t        j                  |       D ]t  \  }}}|D cg c]	  }||vs| c}|dd |D ]Q  }|j                  d      rt        |      |z  }		 |	j	                         j
                  |k\  r|j                  |	       S v |j                  d d       |S c c}w # t        $ r Y |w xY w)u@   root 하위에서 min_bytes 이상인 파일을 수집합니다.>   .git.venvlogsvenvoutput__pycache__node_modulesNr   c                 6    | j                         j                  S )N)r   r   )ps    r   <lambda>z)auto_detect_large_files.<locals>.<lambda>,  s    qvvx// r   T)keyreverse)	oswalkendswithr   r   r   r3   OSErrorsort)
r   r   results	skip_dirsdirpathdirnames	filenamesdfnamefps
             r   auto_detect_large_filesr     s    GZI(* 
$9"*AQay.@qA 	E~~m,g&B779$$	1NN2&	
 LL/L>N B  s   	B)B)!.B..	B:9B:c                     t        j                  dt         j                  d      } | j                  ddd       | j                  dd	d
       | j                  dt        t
        d       | j                  dt        t        d       | j                         }g }|j                  r"|j                  D cg c]  }t	        |       }}|j                  rft        |j                  |j                        }t        dt        |       d|j                  dz   d|j                          |j!                  |       |s%| j#                          t%        j&                  d       t)               }g }|D ]9  }|j+                         }||vs|j-                  |       |j/                  |       ; d}	|D ]  }
	 t1        t	        |
              |	r5t        d|	 dt$        j4                         t%        j&                  d       y t        dt        |       d       y c c}w # t2        $ r0}t        d|
 d| t$        j4                         |	dz  }	Y d }~d }~ww xY w)Nu+   대용량 파일 요약 생성 스크립트u   예시:
  python3 scripts/generate_file_summaries.py /path/to/file.py
  python3 scripts/generate_file_summaries.py --auto
  python3 scripts/generate_file_summaries.py --auto --dir /home/jay/workspace/dashboard
)descriptionformatter_classepilogfiles*u   요약할 파일 경로(들))nargshelpz--auto
store_trueu1   25KB+ 파일을 자동 감지하여 요약 생성)actionr   z--diru<   --auto 시 탐색할 루트 디렉토리 (기본: WORKSPACE))typedefaultr   z
--min-sizeu5   --auto 시 최소 파일 크기(bytes, 기본: 25600))r   z[auto] u   개 파일 감지됨 (>= r   zKB) in r   r   z[ERROR] z: )filerl   u   개 파일 처리 실패.u	   
완료: u   개 파일 요약 생성.)argparseArgumentParserRawDescriptionHelpFormatteradd_argumentr   	WORKSPACEintAUTO_DETECT_MIN_BYTES
parse_argsr   autor   dirmin_sizer   rT   extend
print_helpsysexitsetr   addr3   r   	Exceptionstderr)parserargstargetsfdetectedseenunique_targetstrpr'   r   r7   s               r   mainr   2  s0   $$A <<F s1OP
@  
 K	   %D	   DGzz$(JJ/q47//yy*488t}}MH&?QU@U?VV]^b^f^f]ghix  eD!#N %YY[T>HHRL!!!$	% F 	T"X& 6(343::F
3~.//HIJA 00  	HRD1#&SZZ8aKF	s   5H4H	I(&II__main__)r   N)!__doc__r   r   r   r@   r   datetimer   pathlibr   environro   r   r   ASTr   r   listr   r    dictr:   rN   rV   floatry   r~   r   r   r   r   r   __name__ r   r   <module>r      s    
 	 	 
    02GHI	! 
CGG  & &c &s &'< '< '<X#TD #TT #TP"D "T "&(#4 (#% (#c (#c (#V"#t "#e "## "## "#J#t #e ## ## # D 5 s s t  6 :O $ 3 SWX\S] *AKH zF r   