name: Deploy Docs

on:
  push:
    branches: ["main"]
    paths: ["site/**", ".github/workflows/docs.yml"]
  workflow_dispatch:

permissions:
  contents: read

concurrency:
  group: pages
  cancel-in-progress: true

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          persist-credentials: false
          # Full history: add-sitemap-lastmod.mjs stamps per-file git dates.
          fetch-depth: 0
      - uses: pnpm/action-setup@v6
        with:
          version: 11
      - uses: actions/setup-node@v6
        with:
          node-version: 22
          cache: pnpm
          cache-dependency-path: site/pnpm-lock.yaml
      - name: Regenerate llms.txt from docs (freshness guarantee)
        run: python3 scripts/generate_llms.py
      - name: Check EN/ES translation parity
        run: node scripts/check-i18n-parity.mjs
        working-directory: site
      - name: Build site
        run: pnpm install --frozen-lockfile && pnpm build
        working-directory: site
      - name: Validate HTML
        run: pnpm run html-validate
        working-directory: site
      - name: Accessibility audit (pa11y, WCAG2AA)
        run: pnpm run pa11y
        working-directory: site
      - uses: actions/upload-pages-artifact@v5
        with:
          path: site/dist

  deploy:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      pages: write
      id-token: write
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    outputs:
      page_url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - id: deployment
        uses: actions/deploy-pages@v5

  indexnow:
    name: Submit URLs to IndexNow
    needs: deploy
    runs-on: ubuntu-latest
    permissions: {}
    timeout-minutes: 10
    steps:
      - name: Submit sitemap URLs to IndexNow
        env:
          INDEXNOW_KEY: ${{ secrets.INDEXNOW_KEY }}
          PAGE_URL: ${{ needs.deploy.outputs.page_url }}
        run: |
          set -euo pipefail
          if [ -z "${INDEXNOW_KEY:-}" ]; then
            echo "::error::INDEXNOW_KEY secret is not set"; exit 1
          fi
          python3 - <<'PY'
          import json, os, sys, time, urllib.request, xml.etree.ElementTree as ET
          from urllib.parse import urlparse

          TIMEOUT = 30
          key = os.environ["INDEXNOW_KEY"]
          base = os.environ["PAGE_URL"].rstrip("/")
          host = urlparse(base).netloc

          def fetch(url):
              with urllib.request.urlopen(url, timeout=TIMEOUT) as r:
                  return r.read()

          # Pages can take a moment to propagate after deploy: retry the key file.
          key_url = f"{base}/{key}.txt"
          for attempt in range(6):
              try:
                  assert fetch(key_url).decode().strip() == key
                  break
              except Exception:
                  if attempt == 5:
                      sys.exit(f"key file unreachable: {key_url}")
                  time.sleep(2 ** attempt)

          ns = {"sm": "http://www.sitemaps.org/schemas/sitemap/0.9"}
          index = ET.fromstring(fetch(f"{base}/sitemap-index.xml"))
          urls = []
          for shard in index.findall("sm:sitemap/sm:loc", ns):
              tree = ET.fromstring(fetch(shard.text.strip()))
              urls += [loc.text.strip() for loc in tree.findall("sm:url/sm:loc", ns)]
          if not urls:
              sys.exit("sitemap produced no URLs")

          payload = json.dumps({
              "host": host, "key": key, "keyLocation": key_url, "urlList": urls,
          }).encode()
          req = urllib.request.Request(
              "https://api.indexnow.org/IndexNow", data=payload,
              headers={"Content-Type": "application/json; charset=utf-8"},
          )
          with urllib.request.urlopen(req, timeout=TIMEOUT) as r:
              print(f"IndexNow HTTP {r.status} ({len(urls)} URLs submitted)")
              if r.status not in (200, 202):
                  sys.exit(f"unexpected status {r.status}: {r.read()[:300]}")
          PY
