import subprocess
import sys
import os

if len(sys.argv) < 2 or not os.path.isfile(sys.argv[1]):
    print("Usage: [libduckdb dynamic library file, release build]")
    exit(1)

res = subprocess.run('nm -g -C -P'.split(' ') + [sys.argv[1]], check=True, capture_output=True)
if res.returncode != 0:
    raise ValueError('Failed to run `nm`')

culprits = []

whitelist = [
    '@GLIBC',
    '@GCC',
    '@CXXABI',
    '__gnu_cxx::',
    'std::',
    'N6duckdb',
    'duckdb::',
    'duckdb_miniz::',
    'duckdb_fmt::',
    'duckdb_hll::',
    'duckdb_moodycamel::',
    'duckdb_yyjson::',
    'duckdb_',
    'RefCounter',
    'registerTMCloneTable',
    'RegisterClasses',
    'Unwind_Resume',
    '__gmon_start',
    '_fini',
    '_init',
    '_version',
    '_end',
    '_edata',
    '__bss_start',
    '__udivti3',
    '__popcount',
    'Adbc',
    'ErrorArrayStream',
    'ErrorFromArrayStream',
]

for symbol in res.stdout.decode('utf-8').split('\n'):
    if len(symbol.strip()) == 0:
        continue
    if symbol.endswith(' U'):  # undefined because dynamic linker
        continue
    if symbol.endswith(' U 0 0') and "random_device" not in symbol:  # undefined because dynamic linker
        continue

    is_whitelisted = False
    for entry in whitelist:
        if entry in symbol and "random_device" not in symbol:
            is_whitelisted = True
    if is_whitelisted:
        continue

    culprits.append(symbol)


if len(culprits) > 0:
    print("Found leaked symbols. Either white-list above or change visibility:")
    for symbol in culprits:
        print(symbol)
    sys.exit(1)


sys.exit(0)
