#!/usr/bin/env python3
#
# This script renames symbols in the API, updating SDL_oldnames.h and
# adding documentation for the change.

import argparse
import os
import pathlib
import pprint
import re
import sys
from rename_symbols import create_regex_from_replacements, replace_symbols_in_path

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

SDL_INCLUDE_DIR = SDL_ROOT / "include/SDL3"
SDL_BUILD_SCRIPTS = SDL_ROOT / "build-scripts"


def main():
    if len(args.args) == 0 or (len(args.args) % 2) != 0:
        print("Usage: %s [-h] [--skip-header-check] header {enum,function,hint,structure,symbol} [old new ...]" % sys.argv[0])
        exit(1)

    # Check whether we can still modify the ABI
    version_header = pathlib.Path( SDL_INCLUDE_DIR / "SDL_version.h" ).read_text()
    if not re.search("SDL_MINOR_VERSION\s+[01]\s", version_header):
        raise Exception("ABI is frozen, symbols cannot be renamed")

    # Find the symbol in the headers
    if pathlib.Path(args.header).is_file():
        header = pathlib.Path(args.header)
    else:
        header = pathlib.Path(SDL_INCLUDE_DIR / args.header)

    if not header.exists():
        raise Exception("Couldn't find header %s" % header)

    header_text = header.read_text()

    # Replace the symbols in source code
    replacements = {}
    i = 0
    while i < len(args.args):
        oldname = args.args[i + 0]
        newname = args.args[i + 1]

        if not args.skip_header_check and not re.search((r"\b%s\b" % oldname), header_text):
            raise Exception("Couldn't find %s in %s" % (oldname, header))

        replacements[ oldname ] = newname
        replacements[ oldname + "_REAL" ] = newname + "_REAL"
        i += 2

    regex = create_regex_from_replacements(replacements)
    for dir in ["src", "test", "include", "docs", "cmake/test"]:
        replace_symbols_in_path(SDL_ROOT / dir, regex, replacements)

    # Replace the symbols in documentation
    i = 0
    while i < len(args.args):
        oldname = args.args[i + 0]
        newname = args.args[i + 1]

        add_symbol_to_oldnames(header.name, oldname, newname)
        add_symbol_to_migration(header.name, args.type, oldname, newname)
        add_symbol_to_coccinelle(args.type, oldname, newname)
        i += 2


def add_line(lines, i, section):
    lines.insert(i, section)
    i += 1
    return i


def add_content(lines, i, content, add_trailing_line):
    if lines[i - 1] == "":
        lines[i - 1] = content
    else:
        i = add_line(lines, i, content)

    if add_trailing_line:
        i = add_line(lines, i, "")
    return i


def add_symbol_to_coccinelle(symbol_type, oldname, newname):
    file = open(SDL_BUILD_SCRIPTS / "SDL_migration.cocci", "a")
    # Append-adds at last

    if symbol_type == "function":
        file.write("@@\n")
        file.write("@@\n")
        file.write("- %s\n" % oldname)
        file.write("+ %s\n" % newname)
        file.write("  (...)\n")

    if symbol_type == "symbol":
        file.write("@@\n")
        file.write("@@\n")
        file.write("- %s\n" % oldname)
        file.write("+ %s\n" % newname)

    # double check ?
    if symbol_type == "hint":
        file.write("@@\n")
        file.write("@@\n")
        file.write("- %s\n" % oldname)
        file.write("+ %s\n" % newname)

    if symbol_type == "enum" or symbol_type == "structure":
        file.write("@@\n")
        file.write("typedef %s, %s;\n" % (oldname, newname))
        file.write("@@\n")
        file.write("- %s\n" % oldname)
        file.write("+ %s\n" % newname)

    file.close()


def add_symbol_to_oldnames(header, oldname, newname):
    file = (SDL_INCLUDE_DIR / "SDL_oldnames.h")
    lines = file.read_text().splitlines()
    mode = 0
    i = 0
    while i < len(lines):
        line = lines[i]
        if line == "#ifdef SDL_ENABLE_OLD_NAMES":
            if mode == 0:
                mode = 1
                section = ("/* ##%s */" % header)
                section_added = False
                content = ("#define %s %s" % (oldname, newname))
                content_added = False
            else:
                raise Exception("add_symbol_to_oldnames(): expected mode 0")
        elif line == "#elif !defined(SDL_DISABLE_OLD_NAMES)":
            if mode == 1:
                if not section_added:
                    i = add_line(lines, i, section)

                if not content_added:
                    i = add_content(lines, i, content, True)

                mode = 2
                section = ("/* ##%s */" % header)
                section_added = False
                content = ("#define %s %s_renamed_%s" % (oldname, oldname, newname))
                content_added = False
            else:
                raise Exception("add_symbol_to_oldnames(): expected mode 1")
        elif line == "#endif /* SDL_ENABLE_OLD_NAMES */":
            if mode == 2:
                if not section_added:
                    i = add_line(lines, i, section)

                if not content_added:
                    i = add_content(lines, i, content, True)

                mode = 3
            else:
                raise Exception("add_symbol_to_oldnames(): expected mode 2")
        elif line != "" and (mode == 1 or mode == 2):
            if line.startswith("/* ##"):
                if section_added:
                    if not content_added:
                        i = add_content(lines, i, content, True)
                        content_added = True
                elif line == section:
                    section_added = True
                elif section < line:
                    i = add_line(lines, i, section)
                    section_added = True
                    i = add_content(lines, i, content, True)
                    content_added = True
            elif line != "" and section_added and not content_added:
                if content == line:
                    content_added = True
                elif content < line:
                    i = add_content(lines, i, content, False)
                    content_added = True
        i += 1

    file.write_text("\n".join(lines) + "\n")


def add_symbol_to_migration(header, symbol_type, oldname, newname):
    file = (SDL_ROOT / "docs/README-migration.md")
    lines = file.read_text().splitlines()
    section = ("## %s" % header)
    section_added = False
    note = ("The following %ss have been renamed:" % symbol_type)
    note_added = False
    if symbol_type == "function":
        content = ("* %s() => %s()" % (oldname, newname))
    else:
        content = ("* %s => %s" % (oldname, newname))
    content_added = False
    mode = 0
    i = 0
    while i < len(lines):
        line = lines[i]
        if line.startswith("##") and line.endswith(".h"):
            if line == section:
                section_added = True
            elif section < line:
                break

        elif section_added and not note_added:
            if note == line:
                note_added = True
        elif note_added and not content_added:
            if content == line:
                content_added = True
            elif line == "" or content < line:
                i = add_line(lines, i, content)
                content_added = True
        i += 1

    if not section_added:
        i = add_line(lines, i, section)
        i = add_line(lines, i, "")

    if not note_added:
        i = add_line(lines, i, note)

    if not content_added:
        i = add_content(lines, i, content, True)

    file.write_text("\n".join(lines) + "\n")


if __name__ == "__main__":

    parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
    parser.add_argument("--skip-header-check", action="store_true")
    parser.add_argument("header");
    parser.add_argument("type", choices=["enum", "function", "hint", "structure", "symbol"]);
    parser.add_argument("args", nargs="*")
    args = parser.parse_args()

    try:
        main()
    except Exception as e:
        print(e)
        exit(-1)

    exit(0)

