#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2025 Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
#
# pylint: disable=R0902, R0912, R0913, R0914, R0915, R0917, C0103
#
# Converted from docs Makefile and parallel-wrapper.sh, both under
# GPLv2, copyrighted since 2008 by the following authors:
#
#    Akira Yokosawa <akiyks@gmail.com>
#    Arnd Bergmann <arnd@arndb.de>
#    Breno Leitao <leitao@debian.org>
#    Carlos Bilbao <carlos.bilbao@amd.com>
#    Dave Young <dyoung@redhat.com>
#    Donald Hunter <donald.hunter@gmail.com>
#    Geert Uytterhoeven <geert+renesas@glider.be>
#    Jani Nikula <jani.nikula@intel.com>
#    Jan Stancek <jstancek@redhat.com>
#    Jonathan Corbet <corbet@lwn.net>
#    Joshua Clayton <stillcompiling@gmail.com>
#    Kees Cook <keescook@chromium.org>
#    Linus Torvalds <torvalds@linux-foundation.org>
#    Magnus Damm <damm+renesas@opensource.se>
#    Masahiro Yamada <masahiroy@kernel.org>
#    Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
#    Maxim Cournoyer <maxim.cournoyer@gmail.com>
#    Peter Foley <pefoley2@pefoley.com>
#    Randy Dunlap <rdunlap@infradead.org>
#    Rob Herring <robh@kernel.org>
#    Shuah Khan <shuahkh@osg.samsung.com>
#    Thorsten Blum <thorsten.blum@toblux.com>
#    Tomas Winkler <tomas.winkler@intel.com>


"""
Sphinx build wrapper that handles Kernel-specific business rules:

- it gets the Kernel build environment vars;
- it determines what's the best parallelism;
- it handles SPHINXDIRS

This tool ensures that MIN_PYTHON_VERSION is satisfied. If version is
below that, it seeks for a new Python version. If found, it re-runs using
the newer version.
"""

import argparse
import locale
import os
import re
import shlex
import shutil
import subprocess
import sys

from concurrent import futures
from glob import glob

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

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

from jobserver import JobserverExec                  # pylint: disable=C0413


def parse_version(version):
    """Convert a major.minor.patch version into a tuple"""
    return tuple(int(x) for x in version.split("."))

def ver_str(version):
    """Returns a version tuple as major.minor.patch"""

    return ".".join([str(x) for x in version])

# Minimal supported Python version needed by Sphinx and its extensions
MIN_PYTHON_VERSION = parse_version("3.7")

# Default value for --venv parameter
VENV_DEFAULT = "sphinx_latest"

# List of make targets and its corresponding builder and output directory
TARGETS = {
    "cleandocs": {
        "builder": "clean",
    },
    "htmldocs": {
        "builder": "html",
    },
    "epubdocs": {
        "builder": "epub",
        "out_dir": "epub",
    },
    "texinfodocs": {
        "builder": "texinfo",
        "out_dir": "texinfo",
    },
    "infodocs": {
        "builder": "texinfo",
        "out_dir": "texinfo",
    },
    "latexdocs": {
        "builder": "latex",
        "out_dir": "latex",
    },
    "pdfdocs": {
        "builder": "latex",
        "out_dir": "latex",
    },
    "xmldocs": {
        "builder": "xml",
        "out_dir": "xml",
    },
    "linkcheckdocs": {
        "builder": "linkcheck"
    },
}

# Paper sizes. An empty value will pick the default
PAPER = ["", "a4", "letter"]

class SphinxBuilder:
    """
    Handles a sphinx-build target, adding needed arguments to build
    with the Kernel.
    """

    def is_rust_enabled(self):
        """Check if rust is enabled at .config"""
        config_path = os.path.join(self.srctree, ".config")
        if os.path.isfile(config_path):
            with open(config_path, "r", encoding="utf-8") as f:
                return "CONFIG_RUST=y" in f.read()
        return False

    def get_path(self, path, abs_path=False):
        """
        Ancillary routine to handle patches the right way, as shell does.

        It first expands "~" and "~user". Then, if patch is not absolute,
        join self.srctree. Finally, if requested, convert to abspath.
        """

        path = os.path.expanduser(path)
        if not path.startswith("/"):
            path = os.path.join(self.srctree, path)

        if abs_path:
            return os.path.abspath(path)

        return path

    def __init__(self, venv=None, verbose=False, n_jobs=None, interactive=None):
        """Initialize internal variables"""
        self.venv = venv
        self.verbose = None

        # Normal variables passed from Kernel's makefile
        self.kernelversion = os.environ.get("KERNELVERSION", "unknown")
        self.kernelrelease = os.environ.get("KERNELRELEASE", "unknown")
        self.pdflatex = os.environ.get("PDFLATEX", "xelatex")

        if not interactive:
            self.latexopts = os.environ.get("LATEXOPTS", "-interaction=batchmode -no-shell-escape")
        else:
            self.latexopts = os.environ.get("LATEXOPTS", "")

        if not verbose:
            verbose = bool(os.environ.get("KBUILD_VERBOSE", "") != "")

        # Handle SPHINXOPTS evironment
        sphinxopts = shlex.split(os.environ.get("SPHINXOPTS", ""))

        # As we handle number of jobs and quiet in separate, we need to pick
        # it the same way as sphinx-build would pick, so let's use argparse
        # do to the right argument expansion
        parser = argparse.ArgumentParser()
        parser.add_argument('-j', '--jobs', type=int)
        parser.add_argument('-q', '--quiet', type=int)

        # Other sphinx-build arguments go as-is, so place them
        # at self.sphinxopts
        sphinx_args, self.sphinxopts = parser.parse_known_args(sphinxopts)
        if sphinx_args.quiet == True:
            self.verbose = False

        if sphinx_args.jobs:
            self.n_jobs = sphinx_args.jobs

        # Command line arguments was passed, override SPHINXOPTS
        if verbose is not None:
            self.verbose = verbose

        self.n_jobs = n_jobs

        # Source tree directory. This needs to be at os.environ, as
        # Sphinx extensions and media uAPI makefile needs it
        self.srctree = os.environ.get("srctree")
        if not self.srctree:
            self.srctree = "."
            os.environ["srctree"] = self.srctree

        # Now that we can expand srctree, get other directories as well
        self.sphinxbuild = os.environ.get("SPHINXBUILD", "sphinx-build")
        self.kerneldoc = self.get_path(os.environ.get("KERNELDOC",
                                                      "scripts/kernel-doc.py"))
        self.obj = os.environ.get("obj", "Documentation")
        self.builddir = self.get_path(os.path.join(self.obj, "output"),
                                      abs_path=True)

        # Media uAPI needs it
        os.environ["BUILDDIR"] = self.builddir

        # Detect if rust is enabled
        self.config_rust = self.is_rust_enabled()

        # Get directory locations for LaTeX build toolchain
        self.pdflatex_cmd = shutil.which(self.pdflatex)
        self.latexmk_cmd = shutil.which("latexmk")

        self.env = os.environ.copy()

        # If venv parameter is specified, run Sphinx from venv
        if venv:
            bin_dir = os.path.join(venv, "bin")
            if os.path.isfile(os.path.join(bin_dir, "activate")):
                # "activate" virtual env
                self.env["PATH"] = bin_dir + ":" + self.env["PATH"]
                self.env["VIRTUAL_ENV"] = venv
                if "PYTHONHOME" in self.env:
                    del self.env["PYTHONHOME"]
                print(f"Setting venv to {venv}")
            else:
                sys.exit(f"Venv {venv} not found.")

    def run_sphinx(self, sphinx_build, build_args, *args, **pwargs):
        """
        Executes sphinx-build using current python3 command and setting
        -j parameter if possible to run the build in parallel.
        """

        with JobserverExec() as jobserver:
            if jobserver.claim:
                n_jobs = str(jobserver.claim)
            else:
                n_jobs = "auto" # Supported since Sphinx 1.7

            cmd = []

            if self.venv:
                cmd.append("python")
            else:
                cmd.append(sys.executable)

            cmd.append(sphinx_build)

            # if present, SPHINXOPTS or command line --jobs overrides default
            if self.n_jobs:
                n_jobs = str(self.n_jobs)

            if n_jobs:
                cmd += [f"-j{n_jobs}"]

            if not self.verbose:
                cmd.append("-q")

            cmd += self.sphinxopts

            cmd += build_args

            if self.verbose:
                print(" ".join(cmd))

            rc = subprocess.call(cmd, *args, **pwargs)

    def handle_html(self, css, output_dir):
        """
        Extra steps for HTML and epub output.

        For such targets, we need to ensure that CSS will be properly
        copied to the output _static directory
        """

        if not css:
            return

        css = os.path.expanduser(css)
        if not css.startswith("/"):
            css = os.path.join(self.srctree, css)

        static_dir = os.path.join(output_dir, "_static")
        os.makedirs(static_dir, exist_ok=True)

        try:
            shutil.copy2(css, static_dir)
        except (OSError, IOError) as e:
            print(f"Warning: Failed to copy CSS: {e}", file=sys.stderr)

    def build_pdf_file(self, latex_cmd, from_dir, path):
        """Builds a single pdf file using latex_cmd"""
        try:
            subprocess.run(latex_cmd + [path],
                            cwd=from_dir, check=True)

            return True
        except subprocess.CalledProcessError:
            # LaTeX PDF error code is almost useless: it returns
            # error codes even when build succeeds but has warnings.
            # So, we'll ignore the results
            return False

    def pdf_parallel_build(self, tex_suffix, latex_cmd, tex_files, n_jobs):
        """Build PDF files in parallel if possible"""
        builds = {}
        build_failed = False
        max_len = 0
        has_tex = False

        # Process files in parallel
        with futures.ThreadPoolExecutor(max_workers=n_jobs) as executor:
            jobs = {}

            for from_dir, pdf_dir, entry in tex_files:
                name = entry.name

                if not name.endswith(tex_suffix):
                    continue

                name = name[:-len(tex_suffix)]

                max_len = max(max_len, len(name))

                has_tex = True

                future = executor.submit(self.build_pdf_file, latex_cmd,
                                         from_dir, entry.path)
                jobs[future] = (from_dir, name, entry.path)

            for future in futures.as_completed(jobs):
                from_dir, name, path = jobs[future]

                pdf_name = name + ".pdf"
                pdf_from = os.path.join(from_dir, pdf_name)

                try:
                    success = future.result()

                    if success and os.path.exists(pdf_from):
                        pdf_to = os.path.join(pdf_dir, pdf_name)

                        os.rename(pdf_from, pdf_to)
                        builds[name] = os.path.relpath(pdf_to, self.builddir)
                    else:
                        builds[name] = "FAILED"
                        build_failed = True
                except Exception as e:
                    builds[name] = f"FAILED ({str(e)})"
                    build_failed = True

        # Handle case where no .tex files were found
        if not has_tex:
            name = "Sphinx LaTeX builder"
            max_len = max(max_len, len(name))
            builds[name] = "FAILED (no .tex file was generated)"
            build_failed = True

        return builds, build_failed, max_len

    def handle_pdf(self, output_dirs):
        """
        Extra steps for PDF output.

        As PDF is handled via a LaTeX output, after building the .tex file,
        a new build is needed to create the PDF output from the latex
        directory.
        """
        builds = {}
        max_len = 0
        tex_suffix = ".tex"

        # Get all tex files that will be used for PDF build
        tex_files = []
        for from_dir in output_dirs:
            pdf_dir = os.path.join(from_dir, "../pdf")
            os.makedirs(pdf_dir, exist_ok=True)

            if self.latexmk_cmd:
                latex_cmd = [self.latexmk_cmd, f"-{self.pdflatex}"]
            else:
                latex_cmd = [self.pdflatex]

            latex_cmd.extend(shlex.split(self.latexopts))

            # Get a list of tex files to process
            with os.scandir(from_dir) as it:
                for entry in it:
                    if entry.name.endswith(tex_suffix):
                        tex_files.append((from_dir, pdf_dir, entry))

        # When using make, this won't be used, as the number of jobs comes
        # from POSIX jobserver. So, this covers the case where build comes
        # from command line. On such case, serialize by default, except if
        # the user explicitly sets the number of jobs.
        n_jobs = 1

        # n_jobs is either an integer or "auto". Only use it if it is a number
        if self.n_jobs:
            try:
                n_jobs = int(self.n_jobs)
            except ValueError:
                pass

        # When using make, jobserver.claim is the number of jobs that were
        # used with "-j" and that aren't used by other make targets
        with JobserverExec() as jobserver:
            n_jobs = 1

            # Handle the case when a parameter is passed via command line,
            # using it as default, if jobserver doesn't claim anything
            if self.n_jobs:
                try:
                    n_jobs = int(self.n_jobs)
                except ValueError:
                    pass

            if jobserver.claim:
                n_jobs = jobserver.claim

            # Build files in parallel
            builds, build_failed, max_len = self.pdf_parallel_build(tex_suffix,
                                                                    latex_cmd,
                                                                    tex_files,
                                                                    n_jobs)

        msg = "Summary"
        msg += "\n" + "=" * len(msg)
        print()
        print(msg)

        for pdf_name, pdf_file in builds.items():
            print(f"{pdf_name:<{max_len}}: {pdf_file}")

        print()

        # return an error if a PDF file is missing

        if build_failed:
            sys.exit(f"PDF build failed: not all PDF files were created.")
        else:
            print("All PDF files were built.")

    def handle_info(self, output_dirs):
        """
        Extra steps for Info output.

        For texinfo generation, an additional make is needed from the
        texinfo directory.
        """

        for output_dir in output_dirs:
            try:
                subprocess.run(["make", "info"], cwd=output_dir, check=True)
            except subprocess.CalledProcessError as e:
                sys.exit(f"Error generating info docs: {e}")

    def cleandocs(self, builder):

        shutil.rmtree(self.builddir, ignore_errors=True)

    def build(self, target, sphinxdirs=None, conf="conf.py",
              theme=None, css=None, paper=None):
        """
        Build documentation using Sphinx. This is the core function of this
        module. It prepares all arguments required by sphinx-build.
        """

        builder = TARGETS[target]["builder"]
        out_dir = TARGETS[target].get("out_dir", "")

        # Cleandocs doesn't require sphinx-build
        if target == "cleandocs":
            self.cleandocs(builder)
            return

        # Other targets require sphinx-build
        sphinxbuild = shutil.which(self.sphinxbuild, path=self.env["PATH"])
        if not sphinxbuild:
            sys.exit(f"Error: {self.sphinxbuild} not found in PATH.\n")

        if builder == "latex":
            if not self.pdflatex_cmd and not self.latexmk_cmd:
                sys.exit("Error: pdflatex or latexmk required for PDF generation")

        docs_dir = os.path.abspath(os.path.join(self.srctree, "Documentation"))

        # Prepare base arguments for Sphinx build
        kerneldoc = self.kerneldoc
        if kerneldoc.startswith(self.srctree):
            kerneldoc = os.path.relpath(kerneldoc, self.srctree)

        # Prepare common Sphinx options
        args = [
            "-b", builder,
            "-c", docs_dir,
        ]

        if builder == "latex":
            if not paper:
                paper = PAPER[1]

            args.extend(["-D", f"latex_elements.papersize={paper}paper"])

        if self.config_rust:
            args.extend(["-t", "rustdoc"])

        if conf:
            self.env["SPHINX_CONF"] = self.get_path(conf, abs_path=True)

        if not sphinxdirs:
            sphinxdirs = os.environ.get("SPHINXDIRS", ".")

        # The sphinx-build tool has a bug: internally, it tries to set
        # locale with locale.setlocale(locale.LC_ALL, ''). This causes a
        # crash if language is not set. Detect and fix it.
        try:
            locale.setlocale(locale.LC_ALL, '')
        except Exception:
            self.env["LC_ALL"] = "C"
            self.env["LANG"] = "C"

        # sphinxdirs can be a list or a whitespace-separated string
        sphinxdirs_list = []
        for sphinxdir in sphinxdirs:
            if isinstance(sphinxdir, list):
                sphinxdirs_list += sphinxdir
            else:
                for name in sphinxdir.split(" "):
                    sphinxdirs_list.append(name)

        # Build each directory
        output_dirs = []
        for sphinxdir in sphinxdirs_list:
            src_dir = os.path.join(docs_dir, sphinxdir)
            doctree_dir = os.path.join(self.builddir, ".doctrees")
            output_dir = os.path.join(self.builddir, sphinxdir, out_dir)

            # Make directory names canonical
            src_dir = os.path.normpath(src_dir)
            doctree_dir = os.path.normpath(doctree_dir)
            output_dir = os.path.normpath(output_dir)

            os.makedirs(doctree_dir, exist_ok=True)
            os.makedirs(output_dir, exist_ok=True)

            output_dirs.append(output_dir)

            build_args = args + [
                "-d", doctree_dir,
                "-D", f"kerneldoc_bin={kerneldoc}",
                "-D", f"version={self.kernelversion}",
                "-D", f"release={self.kernelrelease}",
                "-D", f"kerneldoc_srctree={self.srctree}",
                src_dir,
                output_dir,
            ]

            # Execute sphinx-build
            try:
                self.run_sphinx(sphinxbuild, build_args, env=self.env)
            except Exception as e:
                sys.exit(f"Build failed: {e}")

            # Ensure that html/epub will have needed static files
            if target in ["htmldocs", "epubdocs"]:
                self.handle_html(css, output_dir)

        # PDF and Info require a second build step
        if target == "pdfdocs":
            self.handle_pdf(output_dirs)
        elif target == "infodocs":
            self.handle_info(output_dirs)

    @staticmethod
    def get_python_version(cmd):
        """
        Get python version from a Python binary. As we need to detect if
        are out there newer python binaries, we can't rely on sys.release here.
        """

        result = subprocess.run([cmd, "--version"], check=True,
                                stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                                universal_newlines=True)
        version = result.stdout.strip()

        match = re.search(r"(\d+\.\d+\.\d+)", version)
        if match:
            return parse_version(match.group(1))

        print(f"Can't parse version {version}")
        return (0, 0, 0)

    @staticmethod
    def find_python():
        """
        Detect if are out there any python 3.xy version newer than the
        current one.

        Note: this routine is limited to up to 2 digits for python3. We
        may need to update it one day, hopefully on a distant future.
        """
        patterns = [
            "python3.[0-9]",
            "python3.[0-9][0-9]",
        ]

        # Seek for a python binary newer than MIN_PYTHON_VERSION
        for path in os.getenv("PATH", "").split(":"):
            for pattern in patterns:
                for cmd in glob(os.path.join(path, pattern)):
                    if os.path.isfile(cmd) and os.access(cmd, os.X_OK):
                        version = SphinxBuilder.get_python_version(cmd)
                        if version >= MIN_PYTHON_VERSION:
                            return cmd

        return None

    @staticmethod
    def check_python():
        """
        Check if the current python binary satisfies our minimal requirement
        for Sphinx build. If not, re-run with a newer version if found.
        """
        cur_ver = sys.version_info[:3]
        if cur_ver >= MIN_PYTHON_VERSION:
            return

        python_ver = ver_str(cur_ver)

        new_python_cmd = SphinxBuilder.find_python()
        if not new_python_cmd:
            sys.exit(f"Python version {python_ver} is not supported anymore.")

        # Restart script using the newer version
        script_path = os.path.abspath(sys.argv[0])
        args = [new_python_cmd, script_path] + sys.argv[1:]

        print(f"Python {python_ver} not supported. Changing to {new_python_cmd}")

        try:
            os.execv(new_python_cmd, args)
        except OSError as e:
            sys.exit(f"Failed to restart with {new_python_cmd}: {e}")

def jobs_type(value):
    """
    Handle valid values for -j. Accepts Sphinx "-jauto", plus a number
    equal or bigger than one.
    """
    if value is None:
        return None

    if value.lower() == 'auto':
        return value.lower()

    try:
        if int(value) >= 1:
            return value

        raise argparse.ArgumentTypeError(f"Minimum jobs is 1, got {value}")
    except ValueError:
        raise argparse.ArgumentTypeError(f"Must be 'auto' or positive integer, got {value}")

def main():
    """
    Main function. The only mandatory argument is the target. If not
    specified, the other arguments will use default values if not
    specified at os.environ.
    """
    parser = argparse.ArgumentParser(description="Kernel documentation builder")

    parser.add_argument("target", choices=list(TARGETS.keys()),
                        help="Documentation target to build")
    parser.add_argument("--sphinxdirs", nargs="+",
                        help="Specific directories to build")
    parser.add_argument("--conf", default="conf.py",
                        help="Sphinx configuration file")

    parser.add_argument("--theme", help="Sphinx theme to use")

    parser.add_argument("--css", help="Custom CSS file for HTML/EPUB")

    parser.add_argument("--paper", choices=PAPER, default=PAPER[0],
                        help="Paper size for LaTeX/PDF output")

    parser.add_argument("-v", "--verbose", action='store_true',
                        help="place build in verbose mode")

    parser.add_argument('-j', '--jobs', type=jobs_type,
                        help="Sets number of jobs to use with sphinx-build")

    parser.add_argument('-i', '--interactive', action='store_true',
                        help="Change latex default to run in interactive mode")

    parser.add_argument("-V", "--venv", nargs='?', const=f'{VENV_DEFAULT}',
                        default=None,
                        help=f'If used, run Sphinx from a venv dir (default dir: {VENV_DEFAULT})')

    args = parser.parse_args()

    SphinxBuilder.check_python()

    builder = SphinxBuilder(venv=args.venv, verbose=args.verbose,
                            n_jobs=args.jobs, interactive=args.interactive)

    builder.build(args.target, sphinxdirs=args.sphinxdirs, conf=args.conf,
                  theme=args.theme, css=args.css, paper=args.paper)

if __name__ == "__main__":
    main()
