#!/usr/bin/env python3
#
#  Simple DirectMedia Layer
#  Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
#
#  This software is provided 'as-is', without any express or implied
#  warranty.  In no event will the authors be held liable for any damages
#  arising from the use of this software.
#
#  Permission is granted to anyone to use this software for any purpose,
#  including commercial applications, and to alter it and redistribute it
#  freely, subject to the following restrictions:
#
#  1. The origin of this software must not be misrepresented; you must not
#     claim that you wrote the original software. If you use this software
#     in a product, an acknowledgment in the product documentation would be
#     appreciated but is not required.
#  2. Altered source versions must be plainly marked as such, and must not be
#     misrepresented as being the original software.
#  3. This notice may not be removed or altered from any source distribution.
#
# This script detects use of stdlib function in SDL code

import argparse
import os
import pathlib
import re
import sys

SDL_ROOT = pathlib.Path(__file__).resolve().parents[1]

STDLIB_SYMBOLS = (
    'abs',
    'acos',
    'acosf',
    'asin',
    'asinf',
    'asprintf',
    'atan',
    'atan2',
    'atan2f',
    'atanf',
    'atof',
    'atoi',
    'bsearch',
    'calloc',
    'ceil',
    'ceilf',
    'copysign',
    'copysignf',
    'cos',
    'cosf',
    'crc32',
    'exp',
    'expf',
    'fabs',
    'fabsf',
    'floor',
    'floorf',
    'fmod',
    'fmodf',
    'free',
    'getenv',
    'isalnum',
    'isalpha',
    'isblank',
    'iscntrl',
    'isdigit',
    'isgraph',
    'islower',
    'isprint',
    'ispunct',
    'isspace',
    'isupper',
    'isxdigit',
    'itoa',
    'lltoa',
    'log10',
    'log10f',
    'logf',
    'lround',
    'lroundf',
    'ltoa',
    'malloc',
    'memalign',
    'memcmp',
    'memcpy',
    'memcpy4',
    'memmove',
    'memset',
    'pow',
    'powf',
    'qsort',
    'qsort_r',
    'qsort_s',
    'realloc',
    'round',
    'roundf',
    'scalbn',
    'scalbnf',
    'setenv',
    'sin',
    'sinf',
    'snprintf',
    'sqrt',
    'sqrtf',
    'sscanf',
    'strcasecmp',
    'strchr',
    'strcmp',
    'strdup',
    'strlcat',
    'strlcpy',
    'strlen',
    'strlwr',
    'strncasecmp',
    'strncmp',
    'strrchr',
    'strrev',
    'strstr',
    'strtod',
    'strtokr',
    'strtol',
    'strtoll',
    'strtoul',
    'strtoull',
    'strupr',
    'tan',
    'tanf',
    'tolower',
    'toupper',
    'trunc',
    'truncf',
    'uitoa',
    'ulltoa',
    'ultoa',
    'utf8strlcpy',
    'utf8strlen',
    'vasprintf',
    'vsnprintf',
    'vsscanf',
    'wcscasecmp',
    'wcscmp',
    'wcsdup',
    'wcslcat',
    'wcslcpy',
    'wcslen',
    'wcsncasecmp',
    'wcsncmp',
    'wcsstr',
    'wcstol',
    'wcstoll',
    'wcstoul',
    'wcstoull',
)
RE_STDLIB_SYMBOL = re.compile(rf"(?<!->)\b(?P<symbol>{'|'.join(STDLIB_SYMBOLS)})\b\(")


def find_symbols_in_file(file: pathlib.Path) -> int:
    match_count = 0

    allowed_extensions = [ ".c", ".cpp", ".m", ".h",  ".hpp", ".cc" ]

    excluded_paths = [
        "src/stdlib",
        "src/libm",
        "src/hidapi",
        "src/video/khronos",
        "src/video/miniz.h",
        "src/video/stb_image.h",
        "include/SDL3",
        "build-scripts/gen_audio_resampler_filter.c",
        "build-scripts/gen_audio_channel_conversion.c",
        "test/win32/sdlprocdump.c",
    ]

    filename = pathlib.Path(file)

    for ep in excluded_paths:
        if ep in filename.as_posix():
            # skip
            return 0

    if filename.suffix not in allowed_extensions:
        # skip
        return 0

    # print("Parse %s" % file)

    try:
        with file.open("r", encoding="UTF-8", newline="") as rfp:
            parsing_comment = False
            for line_i, original_line in enumerate(rfp, start=1):
                line = original_line.strip()

                line_comment = ""

                # Get the comment block /* ... */ across several lines
                while True:
                    if parsing_comment:
                        pos_end_comment = line.find("*/")
                        if pos_end_comment >= 0:
                            line = line[pos_end_comment+2:]
                            parsing_comment = False
                        else:
                            break
                    else:
                        pos_start_comment = line.find("/*")
                        if pos_start_comment >= 0:
                            pos_end_comment = line.find("*/", pos_start_comment+2)
                            if pos_end_comment >= 0:
                                line_comment += line[pos_start_comment:pos_end_comment+2]
                                line = line[:pos_start_comment] + line[pos_end_comment+2:]
                            else:
                                line_comment += line[pos_start_comment:]
                                line = line[:pos_start_comment]
                                parsing_comment = True
                                break
                        else:
                            break
                if parsing_comment:
                    continue
                pos_line_comment = line.find("//")
                if pos_line_comment >= 0:
                    line_comment += line[pos_line_comment:]
                    line = line[:pos_line_comment]

                if matches := tuple(RE_STDLIB_SYMBOL.finditer(line)):
                    text_string = " or ".join(f"SDL_{m.group(1)}" for m in matches)
                    first_quote = line.find("\"")
                    last_quote = line.rfind("\"")
                    first_occurrence = min(m.span()[0] for m in matches)
                    last_occurrence = max(m.span()[1] for m in matches)
                    if first_quote == -1 or not (first_quote < first_occurrence and last_quote > last_occurrence):
                        override_string = f"This should NOT be {text_string}"
                        if override_string not in line_comment:
                            print(f"{filename}:{line_i}")
                            print(f"    {line}")
                            print(f"")
                            match_count += 1

    except UnicodeDecodeError:
        print(f"{file} is not text, skipping", file=sys.stderr)

    return match_count

def find_symbols_in_dir(path: pathlib.Path) -> int:
    match_count = 0
    for entry in path.iterdir():
        if entry.is_dir():
            match_count += find_symbols_in_dir(entry)
        else:
            match_count += find_symbols_in_file(entry)
    return match_count

def main():
    parser = argparse.ArgumentParser(fromfile_prefix_chars="@")
    parser.add_argument("paths", default=[SDL_ROOT / "src", SDL_ROOT / "test"], nargs="*", type=pathlib.Path, help="Paths to look for stdlib symbols")
    args = parser.parse_args()

    print(f"Looking for stdlib usage in {', '.join(str(p) for p in args.paths)}...")

    match_count = 0
    for path in args.paths:
        if path.is_file():
            match_count = find_symbols_in_file(path)
        else:
            match_count = find_symbols_in_dir(path)

    if match_count:
        print("If the stdlib usage is intentional, add a '// This should NOT be SDL_<symbol>()' line comment.")
        print("")
        print("NOT OK")
    else:
        print("OK")
    return 1 if match_count else 0

if __name__ == "__main__":
    raise SystemExit(main())
