# conf.py — Sphinx configuration for the AutonomyOps docs repository.
#
# This repository hosts four documentation tiers from one shared source tree:
# public (repo root), controlled, saas, and self-hosted.  Each tier is built
# by pointing sphinx-build at the corresponding source directory while reusing
# this config via `-c .`.

from datetime import datetime

# -- Project information ------------------------------------------------------

project = "AutonomyOps ADK"
copyright = f"{datetime.now().year}, AutonomyOps"
author = "AutonomyOps Engineering"

# Version is intentionally left unset here; override at release time via
# -D release=<tag> or an environment-variable substitution in CI.
release = ""

# -- General configuration ----------------------------------------------------

extensions = [
    # MyST — parse all .md files as Markdown with MyST dialect.
    "myst_parser",
    # sphinxcontrib-mermaid — render ```mermaid fenced blocks as diagrams (S-PR3).
    "sphinxcontrib.mermaid",
    # sphinx-copybutton — clipboard copy button on every code block (S-PR3).
    "sphinx_copybutton",
    # sphinx-multiversion — versioned HTML builds from Git tags/branches (S-PR4).
    # Safe to load for single-version builds: when smv_metadata is empty the
    # extension's config-inited hook is a no-op.
    "sphinx_multiversion",
]

# MyST parser options.
# colon_fence        — allow ::: as an alternative to ``` for directives.
# deflist            — definition list syntax.
# tasklist           — GitHub-style task list checkboxes.
# attrs_inline       — inline attribute syntax {.classname}.
# fence_as_directive — treat ```mermaid fences as {mermaid} directives so
#                      sphinxcontrib-mermaid renders them as live diagrams.
myst_enable_extensions = [
    "colon_fence",
    "deflist",
    "tasklist",
    "attrs_inline",
]
myst_fence_as_directive = {"mermaid"}

# Enable auto-generated heading anchors so that cross-page links of the form
# [text](page.md#heading-slug) resolve correctly under sphinx-build -W.
# Depth 3 covers h1/h2/h3; deeper headings are rarely cross-linked.
myst_heading_anchors = 3

# Accept both reStructuredText and Markdown sources.
source_suffix = {
    ".rst": "restructuredtext",
    ".md": "markdown",
}

# Root document defaults to `index` so each tier can be built from its own
# source directory (`.`, `controlled/`, `saas/`, or `self-hosted/`) using the
# same config file.
root_doc = "index"

# Patterns relative to the source directory to exclude from Sphinx.
#
# Note: _generated/cli/ is intentionally NOT excluded — it contains the
# auto-generated CLI reference pages that are wired into the Sphinx nav via
# cli/index.md.  All other _generated/ subdirectories are excluded because
# they contain non-navigable artefacts (repo map, coverage, test outputs).
exclude_patterns = [
    # Sphinx own build output — avoid self-referential builds.
    "_sphinx_build",
    # MkDocs output directory.
    "site",
    # Auto-generated non-navigable artefacts (exclude these explicitly so
    # _generated/cli/ remains accessible to Sphinx).
    "_generated/coverage-report.md",
    "_generated/evidence-ledger.md",
    "_generated/repo-map.md",
    "_generated/tbd-report.md",
    "_generated/test-outputs",
    # MkDocs package-to-page mapping metadata.
    "_meta",
    # Repository metadata, not part of the published docs nav.
    "README.md",
    # Tier directories are built separately; exclude them from the public-root
    # build so gated content does not leak into the public artifact.
    "controlled",
    "saas",
    "self-hosted",
    # Internal-only founder and sales material — kept in the engineering repo.
    "internal",
    # OS / editor noise.
    "Thumbs.db",
    ".DS_Store",
]

# -- HTML output options -------------------------------------------------------

# Furo is a modern, accessible Sphinx theme with light/dark mode support.
# It is the Sphinx counterpart of the MkDocs Material theme used in parallel.
html_theme = "furo"

html_title = "AutonomyOps ADK"

html_theme_options = {
    "sidebar_hide_name": False,
    "source_repository": "https://github.com/AutonomyOps/docs/",
    "source_branch": "main",
    "source_directory": "/",
    # Enable left/right arrow key navigation between pages (S-PR3).
    "navigation_with_keys": True,
}

# Custom Jinja2 templates (e.g. sidebar/versioning.html for S-PR4).
templates_path = ["_templates"]

# Static files (CSS, JS, images) to copy into the _static output directory.
html_static_path = []

# Furo sidebar layout — inject a version selector between navigation and the
# scroll-end sentinel (S-PR4).  The template docs/_templates/sidebar/versioning.html
# renders a dropdown of available versions when sphinx-multiversion metadata is
# present; it is a no-op for single-version builds (guards on `versions`).
html_sidebars = {
    "**": [
        "sidebar/scroll-start.html",
        "sidebar/brand.html",
        "sidebar/search.html",
        "sidebar/navigation.html",
        "sidebar/versioning.html",
        "sidebar/scroll-end.html",
    ]
}

# -- Mermaid diagrams (sphinxcontrib-mermaid, S-PR3) --------------------------

# Pin mermaid.js to 10.2.0 — the last version fully compatible with the
# UMD CDN bundle used by sphinxcontrib-mermaid 0.9.2 (v11+ is ESM-only).
mermaid_version = "10.2.0"

# Initialise Mermaid with a neutral theme that works in both Furo light and
# dark modes.  'base' is the most customisable theme; diagram colours follow
# the page background.
mermaid_init_js = "mermaid.initialize({startOnLoad:true, theme:'neutral'});"

# -- Copy button (sphinx-copybutton, S-PR3) ------------------------------------

# Strip common shell prompts so copied text is paste-ready.
# Matches:  $   >   #   >>>   ...   (Python REPL continuation)
copybutton_prompt_text = r"(?:\$ |> |# |>>> |\.\.\. )"
copybutton_prompt_is_regexp = True

# When a code block contains prompt lines, copy only those lines and skip
# output lines so the copied text is a paste-ready set of commands.
copybutton_only_copy_prompt_lines = True

# -- sphinx-multiversion (S-PR4) -----------------------------------------------
#
# sphinx-multiversion builds one HTML tree per Git ref (tag or branch) and
# writes each into a subdirectory of the output root named by the ref.
#
# Single-version builds (make docs-sphinx / sphinx-build) are unaffected:
# when smv_metadata is empty the extension registers no hooks at all.
# Multi-version builds use: make docs-sphinx-multiversion
#                       or: sphinx-multiversion docs/ docs/_sphinx_build/multiversion/

# Only build SemVer release tags (e.g. v1.0.0, v2.3.1).
smv_tag_whitelist = r"^v\d+\.\d+\.\d+$"

# Build only the main development snapshot in this repo.
smv_branch_whitelist = r"^main$"

# Only include refs from the canonical remote.
smv_remote_whitelist = r"^origin$"

# Refs matching this pattern are considered released (shown as stable).
# Tags are always released; branches are development snapshots.
smv_released_pattern = r"^tags/v.*$"

# Each version's HTML is written to <outputdir>/<ref.name>/.
smv_outputdir_format = "{ref.name}"

# The branch that represents the most-recent development state.
smv_latest_version = "main"

suppress_warnings: list[str] = [
    # Several example code blocks in the docs contain JSON with '...' ellipsis
    # placeholders (valid for documentation, invalid as strict JSON).  Pygments'
    # JSON lexer rejects these tokens and emits a highlight warning.  Suppressing
    # here preserves strict (-W) builds while keeping example fidelity in the source.
    "misc.highlighting_failure",
]

# -- Conditional content tags (S-PR5: ce / paid tier) -------------------------
#
# Pass -t ce or -t paid to sphinx-build to produce a tier-filtered HTML tree:
#
#   sphinx-build -t ce   -b html docs/ docs/_sphinx_build/ce/
#   sphinx-build -t paid -b html docs/ docs/_sphinx_build/paid/
#
# Tag semantics
# -------------
# paid      — set in paid builds and in the default untagged build.
#             Gates paid-only content blocks: {only} paid
#
# ce        — set in CE builds and in the default untagged build.
#             Currently unused for content gating (reserved for future use
#             or for {only} ce blocks that should appear in BOTH the CE
#             build and the default build).
#
# ce_only   — set ONLY in CE builds (never in the default untagged build).
#             Gates CE-specific warning admonitions that must NOT appear in
#             the default untagged build:
#
#               ::::{only} ce_only
#               :::{note}
#               ... CE-audience notice ...
#               :::
#               ::::
#
# When neither tag is passed (plain make docs-sphinx / sphinx-build), both
# `ce` and `paid` are injected so all {only} paid blocks render.  `ce_only`
# is deliberately NOT injected, so CE-only admonitions remain absent from
# the default build — preserving the pre-S-PR5 default-build output exactly.
# tags is None when sphinx-multiversion loads conf.py to enumerate versions
# (it calls load_sphinx_config without a live Sphinx application, so the tags
# object is never initialised).  Guard every tags.has() call so the config
# loads cleanly in that context; the tier-filter logic is a no-op in that
# pass and the real per-tag builds run correctly via sphinx-build -t.
if tags is not None and not tags.has("ce") and not tags.has("paid"):
    tags.add("ce")
    tags.add("paid")

# ce_only: a synthetic tag set exclusively for CE-only builds.  Gating
# admonitions on this tag (instead of plain `ce`) ensures they are absent
# from the default untagged build where both `ce` and `paid` are active.
if tags is not None and tags.has("ce") and not tags.has("paid"):
    tags.add("ce_only")


# Tier-filtered page exclusions.
# Paid-only pages are excluded entirely from CE builds so they are not built
# into the CE HTML tree at all. The corresponding toctree entries are wrapped
# in {only} paid where possible; pages whose toctree placement cannot be
# tier-gated rely on the suppress_warnings entries below.
if tags is not None and tags.has("ce") and not tags.has("paid"):
    # The dedicated SaaS/self-hosted tier sources now live outside the public
    # root, so the old CE exclusions for paid-root pages are no longer needed.
    # Keep the block in place as the anchor for any future public-root CE-only
    # exclusions without carrying forward the previous orchestrator-page rules.
    pass
