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

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

import argparse
import logging
import os
import sys

# Import Python modules

LIB_DIR = "../lib/python"
SRC_DIR = os.path.dirname(os.path.realpath(__file__))

sys.path.insert(0, os.path.join(SRC_DIR, LIB_DIR))

from abi.abi_parser import AbiParser                # pylint: disable=C0413
from abi.abi_regex import AbiRegex                  # pylint: disable=C0413
from abi.helpers import ABI_DIR, DEBUG_HELP         # pylint: disable=C0413
from abi.system_symbols import SystemSymbols        # pylint: disable=C0413

# Command line classes


REST_DESC = """
Produce output in ReST format.

The output is done on two sections:

- Symbols: show all parsed symbols in alphabetic order;
- Files: cross reference the content of each file with the symbols on it.
"""

class AbiRest:
    """Initialize an argparse subparser for rest output"""

    def __init__(self, subparsers):
        """Initialize argparse subparsers"""

        parser = subparsers.add_parser("rest",
                                       formatter_class=argparse.RawTextHelpFormatter,
                                       description=REST_DESC)

        parser.add_argument("--enable-lineno",  action="store_true",
                            help="enable lineno")
        parser.add_argument("--raw", action="store_true",
                            help="output text as contained in the ABI files. "
                                 "It not used, output will contain dynamically"
                                 " generated cross references when possible.")
        parser.add_argument("--no-file", action="store_true",
                            help="Don't the files section")
        parser.add_argument("--show-hints", help="Show-hints")

        parser.set_defaults(func=self.run)

    def run(self, args):
        """Run subparser"""

        parser = AbiParser(args.dir, debug=args.debug)
        parser.parse_abi()
        parser.check_issues()

        for t in parser.doc(args.raw, not args.no_file):
            if args.enable_lineno:
                print (f".. LINENO {t[1]}#{t[2]}\n\n")

            print(t[0])

class AbiValidate:
    """Initialize an argparse subparser for ABI validation"""

    def __init__(self, subparsers):
        """Initialize argparse subparsers"""

        parser = subparsers.add_parser("validate",
                                       formatter_class=argparse.ArgumentDefaultsHelpFormatter,
                                       description="list events")

        parser.set_defaults(func=self.run)

    def run(self, args):
        """Run subparser"""

        parser = AbiParser(args.dir, debug=args.debug)
        parser.parse_abi()
        parser.check_issues()


class AbiSearch:
    """Initialize an argparse subparser for ABI search"""

    def __init__(self, subparsers):
        """Initialize argparse subparsers"""

        parser = subparsers.add_parser("search",
                                       formatter_class=argparse.ArgumentDefaultsHelpFormatter,
                                       description="Search ABI using a regular expression")

        parser.add_argument("expression",
                            help="Case-insensitive search pattern for the ABI symbol")

        parser.set_defaults(func=self.run)

    def run(self, args):
        """Run subparser"""

        parser = AbiParser(args.dir, debug=args.debug)
        parser.parse_abi()
        parser.search_symbols(args.expression)

UNDEFINED_DESC="""
Check undefined ABIs on local machine.

Read sysfs devnodes and check if the devnodes there are defined inside
ABI documentation.

The search logic tries to minimize the number of regular expressions to
search per each symbol.

By default, it runs on a single CPU, as Python support for CPU threads
is still experimental, and multi-process runs on Python is very slow.

On experimental tests, if the number of ABI symbols to search per devnode
is contained on a limit of ~150 regular expressions, using a single CPU
is a lot faster than using multiple processes. However, if the number of
regular expressions to check is at the order of ~30000, using multiple
CPUs speeds up the check.
"""

class AbiUndefined:
    """
    Initialize an argparse subparser for logic to check undefined ABI at
    the current machine's sysfs
    """

    def __init__(self, subparsers):
        """Initialize argparse subparsers"""

        parser = subparsers.add_parser("undefined",
                                       formatter_class=argparse.RawTextHelpFormatter,
                                       description=UNDEFINED_DESC)

        parser.add_argument("-S", "--sysfs-dir", default="/sys",
                            help="directory where sysfs is mounted")
        parser.add_argument("-s", "--search-string",
                            help="search string regular expression to limit symbol search")
        parser.add_argument("-H", "--show-hints", action="store_true",
                            help="Hints about definitions for missing ABI symbols.")
        parser.add_argument("-j", "--jobs", "--max-workers", type=int, default=1,
                            help="If bigger than one, enables multiprocessing.")
        parser.add_argument("-c", "--max-chunk-size", type=int, default=50,
                            help="Maximum number of chunk size")
        parser.add_argument("-f", "--found", action="store_true",
                            help="Also show found items. "
                                 "Helpful to debug the parser."),
        parser.add_argument("-d", "--dry-run", action="store_true",
                            help="Don't actually search for undefined. "
                                 "Helpful to debug the parser."),

        parser.set_defaults(func=self.run)

    def run(self, args):
        """Run subparser"""

        abi = AbiRegex(args.dir, debug=args.debug,
                       search_string=args.search_string)

        abi_symbols = SystemSymbols(abi=abi, hints=args.show_hints,
                                    sysfs=args.sysfs_dir)

        abi_symbols.check_undefined_symbols(dry_run=args.dry_run,
                                            found=args.found,
                                            max_workers=args.jobs,
                                            chunk_size=args.max_chunk_size)


def main():
    """Main program"""

    parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument("-d", "--debug", type=int, default=0, help="debug level")
    parser.add_argument("-D", "--dir", default=ABI_DIR, help=DEBUG_HELP)

    subparsers = parser.add_subparsers()

    AbiRest(subparsers)
    AbiValidate(subparsers)
    AbiSearch(subparsers)
    AbiUndefined(subparsers)

    args = parser.parse_args()

    if args.debug:
        level = logging.DEBUG
    else:
        level = logging.INFO

    logging.basicConfig(level=level, format="[%(levelname)s] %(message)s")

    if "func" in args:
        args.func(args)
    else:
        sys.exit(f"Please specify a valid command for {sys.argv[0]}")


# Call main method
if __name__ == "__main__":
    main()
