#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2024 Julien Moutinho (adh14) <julm+rezine@sourcephile.fr>
# SPDX-License-Identifier: AGPL-3.0-or-later
# shellcheck disable=SC2034
# shellcheck disable=SC2046
# shellcheck disable=SC2086
# shellcheck disable=SC2119
# shellcheck disable=SC2154
rfcOrga=Rézine
rfcRepo=rezine-rfcs
rfcList=rfcs
rfcDomain=rezine.org
# FIXME: host it on rezine.org?
rfcGitweb="https://git.sourcephile.fr/julm/$rfcRepo.git"

removeAtExit=()
exitHook () {
  rm -rf "${removeAtExit[@]}"
}
trap exitHook EXIT

rfcDirMetadata () {
  rfcRoot=$(realpath --relative-to . "${0%/*}"/..)
  rfcDir=$(realpath --relative-to "$rfcRoot" "$rfcDir")
  rfcBranch=$(realpath --relative-to "$rfcRoot"/rfcs "$rfcDir")
  rfcYearAdvocacy=$(git log -1 --pretty=%cd --date=format:%Y "$rfcDir/advocacy.md")
  rfcDateAdvocacy=$(git log -1 --pretty=%cd --date=short "$rfcDir/advocacy.md")
  rfcDateCriticisms=$(git log -1 --pretty=%cd --date=short "$rfcDir/criticisms.yaml")
}

rfcRevision () {
  local advocacyLatestCommit criticismsLatestCommit
  local rfcTagAdvocacyOld rfcTagCriticismsOld
  rfcLatestCommit=$(git rev-list --max-count=1 HEAD -- "$rfcDir" :'!*.html' :'!*.csl.json')
  advocacyLatestCommit=$(git rev-list --max-count=1 HEAD -- "$rfcDir/advocacy.html")
  criticismsLatestCommit=$(git rev-list --max-count=1 HEAD -- "$rfcDir/criticisms.html")
  if test "$advocacyLatestCommit" != "$rfcLatestCommit" ||
     test "$criticismsLatestCommit" != "$rfcLatestCommit"
  then
    advocacyLatestCommit=$rfcLatestCommit
    criticismsLatestCommit=$rfcLatestCommit
  fi
  rfcTagAdvocacyOld="$(git describe --tags "$advocacyLatestCommit")" || true
  rfcTagCriticismsOld="$(git describe --tags "$criticismsLatestCommit")" || true
  if test "${rfcTagAdvocacyOld#"${rfcBranch}v"}" != "$rfcTagAdvocacyOld"
  then IFS=psvc- read -r _ _num rfcRevAdvocacy _rfcRevCriticisms rfcRevWIP <<<"$rfcTagAdvocacyOld"
  else rfcRevAdvocacy=0; rfcTagAdvocacyOld=init
  fi
  if test "${rfcTagCriticismsOld#"${rfcBranch}v"}" != "$rfcTagCriticismsOld"
  then IFS=psvc- read -r _ _num _rfcRevAdvocacy rfcRevCriticisms rfcRevWIP <<<"$rfcTagCriticismsOld"
  else rfcRevCriticisms=0; rfcTagCriticismsOld=init
  fi
  rfcBranchRevision="${rfcBranch}v${rfcRevAdvocacy}"
  rfcTag="${rfcBranchRevision}c${rfcRevCriticisms}${rfcRevWIP:+-$rfcRevWIP}"
  echo rfcRevCriticisms="${rfcRevCriticisms}"
  echo rfcWIP="${rfcRevWIP}"
  if test -z "$rfcRevWIP"
  then rfcTagOrMain=$rfcTag
  else rfcTagOrMain=main
  fi
}

rfcCitation () {
  mkdir -p "$rfcRoot/rfcs/$rfcBranch/citation"
  pandoc >"$rfcRoot/rfcs/$rfcBranch/citation/v${rfcRevAdvocacy}.csl.json" \
    --wrap none \
    $(rfcMetadata) \
    --template "$rfcRoot/styles/rfc.csl.json" \
    "$sourceFile"
}

rfcSource () {
  pandoc \
    --wrap none \
    $(rfcMetadata) \
    --template "$rfcRoot"/styles/rfc.metadata.yaml \
    "$rfcDir"/advocacy.md
  if test ! "${rfcNoAdvocacy:+set}"; then
    printf '\n'
    cat "$rfcRoot/styles/rfc.information.md"
    printf '\n'
    cat "$rfcDir"/advocacy.md
    printf '\n'
  fi
  if test ! "${rfcNoThanks:+set}"; then
    pandoc \
      --wrap none \
      $(rfcMetadata) \
      --template "$rfcRoot"/styles/rfc.thanks.md \
      "$rfcDir"/thanks.yaml
    printf '\n'
  fi
  if test ! "${rfcNoHistory:+set}"; then
    pandoc \
      --wrap none \
      $(rfcMetadata) \
      --template "$rfcRoot"/styles/rfc.history.md \
      "$rfcDir"/history.yaml
    printf '\n'
  fi
  if test ! "${rfcNoCriticisms:+set}"; then
    pandoc \
      --wrap none \
      $(rfcMetadata) \
      --template "$rfcRoot"/styles/rfc.criticisms.md \
      "$rfcDir"/criticisms.yaml
    printf '\n'
  fi
  cat "$rfcRoot"/styles/rfc.references.md
}

rfcMetadata () {
  printf ' --metadata %s' \
    rfcBranch="$rfcBranch" \
    rfcDateAdvocacy="$rfcDateAdvocacy" \
    rfcDateCriticisms="$rfcDateCriticisms" \
    rfcDir="$rfcDir" \
    rfcDomain="$rfcDomain" \
    rfcGitweb="$rfcGitweb" \
    rfcList="$rfcList" \
    rfcOrga="$rfcOrga" \
    rfcRepo="$rfcRepo" \
    rfcBranchRevision="$rfcBranchRevision" \
    rfcRevAdvocacy="$rfcRevAdvocacy" \
    rfcRevisionAdvocacy="v$rfcRevAdvocacy" \
    rfcRevisionCriticisms="c$rfcRevCriticisms" \
    rfcTag="$rfcTag" \
    rfcTagOrMain="$rfcTagOrMain" \
    rfcYearAdvocacy="$rfcYearAdvocacy"
}

rfcTemplate () {
  local sourceFile metaFile
  sourceFile=$(mktemp --suffix ".md")
  metaFile=$(mktemp --suffix ".md")
  removeAtExit+=("$sourceFile" "$metaFile")
  rfcSource >"$sourceFile"
  if test ! "${rfcNoAdvocacy:+set}" && test ! "${rfcNoCriticisms:+set}"; then
    rfcCitation
  fi
  pandoc \
    --wrap none \
    $(rfcMetadata) \
    --template "$sourceFile" \
    "$sourceFile" | "$@"
}

rfcPlain () {
  rfcTemplate \
  pandoc --from markdown+emoji --to plain \
    --citeproc \
    --csl "$rfcRoot"/styles/rfc.csl \
    $(printf " --bibliography %s" "$rfcRoot"/refs/*.json \
                                  "$rfcRoot"/rfcs/*/citation/*.csl.json) \
    --lua-filter "$rfcRoot"/styles/rfc.lua \
    --variable lang=fr-FR \
    "$@"
}

rfcMarkdown () {
  rfcTemplate \
  pandoc --from markdown+emoji --to markdown+emoji \
    --table-of-contents \
    --toc-depth 6 \
    --number-sections \
    --citeproc \
    --csl "$rfcRoot"/styles/rfc.csl \
    $(printf " --bibliography %s" "$rfcRoot"/refs/*.json \
                                  "$rfcRoot"/rfcs/*/citation/*.csl.json) \
    --lua-filter "$rfcRoot"/styles/rfc.lua \
    --variable lang=fr-FR \
    "$@"
}

rfcHTML () {
  rfcTemplate \
  pandoc --from markdown+emoji --to html5 \
    --standalone \
    --embed-resources \
    --include-in-header "$rfcRoot"/styles/rfc.header.html \
    --table-of-contents \
    --toc-depth 6 \
    --number-sections \
    --citeproc \
    --csl "$rfcRoot"/styles/rfc.csl \
    $(printf " --bibliography %s" "$rfcRoot"/refs/*.json \
                                  "$rfcRoot"/rfcs/*/citation/*.csl.json) \
    --lua-filter "$rfcRoot"/styles/rfc.lua \
    --variable lang=fr-FR \
    "$@"
}

rfcPDF () {
  rfcTemplate \
  pandoc --from markdown+emoji --to pdf \
    --pdf-engine lualatex \
    --include-in-header "$rfcRoot"/styles/rfc.header.tex \
    --standalone \
    --embed-resources \
    --table-of-contents \
    --toc-depth 6 \
    --number-sections \
    --citeproc \
    --csl "$rfcRoot"/styles/rfc.csl \
    $(printf " --bibliography %s" "$rfcRoot"/refs/*.json) \
    --lua-filter "$rfcRoot"/styles/rfc.lua \
    --variable colorlinks=true \
    --variable lang=fr-FR \
    --variable links-as-notes=true \
    "$@"
}

rfcTag () {
  git reset
  git diff --exit-code -- "$rfcDir" :'!*.html' :'!*.csl.json' ||
  {
    cat >&2 <<<"ERROR: you have changes to commit"
    exit 1
  }

  : "Check if \$rfcRevAdvocacy must be increased."
  rfcNoCriticisms="set" \
  rfcNoThanks="set" \
  rfcNoHistory="set" \
  rfcHTML -o "$rfcDir"/advocacy.html
  git add "$rfcDir"/advocacy.html
  rfcRevAdvocacyIncrement=0
  if ! git diff --cached --quiet "$rfcDir"/advocacy.html; then
    rfcRevAdvocacyIncrement=1
    # Note that $rfcRevCriticisms is not reset:
    # criticisms have their own independant revisions
    # because, in practice, criticisms to an old $rfcRevAdvocacy
    # can be received and added after a new $rfcRevAdvocacy has been tagged.
  fi

  : "Check if \$rfcRevCriticisms must be increased."
  rfcRevAdvocacy="1" \
  rfcNoAdvocacy="set" \
  rfcNoThanks="set" \
  rfcNoHistory="set" \
  rfcHTML -o "$rfcDir"/criticisms.html
  git add "$rfcDir"/criticisms.html
  rfcRevCriticismsIncrement=0
  if ! git diff --cached --quiet "$rfcDir"/criticisms.html; then
    rfcRevCriticismsIncrement=1
  fi

  if test "$rfcRevAdvocacyIncrement" -gt 0 ||
     test "$rfcRevCriticismsIncrement" -gt 0
  then
    rfcRevAdvocacy=$((rfcRevAdvocacy + rfcRevAdvocacyIncrement))
    rfcRevCriticisms=$((rfcRevCriticisms + rfcRevCriticismsIncrement))
    rfcBranchRevision="${rfcBranch}v$rfcRevAdvocacy"
    rfcTag="${rfcBranchRevision}c$rfcRevCriticisms"
    rfcNoCriticisms="set" \
    rfcNoThanks="set" \
    rfcNoHistory="set" \
    rfcHTML -o "$rfcDir"/advocacy.html
    rfcRevAdvocacy="1" \
    rfcNoAdvocacy="set" \
    rfcNoThanks="set" \
    rfcNoHistory="set" \
    rfcHTML -o "$rfcDir"/criticisms.html
    rfcHTML -o "$rfcDir"/index.html
    #rfcPDF -o "$rfcDir/${rfcRepo}-${rfcBranch}".pdf
    git add "$rfcDir"/{advocacy,criticisms,index}.html
    git add "$rfcDir/citation/v${rfcRevAdvocacy}.csl.json"
    #git add "$rfcDir/${rfcRepo}-${rfcBranch}".pdf
    git diff --cached --quiet ||
    git commit -m "$rfcBranch: v$rfcRevAdvocacy c$rfcRevCriticisms"
    git tag --force --sign --message "${rfcOrga} RFC${rfcTag}" "$rfcTag"
  fi
}