#!/usr/bin/env python3
"""Fonksiyon bazlı ImGui kimlik/çerçeve stack analizi.

Statik sayma erken-dönüş/branch yollarını çift sayar (sahte uyarı). Bunun yerine
her C++ fonksiyonunu ayrı takip eder: Begin*/Push için push, End*/Pop için pop
ve fonksiyon kapanışında yığın boş mu diye bakar. Bu, gerçekten dengesiz olan
yerleri gösterir; branch'li ama dengeli kodu görmezden gelir.

ÇIKTI: fonksiyon -> derinlik geçmişi + fonksiyon sonunda dengesizlik.
"""
import re
import sys
from pathlib import Path

BEGIN = [
    "BeginPopup", "BeginPopupModal", "BeginChild", "BeginTabBar",
    "BeginTabItem", "BeginCombo", "BeginMenu", "BeginPopupContextItem",
    "BeginPopupContextWindow", "BeginPopupContextVoid", "BeginGroup",
    "BeginTable", "BeginDragDropSource", "BeginDragDropTarget", "BeginListBox",
]
END = [
    "EndPopup", "EndPopupModal", "EndChild", "EndTabBar", "EndTabItem",
    "EndCombo", "EndMenu", "EndPopupContextItem", "EndPopupContextWindow",
    "EndPopupContextVoid", "EndGroup", "EndTable", "EndDragDropSource",
    "EndDragDropTarget", "EndListBox",
]


def fonksiyonBosluklari(src):
    """Fonksiyon gövdelerinin { } eşleşme satırlarını (start, end) döner.

    Basit tırnak/yorum temizlemesi + tırmık sayacı. Karmaşık C++'ı tam
    çözemez ama UI kodunda yeterli.
    """
    # Yorumları temizle (/* */ ve // satır) — basit, /* */ içi çok satırlı
    src = re.sub(r"/\*.*?\*/", lambda m: "\n" * m.group(0).count("\n"), src, flags=re.S)
    satirlar = src.split("\n")
    temiz = []
    for s in satirlar:
        s = re.sub(r"//[^\n]*", "", s)
        temiz.append(s)
    sat = "\n".join(temiz)

    sonuc = []
    derinlik = 0
    baslangic = None
    for i, sat in enumerate(sat.split("\n")):
        for ch in sat:
            if ch == "{":
                if derinlik == 0:
                    baslangic = i
                derinlik += 1
            elif ch == "}":
                derinlik -= 1
                if derinlik == 0 and baslangic is not None:
                    sonuc.append((baslangic, i))
                    baslangic = None
    return sonuc


def token_durumu(sat, tokens):
    """SatırdaBegin/End gelince ('B'/'E', tok) listesi."""
    out = []
    for tok in tokens:
        for _ in re.finditer(r"\b" + tok + r"\s*\(", sat):
            out.append(tok)
    return out


def analiz_dosya(path):
    src = Path(path).read_text(encoding="utf-8", errors="replace")
    # Basit fonksiyon parametre parantezi temizlemesi: her { } bloğu bir
    # fonksiyon varsayımıyla (namespace/if/for da olabilir) analiz eder.
    # Gerçek fonksiyon sınırlarını bulmak için üst seviye { } bloklarına bak.
    bloklar = fonksiyonBosluklari(src)

    sorunlu = []
    for (bas, son) in bloklar:
        derinlik = 0
        maxd = 0
        for i in range(bas, son + 1):
            sat = src.split("\n")[i]
            b = token_durumu(sat, BEGIN)
            e = token_durumu(sat, END)
            for t in b:
                derinlik += 1
            for t in e:
                derinlik -= 1
            derinlik = max(0, derinlik)
            maxd = max(maxd, derinlik)
        if derinlik != 0:
            sorunlu.append((bas, son, derinlik))
    return sorunlu


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} {'FONK':>4} {'SORUNLU BLOK':>16}")
    print("-" * 75)
    top = 0
    for f in files:
        sor = analiz_dosya(f)
        if sor:
            top += len(sor)
            for (bas, son, d) in sor:
                print(f"{str(f.relative_to(root)):45} {bas+1:>4}  sat {bas+1}→{son+1} (d+{d})")
    print("-" * 75)
    print(f"Toplam dengesiz blok: {top}")


if __name__ == "__main__":
    main()
