# http://www.sphinx-doc.org/en/stable/config.html
#
# pylint: disable=wrong-import-position,invalid-name  # Disable for file: These checks just can't be satisfied here.

import collections
import glob
import os
import pathlib
import re
import subprocess
import sys

# Add local package dir to path
sys.path.insert(0, os.path.abspath("../src"))

from mini_buildd import api, config, util, webapp  # noqa (pep8 E402)

# Pseudo-configure webapp
webapp.pseudo_configure()

# Autogenerate API documentation for package mini_buildd
# Strange to do this here, but it (works and) seems more coherent than extra support in setup.py
subprocess.check_call(["sphinx-apidoc", "--force", "--separate", "--output-dir", "./python/", "../src/mini_buildd/"])

# Autogenerate static HTML man pages for all commands
os.makedirs("_static/man", exist_ok=True)
COMMANDS = []
for manpage in glob.glob("../src/*.[18]"):
    name = os.path.splitext(os.path.basename(manpage))[0]
    html_file_path = os.path.join("_static/man", name + ".html")
    COMMANDS.append(name)
    print(f"Creating HTML manpage: {manpage} -> {html_file_path}")
    with open(html_file_path, "w", encoding="UTF-8") as f:
        # split magic: Remove CGI header produced by man2html
        f.write(subprocess.check_output(["man2html", "-M", "/static/manual/", manpage]).decode("UTF-8").split("\n", 2)[2])

# Autogenerate admonitions rst (hack)
ADMONITIONS = collections.OrderedDict([
    ("error", ["(BUG) Ongoing issues: No fix yet", []]),
    ("attention", ["(TODO) Ongoing issues: Minor or has workaround", []]),
    ("note", ["(NOTE) Something not obvious you should be aware of", []]),
    ("tip", ["(FAQ) Free tip", []]),
])
ADMONITIONS_FILE = "auto_admonitions.rst"


def pysources():
    return [f".{s}" for s in subprocess.check_output(["./pysources"], cwd="..", encoding="UTF-8").splitlines()]


#: list of tuples: [(file_path, file_hr_id)]
for gen in [
        [pathlib.Path(".").rglob("*.rst"), lambda fn: os.path.splitext(fn)[0]],
        # "../src/mini_buildd/<module>.py" -> "mini_buildd.<module>"
        [pysources(), lambda fn: "python/" + os.path.splitext(str(fn).removeprefix("../src/"))[0].replace("/", ".").replace(".__init__", "")],
        [pathlib.Path("../src/mini_buildd/templates/").rglob("*.html"), lambda fn: "/".join(fn.parts[3:])],
]:
    for f_name in gen[0]:
        if str(f_name) == ADMONITIONS_FILE:
            continue

        with open(f_name, encoding="UTF-8") as f:
            for line in f:
                m = re.match(rf".*\.\. ({'|'.join(ADMONITIONS.keys())}):: (.*)", line)
                if m:
                    print(f"Found admonition: {f_name} ({m[1]}): {m[2]}")
                    ADMONITIONS[m[1]][1].append([gen[1](f_name), m[2]])

with open(ADMONITIONS_FILE, "w", encoding="UTF-8") as f:
    f.write(f"""\
Admonitions (FAQ, NOTE, TODO, BUG)
##################################

Automated index of all admonitions (in this manual as well as in
python code documentation). For simplicity, we only use four
admonitions: *{", ".join(ADMONITIONS)}*.

""")
    for typ, admonitions in ADMONITIONS.items():
        f.write(f"""
.. {typ}:: **{admonitions[0]}**

""")
        for admonition in sorted(admonitions[1]):
            f.write(f"  * `{admonition[0]} <{admonition[0]}.html>`_: {admonition[1]}\n")

# Project data
project = "mini-buildd"
project_copyright = "2012-2024, mini-buildd maintainers"
version = util.__version__
release = util.__version__

# Config
extensions = [
    "sphinx.ext.extlinks",
    "sphinx.ext.autodoc",
    "sphinx.ext.graphviz",
    "sphinx.ext.autosectionlabel",
    "sphinx_ext_mini_buildd",
]
templates_path = ["_templates"]
source_suffix = ".rst"
master_doc = "index"
exclude_patterns = ["_build"]

rst_epilog = ""
for key, uri in config.URIS.items():
    uri = uri.get("view")
    if uri is not None:
        rst_epilog += f".. _{key}: {uri}\n"

# Style
html_theme = "alabaster"
html_logo = "../src/mini_buildd/static/icons/mini-buildd.svg"
html_favicon = html_logo
html_theme_options = {
    "page_width": "95%",
    "body_max_width": "auto",
    "tip_bg": "lightgreen",
    "note_bg": "lightyellow",
    "globaltoc_maxdepth": 3,
}
html_static_path = ["_static"]
html_sidebars = {
    "**": [
        "globaltoc.html",
        "relations.html",
        "searchbox.html",
        "mbd-sidebar-commands.html",
        "mbd-sidebar-apicalls.html",
    ]
}
html_context = {
    "COMMANDS": COMMANDS,
    "APICALLS": api.CALLS,
}

# Extensions
extlinks = {
    "debbug": ("https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%s", "Debian Bug #%s"),
    "debpkg": ("https://tracker.debian.org/pkg/%s", "Debian package '%s'"),
    "mbdpage": ("/mini_buildd/%s", "mini-buildd's '%s' page"),
    "mbdcommand": ("_static/man/%s.html", "command '%s'"),
    "apicall": ("/mini_buildd/api/?call=%s", "API call '%s'"),
}
autodoc_member_order = "bysource"   # Order members like in source (sphinx default (strangely enough) seems to be alphabetic order)
autosectionlabel_prefix_document = True

suppress_warnings = [
    "config.cache",  # sphinx 7.3.7: Some config elements (like api.CALLS) can't be pickled/cached. Avoid warnings for that.
]
