#!/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/python"
SRC_DIR = os.path.dirname(os.path.realpath(__file__))

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

from kdoc.python_version import PythonVersion
from kdoc.latex_fonts import LatexFontChecker
from jobserver import JobserverExec         # pylint: disable=C0413,C0411,E0401

#
#  Some constants
#
VENV_DEFAULT = "sphinx_latest"
MIN_PYTHON_VERSION = PythonVersion("3.7").version
PAPER = ["", "a4", "letter"]

TARGETS = {
    "cleandocs":     { "builder": "clean" },
    "linkcheckdocs": { "builder": "linkcheck" },
    "htmldocs":      { "builder": "html" },
    "epubdocs":      { "builder": "epub",    "out_dir": "epub" },
    "texinfodocs":   { "builder": "texinfo", "out_dir": "texinfo" },
    "infodocs":      { "builder": "texinfo", "out_dir": "texinfo" },
    "mandocs":       { "builder": "man",     "out_dir": "man" },
    "latexdocs":     { "builder": "latex",   "out_dir": "latex" },
    "pdfdocs":       { "builder": "latex",   "out_dir": "latex" },
    "xmldocs":       { "builder": "xml",     "out_dir": "xml" },
}


#
# SphinxBuilder class
#

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

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

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

        path = os.path.expanduser(path)
        if not path.startswith("/"):
            if use_cwd:
                base = os.getcwd()
            else:
                base = self.srctree

            path = os.path.join(base, path)

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

        return path

    def check_rust(self, sphinxdirs):
        """
        Checks if Rust is enabled
        """
        config = os.path.join(self.srctree, ".config")

        if not {'.', 'rust'}.intersection(sphinxdirs):
            return False

        if not os.path.isfile(config):
            return False

        re_rust = re.compile(r"CONFIG_RUST=(m|y)")

        try:
            with open(config, "r", encoding="utf-8") as fp:
                for line in fp:
                    if re_rust.match(line):
                        return True

        except OSError as e:
            print(f"Failed to open {config}", file=sys.stderr)
            return False

        return False

    def get_sphinx_extra_opts(self, n_jobs):
        """
        Get the number of jobs to be used for docs build passed via command
        line and desired sphinx verbosity.

        The number of jobs can be on different places:

        1) It can be passed via "-j" argument;
        2) The SPHINXOPTS="-j8" env var may have "-j";
        3) if called via GNU make, -j specifies the desired number of jobs.
           with GNU makefile, this number is available via POSIX jobserver;
        4) if none of the above is available, it should default to "-jauto",
           and let sphinx decide the best value.
        """

        #
        # SPHINXOPTS env var, if used, contains extra arguments to be used
        # by sphinx-build time. Among them, it may contain sphinx verbosity
        # and desired number of parallel jobs.
        #
        parser = argparse.ArgumentParser()
        parser.add_argument('-j', '--jobs', type=int)
        parser.add_argument('-q', '--quiet', action='store_true')
        parser.add_argument('-v', '--verbose', default=0, action='count')

        #
        # Other sphinx-build arguments go as-is, so place them
        # at self.sphinxopts, using shell parser
        #
        sphinxopts = shlex.split(os.environ.get("SPHINXOPTS", ""))

        #
        # Build a list of sphinx args, honoring verbosity here if specified
        #

        sphinx_args, self.sphinxopts = parser.parse_known_args(sphinxopts)

        verbose = sphinx_args.verbose
        if self.verbose:
            verbose += 1

        if sphinx_args.quiet is True:
            verbose = 0

        #
        # If the user explicitly sets "-j" at command line, use it.
        # Otherwise, pick it from SPHINXOPTS args
        #
        if n_jobs:
            self.n_jobs = n_jobs
        elif sphinx_args.jobs:
            self.n_jobs = sphinx_args.jobs
        else:
            self.n_jobs = None

        if verbose < 1:
            self.sphinxopts += ["-q"]
        else:
            for i in range(1, sphinx_args.verbose):
                self.sphinxopts += ["-v"]

    def __init__(self, builddir, 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")

        #
        # Add localversion* to kernelversion if present
        #
        for file in glob(os.environ["srctree"] + "/localversion*"):
            if not file.endswith(".orig"):
                with open(file, 'r', encoding='utf-8') as f:
                    text = f.read()
                    self.kernelversion += text

        #
        # Kernel main Makefile defines a PYTHON3 variable whose default is
        # "python3". When set to a different value, it allows running a
        # diferent version than the default official python3 package.
        # Several distros package python3xx-sphinx packages with newer
        # versions of Python and sphinx-build.
        #
        # Honor such variable different than default
        #
        self.python = os.environ.get("PYTHON3")
        if self.python == "python3":
            self.python = None

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

        if not verbose:
            try:
                verbose = bool(int(os.environ.get("KBUILD_VERBOSE", 0)))
            except ValueError:
                # Handles an eventual case where verbosity is not a number
                # like KBUILD_VERBOSE=""
                verbose = False

        if verbose is not None:
            self.verbose = verbose

        #
        # Source tree directory. This needs to be at os.environ, as
        # Sphinx extensions use 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",
                                                      "tools/docs/kernel-doc"))
        self.builddir = self.get_path(builddir, use_cwd=True, abs_path=True)

        #
        # 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()

        self.get_sphinx_extra_opts(n_jobs)

        #
        # If venv command line argument is specified, run Sphinx from venv
        #
        if venv:
            bin_dir = os.path.join(venv, "bin")
            if not os.path.isfile(os.path.join(bin_dir, "activate")):
                sys.exit(f"Venv {venv} not found.")

            # "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}")

    def run_sphinx(self, sphinx_build, build_args, *args, **pwargs):
        """
        Executes sphinx-build using current python3 command.

        When calling via GNU make, POSIX jobserver is used to tell how
        many jobs are still available from a job pool. claim all remaining
        jobs, as we don't want sphinx-build to run in parallel with other
        jobs.

        Despite that, the user may actually force a different value than
        the number of available jobs via command line.

        The "with" logic here is used to ensure that the claimed jobs will
        be freed once subprocess finishes
        """

        with JobserverExec() as jobserver:
            if jobserver.claim:
                #
                # when GNU make is used, claim available jobs from jobserver
                #
                n_jobs = str(jobserver.claim)
            else:
                #
                # Otherwise, let sphinx decide by default
                #
                n_jobs = "auto"

            #
            # If explicitly requested via command line, override default
            #
            if self.n_jobs:
                n_jobs = str(self.n_jobs)

            #
            # We can't simply call python3 sphinx-build, as OpenSUSE
            # Tumbleweed uses an ELF binary file (/usr/bin/alts) to switch
            # between different versions of sphinx-build. So, only call it
            # prepending "python3.xx" when PYTHON3 variable is not default.
            #
            if self.python:
                cmd = [self.python]
            else:
                cmd = []

            cmd += [sphinx_build]
            cmd += [f"-j{n_jobs}"]
            cmd += build_args
            cmd += self.sphinxopts

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

            return 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 css:
            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, env=self.env)

            return True
        except subprocess.CalledProcessError:
            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

        #
        # LaTeX PDF error code is almost useless for us:
        # any warning makes it non-zero. For kernel doc builds it always return
        # non-zero even when build succeeds. So, let's do the best next thing:
        # Ignore build errors. At the end, check if all PDF files were built,
        # printing a summary with the built ones and returning 0 if all of
        # them were actually built.
        #
        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)]
                has_tex = True

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

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

                pdf_name = name + ".pdf"
                pdf_from = os.path.join(from_dir, pdf_name)
                pdf_to = os.path.join(pdf_dir, pdf_name)
                out_name = os.path.relpath(pdf_to, self.builddir)
                max_len = max(max_len, len(out_name))

                try:
                    success = future.result()

                    if success and os.path.exists(pdf_from):
                        os.rename(pdf_from, pdf_to)

                        #
                        # if verbose, get the name of built PDF file
                        #
                        if self.verbose:
                           builds[out_name] = "SUCCESS"
                    else:
                        builds[out_name] = "FAILED"
                        build_failed = True
                except futures.Error as e:
                    builds[out_name] = f"FAILED ({repr(e)})"
                    build_failed = True

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

        return builds, build_failed, max_len

    def handle_pdf(self, output_dirs, deny_vf):
        """
        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"
        tex_files = []

        #
        # Since early 2024, Fedora and openSUSE tumbleweed have started
        # deploying variable-font format of "Noto CJK", causing LaTeX
        # to break with CJK. Work around it, by denying the variable font
        # usage during xelatex build by passing the location of a config
        # file with a deny list.
        #
        # See tools/docs/lib/latex_fonts.py for more details.
        #
        if deny_vf:
            deny_vf = os.path.expanduser(deny_vf)
            if os.path.isdir(deny_vf):
                self.env["XDG_CONFIG_HOME"] = deny_vf

        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

            builds, build_failed, max_len = self.pdf_parallel_build(tex_suffix,
                                                                    latex_cmd,
                                                                    tex_files,
                                                                    n_jobs)

        #
        # In verbose mode, print a summary with the build results per file.
        # Otherwise, print a single line with all failures, if any.
        # On both cases, return code 1 indicates build failures,
        #
        if self.verbose:
            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()
            if build_failed:
                msg = LatexFontChecker().check()
                if msg:
                    print(msg)

                sys.exit("Error: not all PDF files were created.")

        elif build_failed:
            n_failures = len(builds)
            failures = ", ".join(builds.keys())

            msg = LatexFontChecker().check()
            if msg:
                print(msg)

            sys.exit(f"Error: Can't build {n_failures} PDF file(s): {failures}")

    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 handle_man(self, kerneldoc, docs_dir, src_dir, output_dir):
        """
        Create man pages from kernel-doc output
        """

        re_kernel_doc = re.compile(r"^\.\.\s+kernel-doc::\s*(\S+)")

        if docs_dir == src_dir:
            #
            # Pick the entire set of kernel-doc markups from the entire tree
            #
            kdoc_files = set([self.srctree])
        else:
            kdoc_files = set()

            for fname in glob(os.path.join(src_dir, "**"), recursive=True):
                if os.path.isfile(fname) and fname.endswith(".rst"):
                    with open(fname, "r", encoding="utf-8") as in_fp:
                        data = in_fp.read()

                    for line in data.split("\n"):
                        match = re_kernel_doc.match(line)
                        if match:
                            if os.path.isfile(match.group(1)):
                                kdoc_files.add(match.group(1))

        if not kdoc_files:
                sys.exit(f"Directory {src_dir} doesn't contain kernel-doc tags")

        cmd = [ kerneldoc, "-m" ] + sorted(kdoc_files)
        try:
            if self.verbose:
                print(" ".join(cmd))

            result = subprocess.run(cmd, stdout=subprocess.PIPE, text= True)

            if result.returncode:
                print(f"Warning: kernel-doc returned {result.returncode} warnings")

        except (OSError, ValueError, subprocess.SubprocessError) as e:
            sys.exit(f"Failed to create man pages for {src_dir}: {repr(e)}")

        fp = None
        try:
            for line in result.stdout.split("\n"):
                if not line.startswith(".TH"):
                    if fp:
                        fp.write(line + '\n')
                    continue

                if fp:
                    fp.close()

                # Use shlex here, as it handles well parameters with commas
                args = shlex.split(line)
                fname = f"{args[1]}.{args[2]}"
                fname = fname.replace("/", " ")
                fname = f"{output_dir}/{fname}"

                if self.verbose:
                    print(f"Creating {fname}")
                fp = open(fname, "w", encoding="utf-8")
                fp.write(line + '\n')
        finally:
            if fp:
                fp.close()

    def cleandocs(self, builder):           # pylint: disable=W0613
        """Remove documentation output directory"""
        shutil.rmtree(self.builddir, ignore_errors=True)

    def build(self, target, sphinxdirs=None,
              theme=None, css=None, paper=None, deny_vf=None,
              skip_sphinx=False):
        """
        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

        if theme:
            os.environ["DOCS_THEME"] = theme

        #
        # Other targets require sphinx-build, so check if it exists
        #
        if not skip_sphinx:
            sphinxbuild = shutil.which(self.sphinxbuild, path=self.env["PATH"])
            if not sphinxbuild and target != "mandocs":
                sys.exit(f"Error: {self.sphinxbuild} not found in PATH.\n")

        if target == "pdfdocs":
            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"))

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

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

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

        args = [ "-b", builder, "-c", docs_dir ]

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

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

        rustdoc = self.check_rust(sphinxdirs_list)
        if rustdoc:
            args.extend(["-t", "rustdoc"])

        #
        # 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 locale.Error:
            self.env["LC_ALL"] = "C"

        #
        # Step 1:  Build each directory in separate.
        #
        # This is not the best way of handling it, as cross-references between
        # them will be broken, but this is what we've been doing since
        # the beginning.
        #
        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"version={self.kernelversion}",
                "-D", f"release={self.kernelrelease}",
                "-D", f"kerneldoc_srctree={self.srctree}",
                src_dir,
                output_dir,
            ]

            if target == "mandocs":
                self.handle_man(kerneldoc, docs_dir, src_dir, output_dir)
            elif not skip_sphinx:
                try:
                    result = self.run_sphinx(sphinxbuild, build_args,
                                             env=self.env)

                    if result:
                        sys.exit(f"Build failed: return code: {result}")

                except (OSError, ValueError, subprocess.SubprocessError) as e:
                    sys.exit(f"Build failed: {repr(e)}")

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

        #
        # Step 2: Some targets (PDF and info) require an extra step once
        #         sphinx-build finishes
        #
        if target == "pdfdocs":
            self.handle_pdf(output_dirs, deny_vf)
        elif target == "infodocs":
            self.handle_info(output_dirs)

        if rustdoc and target in ["htmldocs", "epubdocs"]:
            print("Building rust docs")
            if "MAKE" in self.env:
                cmd = [self.env["MAKE"]]
            else:
                cmd = ["make", "LLVM=1"]

            cmd += [ "rustdoc"]
            if self.verbose:
                print(" ".join(cmd))

            try:
                subprocess.run(cmd, check=True)
            except subprocess.CalledProcessError as e:
                print(f"Ignored errors when building rustdoc: {e}. Is RUST enabled?",
                      file=sys.stderr)

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}")  # pylint: disable=W0707

EPILOG="""
Besides the command line arguments, several environment variables affect its
default behavior, meant to be used when called via Kernel Makefile:

- KERNELVERSION:  Kernel major version
- KERNELRELEASE:  Kernel release
- KBUILD_VERBOSE: Contains the value of "make V=[0|1] variable.
                  When V=0 (KBUILD_VERBOSE=0), sets verbose level to "-q".
- SPHINXBUILD:    Documentation build tool (default: "sphinx-build").
- SPHINXOPTS:     Extra options pased to SPHINXBUILD
                  (default: "-j auto" and "-q" if KBUILD_VERBOSE=0).
                  The "-v" flag can be used to increase verbosity.
                  If V=0, the first "-v" will drop "-q".
- PYTHON3:        Python command to run SPHINXBUILD
- PDFLATEX:       LaTeX PDF engine. (default: "xelatex")
- LATEXOPTS:      Optional set of command line arguments to the LaTeX engine
- srctree:        Location of the Kernel root directory (default: ".").

"""

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(formatter_class=argparse.RawTextHelpFormatter,
                                     description=__doc__,
                                     epilog=EPILOG)

    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("--builddir", default="output",
                        help="Sphinx configuration file (default: %(default)s)")

    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('--deny-vf',
                        help="Configuration to deny variable fonts on pdf builds")

    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(default: auto)")

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

    parser.add_argument('-s', '--skip-sphinx-build', action='store_true',
                        help="Skip sphinx-build step")

    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()

    PythonVersion.check_python(MIN_PYTHON_VERSION, show_alternatives=True,
                               bail_out=True)

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

    builder.build(args.target, sphinxdirs=args.sphinxdirs,
                  theme=args.theme, css=args.css, paper=args.paper,
                  deny_vf=args.deny_vf,
                  skip_sphinx=args.skip_sphinx_build)

if __name__ == "__main__":
    main()
