#!/usr/bin/env bash
# Verify that AGENTS.md and the docs audience indexes stay in sync.
#
# Checks:
#   1. Every docs/ link from AGENTS.md, docs/user/index.md, and
#      docs/dev/index.md exists.
#   2. Every canonical docs file is discoverable from those indexes.
#
# Release notes are represented by the docs/releases/ directory entry instead
# of requiring every per-version release note to be linked individually.

set -euo pipefail

repo_root="$(cd "$(dirname "$0")/.." && pwd)"
cd "$repo_root"

index_files=(AGENTS.md docs/user/index.md docs/dev/index.md)
for index_file in "${index_files[@]}"; do
  if [[ ! -f "$index_file" ]]; then
    echo "error: $index_file not found" >&2
    exit 1
  fi
done

normalize_path() {
  python3 - "$1" <<'PY'
import os
import sys

print(os.path.normpath(sys.argv[1]).replace(os.sep, "/"))
PY
}

canonical=()
while IFS= read -r line; do
  canonical+=("$line")
done < <(find docs -type f -name '*.md' ! -path 'docs/releases/*' ! -path 'docs/internal/*' ! -path 'docs/rfcs/*' | sort)
if [[ -d docs/releases ]]; then
  canonical+=("docs/releases/")
fi
# RFCs are a growing collection (like releases): represent the directory, not
# every per-RFC file. The dir must be linked from an audience index.
if [[ -d docs/rfcs ]]; then
  canonical+=("docs/rfcs/")
fi

linked=()
for index_file in "${index_files[@]}"; do
  base_dir="$(dirname "$index_file")"

  # Markdown links.
  while IFS= read -r raw_link; do
    link="${raw_link%%#*}"
    [[ -z "$link" ]] && continue
    [[ "$link" =~ ^[a-zA-Z][a-zA-Z0-9+.-]*: ]] && continue
    [[ "$link" == /* ]] && continue

    if [[ "$link" == docs/* ]]; then
      normalized="$(normalize_path "$link")"
    else
      normalized="$(normalize_path "$base_dir/$link")"
    fi
    if [[ "$link" == */ ]]; then
      normalized="${normalized%/}/"
    fi
    linked+=("$normalized")
  done < <(
    grep -oE '\[[^]]+\]\([^)]+\)' "$index_file" \
      | sed -E 's/.*\(([^)]+)\).*/\1/' || true
  )

  # Agent import directives in AGENTS.md.
  while IFS= read -r raw_link; do
    link="${raw_link#@}"
    linked+=("$(normalize_path "$link")")
  done < <(grep -oE '^@docs/[^[:space:]]+' "$index_file" || true)
done

deduped=()
while IFS= read -r line; do
  deduped+=("$line")
done < <(printf '%s\n' "${linked[@]}" | sort -u)
linked=("${deduped[@]}")

fail=0

for link in "${linked[@]}"; do
  if [[ "$link" == */ ]]; then
    if [[ ! -d "$link" ]]; then
      echo "error: docs index links to missing directory: $link" >&2
      fail=1
    fi
  else
    if [[ ! -f "$link" ]]; then
      echo "error: docs index links to missing file: $link" >&2
      fail=1
    fi
  fi
done

for doc in "${canonical[@]}"; do
  found=0
  for link in "${linked[@]}"; do
    if [[ "$link" == "$doc" ]]; then
      found=1
      break
    fi
  done
  if [[ "$found" -eq 0 ]]; then
    echo "error: doc not linked from AGENTS.md or audience indexes: $doc" >&2
    fail=1
  fi
done

if [[ "$fail" -ne 0 ]]; then
  echo >&2
  echo "AGENTS.md / docs indexes are out of sync. Update AGENTS.md, docs/user/index.md, or docs/dev/index.md." >&2
  exit 1
fi

echo "AGENTS.md ↔ docs indexes OK (${#linked[@]} links, ${#canonical[@]} docs)."
