"""code_stats - Projekt-Statistiken."""
import json
from db import execute_query, execute_single
def register_stats_tool(mcp):
"""Registriert code_stats Tool."""
@mcp.tool()
def code_stats() -> dict:
"""
Zeigt Projekt-Statistiken der Code-Analyse.
Returns:
Dict mit total_files, total_classes, total_interfaces, total_traits,
dependencies_by_type, top_used_classes
"""
# Basis-Statistiken - SQL aus PHP CodeAnalysisRepository::getStatistics() (Zeile 217-227)
stats_sql = """
SELECT
COUNT(*) as total_files,
SUM(line_count) as total_lines,
SUM(file_size) as total_size,
COUNT(CASE WHEN parse_error IS NOT NULL THEN 1 END) as files_with_errors,
MAX(scanned_at) as last_scan
FROM code_analysis
"""
stats = execute_single(stats_sql)
# Klassen/Interfaces/Traits zaehlen
classes_sql = "SELECT classes FROM code_analysis WHERE classes IS NOT NULL AND classes != '[]'"
rows = execute_query(classes_sql, max_rows=1000)
total_classes = 0
total_interfaces = 0
total_traits = 0
for row in rows:
classes = json.loads(row["classes"] or "[]")
for cls in classes:
cls_type = cls.get("type", "class")
if cls_type == "interface":
total_interfaces += 1
elif cls_type == "trait":
total_traits += 1
else:
total_classes += 1
# Dependency-Statistiken - SQL aus PHP CodeAnalysisRepository::getDependencyStatistics() (Zeile 343-351)
by_type_sql = """
SELECT dependency_type, COUNT(*) as cnt
FROM code_dependencies
GROUP BY dependency_type
"""
by_type_rows = execute_query(by_type_sql)
dependencies_by_type = {r["dependency_type"]: r["cnt"] for r in by_type_rows}
# Most used classes - SQL aus PHP CodeAnalysisRepository::getDependencyStatistics() (Zeile 354-360)
top_sql = """
SELECT target_fqcn as fqcn, COUNT(*) as count
FROM code_dependencies
GROUP BY target_fqcn
ORDER BY count DESC
LIMIT 20
"""
top_used = execute_query(top_sql)
# Total dependencies
total_deps_sql = "SELECT COUNT(*) as cnt FROM code_dependencies"
total_deps_row = execute_single(total_deps_sql)
return {
"total_files": stats["total_files"] or 0,
"total_lines": stats["total_lines"] or 0,
"total_classes": total_classes,
"total_interfaces": total_interfaces,
"total_traits": total_traits,
"files_with_errors": stats["files_with_errors"] or 0,
"last_scan": str(stats["last_scan"]) if stats["last_scan"] else None,
"total_dependencies": total_deps_row["cnt"] if total_deps_row else 0,
"dependencies_by_type": dependencies_by_type,
"top_used_classes": top_used,
}