#!/usr/bin/env python3
"""PushID/PopID denge analizi — imgui kimlik yığını sıkıntısı tarar.

Her .cpp/.hpp dosyasında:
- PushID sayısı vs PopID sayısı (dışsal denge)
- BeginPopup/BeginChild/BeginTabItem/BeginCombo/BeginMenu ile End eşleşmesi
- Nested açılma/kapanma sırası (stack benzeri)
"""
import re
import sys
from pathlib import Path

# Push/Pop çiftleri: Begin* ile End* eşleşmeli
BEGIN_TOKENS = [
    "BeginPopup", "BeginPopupModal", "BeginChild", "BeginTabBar",
    "BeginTabItem", "BeginCombo", "BeginMenu", "BeginPopupContextItem",
    "BeginPopupContextWindow", "BeginPopupContextVoid", "BeginGroup",
    "BeginTable", "BeginDragDropSource", "BeginDragDropTarget",
    "BeginListBox",
]
END_TOKENS = [
    "EndPopup", "EndPopupModal", "EndChild", "EndTabBar",
    "EndTabItem", "EndCombo", "EndMenu", "EndPopupContextItem",
    "EndPopupContextWindow", "EndPopupContextVoid", "EndGroup",
    "EndTable", "EndDragDropSource", "EndDragDropTarget",
    "EndListBox",
]

DUMMY = r"[A-Za-z_][A-Za-z0-9_]*"


def satirlar(path):
    try:
        return Path(path).read_text(encoding="utf-8", errors="replace").splitlines()
    except Exception:
        return []


def token_line(line):
    """Bir satırda hangi Begin/End/Push/Pop token'larının geldiğini döner."""
    out = []
    for tok in BEGIN_TOKENS + END_TOKENS:
        for m in re.finditer(r"\b" + tok + r"\s*\(", line):
            out.append(("B", tok))
    for tok in END_TOKENS:
        for m in re.finditer(r"\b" + tok + r"\s*\(", line):
            out.append(("E", tok))
    out.append(("P", "PushID" if "PushID" in line else "PopID"))
    return out


def analiz_dosya(path):
    sat = satirlar(path)
    # Basit satır tabanlı denge (nested'i tam çözemez, ama dengesizliği yakar)
    n_begin = sum([len(re.findall(r"\b" + t + r"\s*\(", "\n".join(sat))) for t in BEGIN_TOKENS])
    n_end = sum([len(re.findall(r"\b" + t + r"\s*\(", "\n".join(sat))) for t in END_TOKENS])
    n_push = sum([len(re.findall(r"\bPushID\b", "\n".join(sat)))])
    n_pop = sum([len(re.findall(r"\bPopID\b", "\n".join(sat)))])
    return (n_begin, n_end, n_push, n_pop)


def main():
    root = Path(sys.argv[1]) if len(sys.argv) > 1 else Path("uygulama/fikocad")
    files = sorted(root.rglob("*.cpp")) + sorted(root.rglob("*.hpp"))
    print(f"{'DOSYA':45} {'B/E':>5} {'P/P':>5}  DURUM")
    print("-" * 90)
    for f in files:
        b, e, p, q = analiz_dosya(f)
        durum = "OK"
        if b != e:
            durum = f"BEGIN/END dengesiz ({b}-{e})"
        elif p != q:
            durum = f"Push/Pop dengesiz ({p}-{q})"
        if b != e or p != q:
            print(f"{str(f.relative_to(root)):45} {b:>3}/{e:<2} {p:>3}/{q:<2}  {durum}")
    print("-" * 90)


if __name__ == "__main__":
    main()
