"""Naive PHP brace-balance check.

Caveats: doesn't understand heredoc/nowdoc, and may be confused by
curly chars in string interpolation `"{$var}"` (we strip those before
counting). Intent is a smoke test, not a real lint.
"""
import re, sys

def strip(src):
    s = re.sub(r'/\*.*?\*/', '', src, flags=re.S)
    s = re.sub(r"'(?:\\.|[^'\\])*'", "''", s)
    s = re.sub(r'"(?:\\.|[^"\\])*"', '""', s)
    # Heredoc / nowdoc: <<<TAG ... TAG;
    s = re.sub(r'<<<\s*[\'"]?(\w+)[\'"]?\s*\n.*?\n\s*\1\b;?', "''", s, flags=re.S)
    s = re.sub(r'//[^\n]*', '', s)
    s = re.sub(r'#[^\n]*', '', s)
    return s

def report(label, src):
    s = strip(src)
    o, c = s.count('{'), s.count('}')
    po, pc = s.count('('), s.count(')')
    bo, bc = s.count('['), s.count(']')
    status = 'OK' if (o == c and po == pc and bo == bc) else 'MISMATCH'
    print(f'{status:>9}  braces {o-c:+d}  parens {po-pc:+d}  brackets {bo-bc:+d}  {label}')
    return o == c and po == pc and bo == bc

files = [
    'carta-online.php',
    'uninstall.php',
    'includes/co_api.php',
    'includes/localcache/co_localcache_constants.php',
    'includes/localcache/co_localcache_schema.php',
    'includes/localcache/co_localcache_settings.php',
]
ok = True
for f in files:
    with open(f, 'r', encoding='utf-8') as fh:
        src = fh.read()
    if not report(f, src):
        ok = False
sys.exit(0 if ok else 1)
