#!/usr/bin/env bash
set -euo pipefail

usage() {
  cat >&2 <<'USAGE'
Usage:
  assemble-doc.sh <template.md.tmpl|template.<lang>.md.tmpl> <blocks-file> <output.md>

Reads a Markdown template containing {{KEY}} placeholders and a content file
containing @@KEY@@ blocks. Writes the rendered Markdown to <output.md>.
USAGE
}

fail() {
  echo "assemble-doc: $*" >&2
  exit 1
}

if [[ $# -ne 3 ]]; then
  usage
  exit 64
fi

TEMPLATE="$1"
BLOCKS="$2"
OUT="$3"

[[ -f "$TEMPLATE" ]] || fail "template not found: $TEMPLATE"
[[ -f "$BLOCKS" ]] || fail "blocks file not found: $BLOCKS"

TMP="${OUT}.tmp.$$"
trap 'rm -f "$TMP"' EXIT

awk '
  { sub(/\r$/, "") }

  FILENAME == ARGV[1] {
    template[++tn] = $0
    line = $0
    while (match(line, /\{\{[A-Z0-9_]+\}\}/)) {
      key = substr(line, RSTART + 2, RLENGTH - 4)
      needed[key] = 1
      line = substr(line, RSTART + RLENGTH)
    }
    next
  }

  FILENAME == ARGV[2] {
    if ($0 ~ /^@@[A-Z0-9_]+@@[ \t]*$/) {
      key = $0
      gsub(/^@@/, "", key); gsub(/@@[ \t]*$/, "", key)
      cur = key; blocks[cur] = ""; seen[cur] = 1
      next
    }
    if (cur != "")
      blocks[cur] = (blocks[cur] == "" ? $0 : blocks[cur] "\n" $0)
    next
  }

  END {
    miss = ""
    for (k in needed)
      if (!(k in seen)) miss = miss " @@" k "@@"
    if (miss != "") {
      print "assemble-doc: missing required block(s):" miss > "/dev/stderr"
      exit 3
    }

    for (k in blocks) {
      v = blocks[k]
      sub(/[ \t\r\n]+$/, "", v)
      while (substr(v, 1, 1) == "\n") v = substr(v, 2)
      blocks[k] = v
    }

    for (i = 1; i <= tn; i++) {
      line = template[i]
      if (line ~ /^\{\{[A-Z0-9_]+\}\}$/) {
        key = line
        gsub(/^\{\{/, "", key); gsub(/\}\}$/, "", key)
        print blocks[key]
        continue
      }
      while (match(line, /\{\{[A-Z0-9_]+\}\}/)) {
        ph = substr(line, RSTART, RLENGTH)
        key = substr(ph, 3, length(ph) - 4)
        val = blocks[key]
        gsub(/\n/, " ", val)
        line = substr(line, 1, RSTART - 1) val substr(line, RSTART + RLENGTH)
      }
      print line
    }
  }
' "$TEMPLATE" "$BLOCKS" > "$TMP"

mv "$TMP" "$OUT"
trap - EXIT
echo "assemble-doc: wrote $OUT"
