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

"""
Parse ABI documentation and produce results from it.
"""

import os
import re
import sys

from concurrent import futures
from datetime import datetime
from random import shuffle

from abi.helpers import AbiDebug

class SystemSymbols:
    """Stores arguments for the class and initialize class vars"""

    def graph_add_file(self, path, link=None):
        """
        add a file path to the sysfs graph stored at self.root
        """

        if path in self.files:
            return

        name = ""
        ref = self.root
        for edge in path.split("/"):
            name += edge + "/"
            if edge not in ref:
                ref[edge] = {"__name": [name.rstrip("/")]}

            ref = ref[edge]

        if link and link not in ref["__name"]:
            ref["__name"].append(link.rstrip("/"))

        self.files.add(path)

    def print_graph(self, root_prefix="", root=None, level=0):
        """Prints a reference tree graph using UTF-8 characters"""

        if not root:
            root = self.root
            level = 0

        # Prevent endless traverse
        if level > 5:
            return

        if level > 0:
            prefix = "├──"
            last_prefix = "└──"
        else:
            prefix = ""
            last_prefix = ""

        items = list(root.items())

        names = root.get("__name", [])
        for k, edge in items:
            if k == "__name":
                continue

            if not k:
                k = "/"

            if len(names) > 1:
                k += " links: " + ",".join(names[1:])

            if edge == items[-1][1]:
                print(root_prefix + last_prefix + k)
                p = root_prefix
                if level > 0:
                    p += "   "
                self.print_graph(p, edge, level + 1)
            else:
                print(root_prefix + prefix + k)
                p = root_prefix + "│   "
                self.print_graph(p, edge, level + 1)

    def _walk(self, root):
        """
        Walk through sysfs to get all devnodes that aren't ignored.

        By default, uses /sys as sysfs mounting point. If another
        directory is used, it replaces them to /sys at the patches.
        """

        with os.scandir(root) as obj:
            for entry in obj:
                path = os.path.join(root, entry.name)
                if self.sysfs:
                    p = path.replace(self.sysfs, "/sys", count=1)
                else:
                    p = path

                if self.re_ignore.search(p):
                    return

                # Handle link first to avoid directory recursion
                if entry.is_symlink():
                    real = os.path.realpath(path)
                    if not self.sysfs:
                        self.aliases[path] = real
                    else:
                        real = real.replace(self.sysfs, "/sys", count=1)

                    # Add absfile location to graph if it doesn't exist
                    if not self.re_ignore.search(real):
                        # Add link to the graph
                        self.graph_add_file(real, p)

                elif entry.is_file():
                    self.graph_add_file(p)

                elif entry.is_dir():
                    self._walk(path)

    def __init__(self, abi, sysfs="/sys", hints=False):
        """
        Initialize internal variables and get a list of all files inside
        sysfs that can currently be parsed.

        Please notice that there are several entries on sysfs that aren't
        documented as ABI. Ignore those.

        The real paths will be stored under self.files. Aliases will be
        stored in separate, as self.aliases.
        """

        self.abi = abi
        self.log = abi.log

        if sysfs != "/sys":
            self.sysfs = sysfs.rstrip("/")
        else:
            self.sysfs = None

        self.hints = hints

        self.root = {}
        self.aliases = {}
        self.files = set()

        dont_walk = [
            # Those require root access and aren't documented at ABI
            f"^{sysfs}/kernel/debug",
            f"^{sysfs}/kernel/tracing",
            f"^{sysfs}/fs/pstore",
            f"^{sysfs}/fs/bpf",
            f"^{sysfs}/fs/fuse",

            # This is not documented at ABI
            f"^{sysfs}/module",

            f"^{sysfs}/fs/cgroup",  # this is big and has zero docs under ABI
            f"^{sysfs}/firmware",   # documented elsewhere: ACPI, DT bindings
            "sections|notes",       # aren't actually part of ABI

            # kernel-parameters.txt - not easy to parse
            "parameters",
        ]

        self.re_ignore = re.compile("|".join(dont_walk))

        print(f"Reading {sysfs} directory contents...", file=sys.stderr)
        self._walk(sysfs)

    def check_file(self, refs, found):
        """Check missing ABI symbols for a given sysfs file"""

        res_list = []

        try:
            for names in refs:
                fname = names[0]

                res = {
                    "found": False,
                    "fname": fname,
                    "msg": "",
                }
                res_list.append(res)

                re_what = self.abi.get_regexes(fname)
                if not re_what:
                    self.abi.log.warning(f"missing rules for {fname}")
                    continue

                for name in names:
                    for r in re_what:
                        if self.abi.debug & AbiDebug.UNDEFINED:
                            self.log.debug("check if %s matches '%s'", name, r.pattern)
                        if r.match(name):
                            res["found"] = True
                            if found:
                                res["msg"] += f"  {fname}: regex:\n\t"
                            continue

                if self.hints and not res["found"]:
                    res["msg"] += f"  {fname} not found. Tested regexes:\n"
                    for r in re_what:
                        res["msg"] += "    " + r.pattern + "\n"

        except KeyboardInterrupt:
            pass

        return res_list

    def _ref_interactor(self, root):
        """Recursive function to interact over the sysfs tree"""

        for k, v in root.items():
            if isinstance(v, dict):
                yield from self._ref_interactor(v)

            if root == self.root or k == "__name":
                continue

            if self.abi.re_string:
                fname = v["__name"][0]
                if self.abi.re_string.search(fname):
                    yield v
            else:
                yield v


    def get_fileref(self, all_refs, chunk_size):
        """Interactor to group refs into chunks"""

        n = 0
        refs = []

        for ref in all_refs:
            refs.append(ref)

            n += 1
            if n >= chunk_size:
                yield refs
                n = 0
                refs = []

        yield refs

    def check_undefined_symbols(self, max_workers=None, chunk_size=50,
                                found=None, dry_run=None):
        """Seach ABI for sysfs symbols missing documentation"""

        self.abi.parse_abi()

        if self.abi.debug & AbiDebug.GRAPH:
            self.print_graph()

        all_refs = []
        for ref in self._ref_interactor(self.root):
            all_refs.append(ref["__name"])

        if dry_run:
            print("Would check", file=sys.stderr)
            for ref in all_refs:
                print(", ".join(ref))

            return

        print("Starting to search symbols (it may take several minutes):",
              file=sys.stderr)
        start = datetime.now()
        old_elapsed = None

        # Python doesn't support multithreading due to limitations on its
        # global lock (GIL). While Python 3.13 finally made GIL optional,
        # there are still issues related to it. Also, we want to have
        # backward compatibility with older versions of Python.
        #
        # So, use instead multiprocess. However, Python is very slow passing
        # data from/to multiple processes. Also, it may consume lots of memory
        # if the data to be shared is not small.  So, we need to group workload
        # in chunks that are big enough to generate performance gains while
        # not being so big that would cause out-of-memory.

        num_refs = len(all_refs)
        print(f"Number of references to parse: {num_refs}", file=sys.stderr)

        if not max_workers:
            max_workers = os.cpu_count()
        elif max_workers > os.cpu_count():
            max_workers = os.cpu_count()

        max_workers = max(max_workers, 1)

        max_chunk_size = int((num_refs + max_workers - 1) / max_workers)
        chunk_size = min(chunk_size, max_chunk_size)
        chunk_size = max(1, chunk_size)

        if max_workers > 1:
            executor = futures.ProcessPoolExecutor

            # Place references in a random order. This may help improving
            # performance, by mixing complex/simple expressions when creating
            # chunks
            shuffle(all_refs)
        else:
            # Python has a high overhead with processes. When there's just
            # one worker, it is faster to not create a new process.
            # Yet, User still deserves to have a progress print. So, use
            # python's "thread", which is actually a single process, using
            # an internal schedule to switch between tasks. No performance
            # gains for non-IO tasks, but still it can be quickly interrupted
            # from time to time to display progress.
            executor = futures.ThreadPoolExecutor

        not_found = []
        f_list = []
        with executor(max_workers=max_workers) as exe:
            for refs in self.get_fileref(all_refs, chunk_size):
                if refs:
                    try:
                        f_list.append(exe.submit(self.check_file, refs, found))

                    except KeyboardInterrupt:
                        return

            total = len(f_list)

            if not total:
                if self.abi.re_string:
                    print(f"No ABI symbol matches {self.abi.search_string}")
                else:
                    self.abi.log.warning("No ABI symbols found")
                return

            print(f"{len(f_list):6d} jobs queued on {max_workers} workers",
                  file=sys.stderr)

            while f_list:
                try:
                    t = futures.wait(f_list, timeout=1,
                                     return_when=futures.FIRST_COMPLETED)

                    done = t[0]

                    for fut in done:
                        res_list = fut.result()

                        for res in res_list:
                            if not res["found"]:
                                not_found.append(res["fname"])
                            if res["msg"]:
                                print(res["msg"])

                        f_list.remove(fut)
                except KeyboardInterrupt:
                    return

                except RuntimeError as e:
                    self.abi.log.warning(f"Future: {e}")
                    break

                if sys.stderr.isatty():
                    elapsed = str(datetime.now() - start).split(".", maxsplit=1)[0]
                    if len(f_list) < total:
                        elapsed += f" ({total - len(f_list)}/{total} jobs completed).  "
                    if elapsed != old_elapsed:
                        print(elapsed + "\r", end="", flush=True,
                              file=sys.stderr)
                        old_elapsed = elapsed

        elapsed = str(datetime.now() - start).split(".", maxsplit=1)[0]
        print(elapsed, file=sys.stderr)

        for f in sorted(not_found):
            print(f"{f} not found.")
