#!/usr/bin/env python3
#
#  Simple DirectMedia Layer
#  Copyright (C) 1997-2025 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',
    'strupr',
    'tan',
    'tanf',
    'tolower',
    'toupper',
    'trunc',
    'truncf',
    'uitoa',
    'ulltoa',
    'ultoa',
    'utf8strlcpy',
    'utf8strlen',
    'vasprintf',
    'vsnprintf',
    'vsscanf',
    'wcscasecmp',
    'wcscmp',
    'wcsdup',
    'wcslcat',
    'wcslcpy',
    'wcslen',
    'wcsncasecmp',
    'wcsncmp',
    'wcsstr',
]
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 m := RE_STDLIB_SYMBOL.match(line):
                    override_string = f"This should NOT be SDL_{m['symbol']}()"
                    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.glob("*"):
        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("path", default=SDL_ROOT, nargs="?", type=pathlib.Path, help="Path to look for stdlib symbols")
    args = parser.parse_args()

    print(f"Looking for stdlib usage in {args.path}...")

    match_count = find_symbols_in_dir(args.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())
