
    Ki]              	         d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	 ddl
mZmZmZ dd	lmZmZ dd
lmZmZmZ ddlmZ ddlmZmZ  ej4                  e      ZdddddddddZ	 	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 d	 	 	 	 	 	 	 	 	 d dZ	 	 	 	 	 	 d!	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d"dZ d#d$dZ!	 	 	 	 	 d%	 	 	 	 	 	 	 	 	 	 	 d&dZ"	 	 	 	 d'	 	 	 	 	 	 	 	 	 	 	 d(dZ#y))z4Tools 2, 3, 5, 6, 9: query / search / stats helpers.    )annotationsN)Path)Any   )EmbeddingStore)_sanitize_nameedge_to_dictnode_to_dict)generate_hintsget_session)get_changed_filesget_db_pathget_staged_and_unstaged)hybrid_search   )_BUILTIN_CALL_NAMES
_get_storez-Find all functions that call a given functionz-Find all functions called by a given functionz*Find all imports of a given file or modulez1Find all files that import a given file or modulez+Find all nodes contained in a file or classz,Find all tests for a given function or classz0Find all classes that inherit from a given classz$Get a summary of all nodes in a file)
callers_of
callees_of
imports_ofimporters_ofchildren_of	tests_forinheritors_offile_summaryc           
        t        |      \  }}	 | t        ||      } | st        |      } | sddg g g ddd|j                          S | D cg c]  }t	        ||z         }	}|j                  |	||      }
|
d   D cg c]  }t        |       }}|
d	   D cg c]  }t        |       }}|
d
   D cg c]  }t        |       }}|
d   }|
d   }dt        |        ddt        |       ddt        |       d| ddt        |
d          dg}|r!|j                  dt        |       d| d       |dk(  rft        |      }|dkD  rd}n
|dkD  rd}nd}|dd D cg c]  }|d   	 }}ddj                  |      |t        |
d         ||d |j                          S ddj                  |      | |||
d   |||d!	|j                          S c c}w c c}w c c}w c c}w c c}w # |j                          w xY w)"a  Analyze the blast radius of changed files.

    Args:
        changed_files: Explicit list of changed file paths (relative to repo root).
                       If omitted, auto-detects from git diff.
        max_depth: How many hops to traverse in the graph (default: 2).
        max_results: Maximum impacted nodes to return (default: 500).
        repo_root: Repository root path. Auto-detected if omitted.
        base: Git ref for auto-detecting changes (default: HEAD~1).
        detail_level: "standard" (full output) or "minimal" (summary only).

    Returns:
        Changed nodes, impacted nodes, impacted files, connecting edges,
        plus ``truncated`` flag and ``total_impacted`` count.
    NokzNo changed files detected.Fr   )statussummarychanged_nodesimpacted_nodesimpacted_files	truncatedtotal_impacted)	max_depth	max_nodesr    r!   edgesr#   r$   zBlast radius for z changed file(s):z  - z nodes directly changedz nodes impacted (within z hops)r"   z additional files affectedz  - Results truncated: showing z of z impacted nodesminimal   high   mediumlowname
)r   r   riskimpacted_file_countkey_entitiesr#   )	r   r   changed_filesr    r!   r"   r'   r#   r$   )r   r   r   closestrget_impact_radiusr
   r	   lenappendjoin)r3   r%   max_results	repo_rootbasedetail_levelstorerootf	abs_filesresultnchanged_dictsimpacted_dictse
edge_dictsr#   r$   summary_partsimpacted_countr0   r2   s                         i/home/jay/workspace/scripts/.codegraph-venv/lib/python3.12/site-packages/code_review_graph/tools/query.pyr6   r6   "   s   . Y'KE4I -dD9M  7 =7!#"$"$""#D 	o -::qS]:	:((k ) 
 392IJQaJJ39:J3KLa,q/LL/5g?!l1o?
?;'	 01  M 233DE3}%&&=>3~&''?	{&Q3v./011KL	
   1#n2E1F~&o7
 9$ 0N"!##1"1#5&	L  99]3'*62B+C'D ,&* 	 yy/**,$%56",

 	o ;
 KL?00 	sZ   &G& G& G G& =G	G& G*	G& 3GBG& G!)%G& G& G& &G8c           
     T   t        |      \  }}	 | t        vr6dd|  dt        t        j                                d|j	                          S g }g }| dk(  r1|t
        v r)d|vr%d| |t        |    d| d	g g d
|j	                          S |j                  |      }|st        ||z        }	|j                  |	      }|sr|j                  |d      }
t        |
      dk(  r|
d   }|j                  }n?t        |
      dkD  r1dd| d|
D cg c]  }t        |       c}d|j	                          S |s| dk7  rdd| dd|j	                          S |r|j                  n|}| dk(  r|j                  |      D ]c  }|j                  dk(  s|j                  |j                        }|r|j                  t        |             |j                  t!        |             e |s|r|j#                  |j$                        D ]S  }|j                  |j                        }|r|j                  t        |             |j                  t!        |             U n| dk(  ry|j'                  |      D ]c  }|j                  dk(  s|j                  |j(                        }|r|j                  t        |             |j                  t!        |             e n| dk(  r_|j'                  |      D ]I  }|j                  dk(  s|j                  d|j(                  i       |j                  t!        |             K n<| dk(  r|t        ||z  j+                               n|j,                  }	|j                  |	      D ]T  }|j                  dk(  s|j                  |j                  |j,                  d       |j                  t!        |             V n| d k(  r`|j'                  |      D ]J  }|j                  d!k(  s|j                  |j(                        }|s1|j                  t        |             L n>| d"k(  r|j                  |      D ]J  }|j                  d#k(  s|j                  |j                        }|s1|j                  t        |             L |r|j$                  n|}|j                  d$| d%      }||j                  d&| d%      z  }|D ch c]  }|j/                  d'       }}|D ]8  }|j                  |vs|j0                  s|j                  t        |             : n?| d(k(  r|j                  |      D ]b  }|j                  d)v s|j                  |j                        }|r|j                  t        |             |j                  t!        |             d |s|rd)D ]u  }|j#                  |j$                  |*      D ]S  }|j                  |j                        }|r|j                  t        |             |j                  t!        |             U w nE| dk(  r@t        ||z        }|j3                  |      }|D ]  }|j                  t        |              d+t        |       d,|  d-| d.}|d/k(  rT|dd D cg c]  }d0D ci c]  }||v r|||    c} }}}d| |t        |    |t        |      |d1|j	                          S d| |t        |    |||d
|j	                          S c c}w c c}w c c}w c c}}w # |j	                          w xY w)2a  Run a predefined graph query.

    Args:
        pattern: Query pattern. One of: callers_of, callees_of, imports_of,
                 importers_of, children_of, tests_for, inheritors_of, file_summary.
        target: The node name, qualified name, or file path to query about.
        repo_root: Repository root path. Auto-detected if omitted.
        detail_level: "standard" (full output) or "minimal" (summary only).

    Returns:
        Matching nodes and edges for the query.
    errorzUnknown pattern 'z'. Available: )r   rL   r   z::r   'u<   ' is a common builtin — callers_of skipped to avoid noise.)r   patterntargetdescriptionr   resultsr'   r+   limitr   r   	ambiguouszMultiple matches for 'z'. Please use a qualified name.)r   r   
candidatesr   	not_foundzNo node found matching 'z'.)r   r   CALLSr   r   IMPORTS_FROMimport_targetr   N)importerfiler   CONTAINSr   	TESTED_BYtest_
   Testqualified_namer   )INHERITS
IMPLEMENTS)kindFound z result(s) for z('z')r(   )r.   rd   	file_path)r   rN   rO   rP   r   result_countrQ   )r   _QUERY_PATTERNSlistkeysr4   r   get_noder5   search_nodesr7   ra   r
   get_edges_by_targetrd   source_qualifiedr8   r	   search_edges_by_target_namer.   get_edges_by_sourcetarget_qualifiedresolverf   getis_testget_nodes_by_file)rN   rO   r;   r=   r>   r?   rQ   	edges_outnode
abs_targetrU   cqnrF   callercalleechildtestr.   
test_nodesrseentrd   abs_path
file_nodesrC   r   kminimal_resultss                                 rJ   query_graphr      s-   $ Y'KE4{/)!'y 1""&';';'=">!?Ar 	c ! "	 |#--F" 7f.w7x  = = L 	w ~~f%TF]+J>>*-D++F!+<J:!#!!},,Z1$)0 97 7 =G"Gq<?"G` 	O >1%5fXR@L 	C %)T  fl"..r2 666W$"^^A,>,>?F|F';<$$\!_56 t::499E 6A"^^A,>,>?F|F';<$$\!_5	6 $..r2 666W$"^^A,>,>?F|F';<$$\!_56 $..r2 666^+NNOQ5G5G#HI$$\!_56
 &
 37,TF]++-.^^  ..z: 666^+NN$%$6$6 !$  $$\!_56 %..r2 <66Z'!NN1+=+=>E|E':;	< #..r2 ;66[( >>!*<*<=D|D'9:	; !%499&D++eD6N"+EJ%,,tD6]",EEJ5<=AEE*+=D= 4##4/AIINN<?34 '..r2 66677!NN1+=+=>E|E':;$$\!_56 t6 :D">>tyyt>T : %q/A/A B #NN<+>?!((a9	:: &4&=)H00:J 0|A/0 S\N #)2fXR) 	
 9$ !!  ;Av qtGO  " .w7" #G*( 	 *73
 	U #HV >H8 	s   -\ )\ A?\ \ \ .\ 8\ C4\ <A=\ :B\ A.\ 7\ A\ \ :A\ \1\ \ A\ D9\ 	\\
-\2\ \  
\ 
\\ \'c           
        t        |      \  }}	 t        || ||||      }	d}
|	sd}
dt        |	       d|  d|rd| dnd	z   }|d
k(  rB|	dd D cg c]  }dD ci c]  }||v r|||    c} }}}d| |
||d|j                          S d| |
||	d}t	        d|t                     |d<   ||j                          S c c}w c c}}w # |j                          w xY w)a  Search for nodes by name, keyword, or semantic similarity.

    Uses hybrid search (FTS5 BM25 + vector embeddings merged via Reciprocal
    Rank Fusion) as the primary search path, with graceful fallback to
    keyword matching.

    Args:
        query: Search string to match against node names and qualified names.
        kind: Optional filter by node kind (File, Class, Function, Type, Test).
        limit: Maximum results to return (default: 20).
        repo_root: Repository root path. Auto-detected if omitted.
        context_files: Optional list of file paths. Nodes in these files
            receive a relevance boost.
        detail_level: "standard" (full output) or "minimal" (summary only).

    Returns:
        Ranked list of matching nodes.
    )rd   rS   context_filesmodelhybridkeywordre   z node(s) matching 'rM    (kind=) r(   Nr+   )r.   rd   rf   scorer   )r   querysearch_moder   rQ   semantic_search_nodes_hints)r   r   r7   r4   r   r   )r   rd   rS   r;   r   r   r=   r>   r?   rQ   r   r   r   r   r   rB   s                   rJ   r   r   a  s8   6 Y'KE4+5t5

 #K3w<.(;E7!D!%gdV12
 9$ !!  DAv qtGO  *"*( 	 &%
 *#V[]
x 78 	s6   AC 	CB=+C0
C !C =CC Cc                   t        |       \  }}	 |j                         }d|j                   dd|j                   d|j                   d|j
                   d|j                  rdj                  |j                        nd d	|j                  xs d
 ddg}t        |j                  j                               D ]  \  }}|j                  d| d|         |j                  d       |j                  d       t        |j                  j                               D ]  \  }}|j                  d| d|         t        t        |            }	 |j!                         }|j                  d       |j                  d| d       |j"                  s|j                  d       |j%                          ddj                  |      |j                  |j
                  |j                  |j                  |j                  |j                  |j                  |d
|j%                          S # |j%                          w xY w# |j%                          w xY w)zGet aggregate statistics about the knowledge graph.

    Args:
        repo_root: Repository root path. Auto-detected if omitted.

    Returns:
        Total nodes, edges, breakdown by kind, languages, and last update time.
    zGraph statistics for :z	  Files: z  Total nodes: z  Total edges: z  Languages: z, nonez  Last updated: neverr   zNodes by kind:  z: zEdges by kind:zEmbeddings: z nodes embeddedz5  (install sentence-transformers for semantic search)r   r/   )
r   r   total_nodestotal_edgesnodes_by_kindedges_by_kind	languagesfiles_countlast_updatedembeddings_count)r   	get_statsr.   r   r   r   r   r9   r   sortedr   itemsr8   r   r   r   count	availabler4   )	r;   r>   r?   statsrH   rd   r   	emb_store	emb_counts	            rJ   list_graph_statsr     s6    Y'KE4.! $DII;a0))*+e//01e//01%//DIIeoo6vVWu11<W=>	
 "%"5"5";";"=> 	7KD%  2dV2eW!56	7R -.!%"5"5";";"=> 	7KD%  2dV2eW!56	7 #;t#45			!)I  $  <	{/!JK&&$$K OO yy/ ,, ,,"00"00 ,,!.. )
 	 OO 	s&   EH? AH* (A1H? *H<<H? ?Ic                \   t        |      \  }}	 |j                  | |||      }g }|D ]  }	t        |	      }
|	j                  r(|	j                  r|	j                  |	j                  z
  dz   nd|
d<   	 t        t        |	j                        j                  |            |
d<   |j                  |
        dt        |       d|  d|rd	| d
ndz   |rd| dndz   dz   g}|dd D ]4  }|j                  d|d   dd|d   dd|d    d|d    d|d    d
       6 t        |      dkD  r!|j                  dt        |      dz
   d       ddj                  |      t        |      | |d|j                          S # t        $ r |	j                  |
d<   Y w xY w# |j                          w xY w)a\  Find functions, classes, or files exceeding a line-count threshold.

    Useful for identifying decomposition targets, code-quality audits,
    and enforcing size limits during code review.

    Args:
        min_lines: Minimum line count to flag (default: 50).
        kind: Filter by node kind: Function, Class, File, or Test.
        file_path_pattern: Filter by file path substring (e.g. "components/").
        limit: Maximum results (default: 50).
        repo_root: Repository root path. Auto-detected if omitted.

    Returns:
        Oversized nodes with line counts, ordered largest first.
    )	min_linesrd   file_path_patternrS   r   r   
line_countrelative_pathre   z node(s) with >= z linesr   r   r   z matching 'rM   r   Nr_   r   z>4z	 lines | rd   z>8z | r.   z (
line_startz
  ... and z morer   r/   )r   r   total_foundr   rQ   )r   get_nodes_by_sizer
   r   line_endr5   r   rf   relative_to
ValueErrorr8   r7   r9   r4   )r   rd   r   rS   r;   r>   r?   nodesrQ   rC   drH   r   s                rJ   find_large_functionsr     s   , Y'KE4-''/	 ( 
  	AQA <<AJJ all*Q. lO1%(akk):)F)Ft)L%M/" NN1	 S\N"3I;fE$(a b25F./q1BP 
 " 	A  Q|_R(	!F)BsV9+R/ 231Q|_4EQH	
 w<"  :c'lR.?-@!FG yy/w<"
 	5  1%&[[/"14 	s1   A F 10E;!C	F ;FF FF F+c                   t        |      \  }}	 t        || d      }|sd|  dg d|j                          S |d   d   }t        dt	        |d            }i }	|dfg}
g }d}|
r=|d	k(  r|
j                  d      \  }}n|
j                         \  }}||	v r5||kD  r;||	|<   |j                  |      }|sTt        |j                        |j                  |j                  |j                  |d
}|t        t        |            dz  z  }||kD  rn|j                  |       |j                  |      }|j!                  |      }|D ])  }|j"                  }||	vs|
j                  ||dz   f       + |D ])  }|j$                  }||	vs|
j                  ||dz   f       + |
r=|||t        |      |||kD  ddgd|j                          S # |j                          w xY w)aH  BFS/DFS traversal from best-matching node.

    Args:
        query: Search string to find the starting node.
        mode: "bfs" (breadth-first) or "dfs" (depth-first).
        depth: Max traversal depth (1-6). Default: 3.
        token_budget: Approximate token limit for results.
        repo_root: Repository root path.
    r   rR   zNo node matching 'rM   )rL   r   r   ra      bfs)r.   ra   rd   r[   depth   z4query_graph callers_of -- focused relationship queryz*get_impact_radius -- blast radius analysis)
start_nodemoder%   nodes_visited	traversalr#   next_tool_suggestions)r   r   r4   maxminpoprk   r   r.   ra   rd   rf   r7   r5   r8   rp   rm   rq   rn   )r   r   r   token_budgetr;   r>   r?   rQ   start_qnvisitedqueuer   approx_tokens
current_qn	cur_depthrw   entry	out_edgesin_edgesrF   tgtsrcs                         rJ   traverse_graph_funcr   <  s8     Y'KE4OuA6-eWA6X 	O 1:./As5!}% #%qM(
 !#	u}(-		!%
I(-		%
IW$5 "+GJ>>*-D 'tyy1"&"5"5		"E SU_11M|+U# 11I 00H  7((g%LL#y1}!567  7((g%LL#y1}!567Q \ # ^"&51,&
 	s#   G
 DG
 -G
 G
 "G
 
G)Nr   i  NzHEAD~1standard)r3   list[str] | Noner%   intr:   r   r;   
str | Noner<   r5   r=   r5   returndict[str, Any])Nr   )
rN   r5   rO   r5   r;   r   r=   r5   r   r   )Nr)   NNNr   )r   r5   rd   r   rS   r   r;   r   r   r   r   r   r=   r5   r   r   )N)r;   r   r   r   )2   NNr   N)r   r   rd   r   r   r   rS   r   r;   r   r   r   )r      i  N)r   r5   r   r5   r   r   r   r   r;   r   r   r   )$__doc__
__future__r   loggingpathlibr   typingr   
embeddingsr   graphr   r	   r
   hintsr   r   incrementalr   r   r   searchr   _commonr   r   	getLogger__name__loggerrh   r6   r   r   r   r   r        rJ   <module>r      s#   : "    ' > > / Q Q " 4			8	$ BA>G@?G:	 '+ "a#aa a 	a
 a a aX !"	NNN N 	N
 Np  &*"GG
G G 	G
 $G G G G^8B $( DD
D "D 	D
 D D\  ``
` ` 	`
 ` `r   