#!/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 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("/"):
            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")

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