#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2016-2025 by Mauro Carvalho Chehab <mchehab@kernel.org>.
# pylint: disable=R0912,R0915

"""
Parse a source file or header, creating ReStructured Text cross references.

It accepts an optional file to change the default symbol reference or to
suppress symbols from the output.

It is capable of identifying ``define``, function, ``struct``, ``typedef``,
``enum`` and ``enum`` symbols and create cross-references for all of them.
It is also capable of distinguish #define used for specifying a Linux
ioctl.

The optional rules file contains a set of rules like::

    ignore ioctl VIDIOC_ENUM_FMT
    replace ioctl VIDIOC_DQBUF vidioc_qbuf
    replace define V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ :c:type:`v4l2_event_motion_det`
"""

import os
import re
import sys


class ParseDataStructs:
    """
    Creates an enriched version of a Kernel header file with cross-links
    to each C data structure type.

    It is meant to allow having a more comprehensive documentation, where
    uAPI headers will create cross-reference links to the code.

    It is capable of identifying ``define``, function, ``struct``, ``typedef``,
    ``enum`` and ``enum`` symbols and create cross-references for all of them.
    It is also capable of distinguish #define used for specifying a Linux
    ioctl.

    By default, it create rules for all symbols and defines, but it also
    allows parsing an exception file. Such file contains a set of rules
    using the syntax below:

    1. Ignore rules::

        ignore <type> <symbol>`

    Removes the symbol from reference generation.

    2. Replace rules::

        replace <type> <old_symbol> <new_reference>

       Replaces how old_symbol with a new reference. The new_reference can be:

        - A simple symbol name;
        - A full Sphinx reference.

    3. Namespace rules::

        namespace <namespace>

       Sets C namespace to be used during cross-reference generation. Can
       be overridden by replace rules.

    On ignore and replace rules, ``<type>`` can be:
        - ``ioctl``: for defines that end with ``_IO*``, e.g. ioctl definitions
        - ``define``: for other defines
        - ``symbol``: for symbols defined within enums;
        - ``typedef``: for typedefs;
        - ``enum``: for the name of a non-anonymous enum;
        - ``struct``: for structs.

    Examples::

        ignore define __LINUX_MEDIA_H
        ignore ioctl VIDIOC_ENUM_FMT
        replace ioctl VIDIOC_DQBUF vidioc_qbuf
        replace define V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ :c:type:`v4l2_event_motion_det`

        namespace MC
    """

    #: Parser regex with multiple ways to capture enums.
    RE_ENUMS = [
        re.compile(r"^\s*enum\s+([\w_]+)\s*\{"),
        re.compile(r"^\s*enum\s+([\w_]+)\s*$"),
        re.compile(r"^\s*typedef\s*enum\s+([\w_]+)\s*\{"),
        re.compile(r"^\s*typedef\s*enum\s+([\w_]+)\s*$"),
    ]

    #: Parser regex with multiple ways to capture structs.
    RE_STRUCTS = [
        re.compile(r"^\s*struct\s+([_\w][\w\d_]+)\s*\{"),
        re.compile(r"^\s*struct\s+([_\w][\w\d_]+)$"),
        re.compile(r"^\s*typedef\s*struct\s+([_\w][\w\d_]+)\s*\{"),
        re.compile(r"^\s*typedef\s*struct\s+([_\w][\w\d_]+)$"),
    ]

    # NOTE: the original code was written a long time before Sphinx C
    # domain to have multiple namespaces. To avoid to much turn at the
    # existing hyperlinks, the code kept using "c:type" instead of the
    # right types. To change that, we need to change the types not only
    # here, but also at the uAPI media documentation.

    #: Dictionary containing C type identifiers to be transformed.
    DEF_SYMBOL_TYPES = {
        "ioctl": {
            "prefix": "\\ ",
            "suffix": "\\ ",
            "ref_type": ":ref",
            "description": "IOCTL Commands",
        },
        "define": {
            "prefix": "\\ ",
            "suffix": "\\ ",
            "ref_type": ":ref",
            "description": "Macros and Definitions",
        },
        # We're calling each definition inside an enum as "symbol"
        "symbol": {
            "prefix": "\\ ",
            "suffix": "\\ ",
            "ref_type": ":ref",
            "description": "Enumeration values",
        },
        "typedef": {
            "prefix": "\\ ",
            "suffix": "\\ ",
            "ref_type": ":c:type",
            "description": "Type Definitions",
        },
        # This is the description of the enum itself
        "enum": {
            "prefix": "\\ ",
            "suffix": "\\ ",
            "ref_type": ":c:type",
            "description": "Enumerations",
        },
        "struct": {
            "prefix": "\\ ",
            "suffix": "\\ ",
            "ref_type": ":c:type",
            "description": "Structures",
        },
    }

    def __init__(self, debug: bool = False):
        """Initialize internal vars"""
        self.debug = debug
        self.data = ""

        self.symbols = {}

        self.namespace = None
        self.ignore = []
        self.replace = []

        for symbol_type in self.DEF_SYMBOL_TYPES:
            self.symbols[symbol_type] = {}

    def read_exceptions(self, fname: str):
        """
        Read an optional exceptions file, used to override defaults.
        """

        if not fname:
            return

        name = os.path.basename(fname)

        with open(fname, "r", encoding="utf-8", errors="backslashreplace") as f:
            for ln, line in enumerate(f):
                ln += 1
                line = line.strip()
                if not line or line.startswith("#"):
                    continue

                # ignore rules
                match = re.match(r"^ignore\s+(\w+)\s+(\S+)", line)

                if match:
                    self.ignore.append((ln, match.group(1), match.group(2)))
                    continue

                # replace rules
                match = re.match(r"^replace\s+(\S+)\s+(\S+)\s+(\S+)", line)
                if match:
                    self.replace.append((ln, match.group(1), match.group(2),
                                         match.group(3)))
                    continue

                match = re.match(r"^namespace\s+(\S+)", line)
                if match:
                    self.namespace = match.group(1)
                    continue

                sys.exit(f"{name}:{ln}: invalid line: {line}")

    def apply_exceptions(self):
        """
        Process exceptions file with rules to ignore or replace references.
        """

        # Handle ignore rules
        for ln, c_type, symbol in self.ignore:
            if c_type not in self.DEF_SYMBOL_TYPES:
                sys.exit(f"{name}:{ln}: {c_type} is invalid")

            d = self.symbols[c_type]
            if symbol in d:
                del d[symbol]

        # Handle replace rules
        for ln, c_type, old, new in self.replace:
            if c_type not in self.DEF_SYMBOL_TYPES:
                sys.exit(f"{name}:{ln}: {c_type} is invalid")

            reftype = None

            # Parse reference type when the type is specified

            match = re.match(r"^\:c\:(\w+)\:\`(.+)\`", new)
            if match:
                reftype = f":c:{match.group(1)}"
                new = match.group(2)
            else:
                match = re.search(r"(\:ref)\:\`(.+)\`", new)
                if match:
                    reftype = match.group(1)
                    new = match.group(2)

            # If the replacement rule doesn't have a type, get default
            if not reftype:
                reftype = self.DEF_SYMBOL_TYPES[c_type].get("ref_type")
                if not reftype:
                    reftype = self.DEF_SYMBOL_TYPES[c_type].get("real_type")

            new_ref = f"{reftype}:`{old} <{new}>`"

            # Change self.symbols to use the replacement rule
            if old in self.symbols[c_type]:
                (_, ln) = self.symbols[c_type][old]
                self.symbols[c_type][old] = (new_ref, ln)
            else:
                print(f"{name}:{ln}: Warning: can't find {old} {c_type}")

    def store_type(self, ln, symbol_type: str, symbol: str,
                   ref_name: str = None, replace_underscores: bool = True):
        """
        Store a new symbol at self.symbols under symbol_type.

        By default, underscores are replaced by ``-``.
        """
        defs = self.DEF_SYMBOL_TYPES[symbol_type]

        prefix = defs.get("prefix", "")
        suffix = defs.get("suffix", "")
        ref_type = defs.get("ref_type")

        # Determine ref_link based on symbol type
        if ref_type or self.namespace:
            if not ref_name:
                ref_name = symbol.lower()

            # c-type references don't support hash
            if ref_type == ":ref" and replace_underscores:
                ref_name = ref_name.replace("_", "-")

            # C domain references may have namespaces
            if ref_type.startswith(":c:"):
                if self.namespace:
                    ref_name = f"{self.namespace}.{ref_name}"

            if ref_type:
                ref_link = f"{ref_type}:`{symbol} <{ref_name}>`"
            else:
                ref_link = f"`{symbol} <{ref_name}>`"
        else:
            ref_link = symbol

        self.symbols[symbol_type][symbol] = (f"{prefix}{ref_link}{suffix}", ln)

    def store_line(self, line):
        """
        Store a line at self.data, properly indented.
        """
        line = "    " + line.expandtabs()
        self.data += line.rstrip(" ")

    def parse_file(self, file_in: str, exceptions: str = None):
        """
        Read a C source file and get identifiers.
        """
        self.data = ""
        is_enum = False
        is_comment = False
        multiline = ""

        self.read_exceptions(exceptions)

        with open(file_in, "r",
                  encoding="utf-8", errors="backslashreplace") as f:
            for line_no, line in enumerate(f):
                self.store_line(line)
                line = line.strip("\n")

                # Handle continuation lines
                if line.endswith(r"\\"):
                    multiline += line[-1]
                    continue

                if multiline:
                    line = multiline + line
                    multiline = ""

                # Handle comments. They can be multilined
                if not is_comment:
                    if re.search(r"/\*.*", line):
                        is_comment = True
                    else:
                        # Strip C99-style comments
                        line = re.sub(r"(//.*)", "", line)

                if is_comment:
                    if re.search(r".*\*/", line):
                        is_comment = False
                    else:
                        multiline = line
                        continue

                # At this point, line variable may be a multilined statement,
                # if lines end with \ or if they have multi-line comments
                # With that, it can safely remove the entire comments,
                # and there's no need to use re.DOTALL for the logic below

                line = re.sub(r"(/\*.*\*/)", "", line)
                if not line.strip():
                    continue

                # It can be useful for debug purposes to print the file after
                # having comments stripped and multi-lines grouped.
                if self.debug > 1:
                    print(f"line {line_no + 1}: {line}")

                # Now the fun begins: parse each type and store it.

                # We opted for a two parsing logic here due to:
                # 1. it makes easier to debug issues not-parsed symbols;
                # 2. we want symbol replacement at the entire content, not
                #    just when the symbol is detected.

                if is_enum:
                    match = re.match(r"^\s*([_\w][\w\d_]+)\s*[\,=]?", line)
                    if match:
                        self.store_type(line_no, "symbol", match.group(1))
                    if "}" in line:
                        is_enum = False
                    continue

                match = re.match(r"^\s*#\s*define\s+([\w_]+)\s+_IO", line)
                if match:
                    self.store_type(line_no, "ioctl", match.group(1),
                                    replace_underscores=False)
                    continue

                match = re.match(r"^\s*#\s*define\s+([\w_]+)(\s+|$)", line)
                if match:
                    self.store_type(line_no, "define", match.group(1))
                    continue

                match = re.match(r"^\s*typedef\s+([_\w][\w\d_]+)\s+(.*)\s+([_\w][\w\d_]+);",
                                 line)
                if match:
                    name = match.group(2).strip()
                    symbol = match.group(3)
                    self.store_type(line_no, "typedef", symbol, ref_name=name)
                    continue

                for re_enum in self.RE_ENUMS:
                    match = re_enum.match(line)
                    if match:
                        self.store_type(line_no, "enum", match.group(1))
                        is_enum = True
                        break

                for re_struct in self.RE_STRUCTS:
                    match = re_struct.match(line)
                    if match:
                        self.store_type(line_no, "struct", match.group(1))
                        break

        self.apply_exceptions()

    def debug_print(self):
        """
        Print debug information containing the replacement rules per symbol.
        To make easier to check, group them per type.
        """
        if not self.debug:
            return

        for c_type, refs in self.symbols.items():
            if not refs:  # Skip empty dictionaries
                continue

            print(f"{c_type}:")

            for symbol, (ref, ln) in sorted(refs.items()):
                print(f"  #{ln:<5d} {symbol} -> {ref}")

            print()

    def gen_output(self):
        """Write the formatted output to a file."""

        # Avoid extra blank lines
        text = re.sub(r"\s+$", "", self.data) + "\n"
        text = re.sub(r"\n\s+\n", "\n\n", text)

        # Escape Sphinx special characters
        text = re.sub(r"([\_\`\*\<\>\&\\\\:\/\|\%\$\#\{\}\~\^])", r"\\\1", text)

        # Source uAPI files may have special notes. Use bold font for them
        text = re.sub(r"DEPRECATED", "**DEPRECATED**", text)

        # Delimiters to catch the entire symbol after escaped
        start_delim = r"([ \n\t\(=\*\@])"
        end_delim = r"(\s|,|\\=|\\:|\;|\)|\}|\{)"

        # Process all reference types
        for ref_dict in self.symbols.values():
            for symbol, (replacement, _) in ref_dict.items():
                symbol = re.escape(re.sub(r"([\_\`\*\<\>\&\\\\:\/])", r"\\\1", symbol))
                text = re.sub(fr'{start_delim}{symbol}{end_delim}',
                              fr'\1{replacement}\2', text)

        # Remove "\ " where not needed: before spaces and at the end of lines
        text = re.sub(r"\\ ([\n ])", r"\1", text)
        text = re.sub(r" \\ ", " ", text)

        return text

    def gen_toc(self):
        """
        Create a list of symbols to be part of a TOC contents table.
        """
        text = []

        # Sort symbol types per description
        symbol_descriptions = []
        for k, v in self.DEF_SYMBOL_TYPES.items():
            symbol_descriptions.append((v['description'], k))

        symbol_descriptions.sort()

        # Process each category
        for description, c_type in symbol_descriptions:

            refs = self.symbols[c_type]
            if not refs:  # Skip empty categories
                continue

            text.append(f"{description}")
            text.append("-" * len(description))
            text.append("")

            # Sort symbols alphabetically
            for symbol, (ref, ln) in sorted(refs.items()):
                text.append(f"- LINENO_{ln}: {ref}")

            text.append("")  # Add empty line between categories

        return "\n".join(text)

    def write_output(self, file_in: str, file_out: str, toc: bool):
        """
        Write a ReST output file.
        """

        title = os.path.basename(file_in)

        if toc:
            text = self.gen_toc()
        else:
            text = self.gen_output()

        with open(file_out, "w", encoding="utf-8", errors="backslashreplace") as f:
            f.write(".. -*- coding: utf-8; mode: rst -*-\n\n")
            f.write(f"{title}\n")
            f.write("=" * len(title) + "\n\n")

            if not toc:
                f.write(".. parsed-literal::\n\n")

            f.write(text)
