#!/usr/bin/env bash

pushd "$DOTFILES/sh/templates/" &>/dev/null || exit 1

mkdir -p "$DOTFILES/cron/generated/"
for job in report-summary annex run-local-backup copy-box-backups repo-update mbox-archive mr-remotes-backup; do
  sed "s/__JOB__/$job/" cronjob-with-email.sh > "$HOME/dev/libre/dotfiles/cron/generated/job-$job.sh"
  chmod +x "$HOME/dev/libre/dotfiles/cron/$job.sh"
  chmod +x "$HOME/dev/libre/dotfiles/cron/generated/job-$job.sh"
done

mkdir -p "$HOME/annex/bin/cron/generated/"
# shellcheck disable=2043
for job in pacheco; do
  prefix="$HOME/annex/bin/cron"
  sed "s/job-__JOB__/job-$job/" cronjob-with-email.sh | sed "s|.*__JOB__.*|$prefix/$job.sh|" > "$HOME/annex/bin/cron/generated/job-$job.sh"
  chmod +x "$HOME/annex/bin/cron/$job.sh"
  chmod +x "$HOME/annex/bin/cron/generated/job-$job.sh"
done

cp ~/dev/libre/package-repository/EuAndreh.key ~/dev/libre/website/public-key.txt

mkdir -p ~/archive/torrent/
find ~/dev/libre/website/ -type f -name '*.torrent' -exec cp {} ~/archive/torrent/ \;

normalize_name() {
  if [ -n "$RENAME_TO" ]; then
    echo "$RENAME_TO"
  elif [[ "$1" = ..* ]]; then
    echo "${1:1}"
  else
    echo "$1"
  fi
}

cp_all() {
  for f in "$@"; do
    OUT="$PPREFIX/$(normalize_name "$f")"
    mkdir -p "$(dirname "$OUT")"
    cp "$f" "$OUT"
  done
}

cp_if_not() {
  for f in "$@"; do
    OUT="$PPREFIX/$(normalize_name "$f")"
    if [ ! -f "$OUT" ]; then
      cp_all "$f"
    fi
  done
}

cp_if() {
  for f in "$@"; do
    OUT="$PPREFIX/$(normalize_name "$f")"
    if [ -f "$OUT" ]; then
      rm -f "$OUT"
      cp_all "$f"
    fi
  done
}

sed_all() {
  for f in "$@"; do
    OUT="$PPREFIX/$(normalize_name "$f")"
    mkdir -p "$(dirname "$OUT")"

    if [ -n "$ENABLE_CI" ]; then
      ENABLE_CI_SCRIPT='s/__ENABLE_CI__ //g'
      if [ -n "$ENABLE_AUTOTOOLS" ]; then
        TLD_SCRIPT=''
      else
        TLD_SCRIPT="$DEFAULT_TLD_SCRIPT"
      fi
    else
      ENABLE_CI_SCRIPT='/__ENABLE_CI__ /d'
      TLD_SCRIPT="$DEFAULT_TLD_SCRIPT"
    fi

    sed "$f"                                    \
        -e "s/__PROJECT_UC__/$PROJECT_UC/g"     \
        -e "s/__PROJECT__/$PROJECT/g"           \
        -e "s/__MAILING_LIST__/$MAILING_LIST/g" \
        -e "$TLD_SCRIPT"                        \
        -e "$ENABLE_CI_SCRIPT"                  \
        -e "$ENABLE_AUTOTOOLS_SCRIPT"           \
        > "$OUT"

    if [ -n "$EXECUTABLE" ]; then
      chmod +x "$OUT"
    fi
  done
}

sed_if_not() {
  for f in "$@"; do
    OUT="$PPREFIX/$(normalize_name "$f")"
    if [ ! -f "$OUT" ]; then
      sed_all "$f"
    fi
  done
}

ln_env() {
  export PROJECT="$1"
  export PPREFIX="${PPREFIX_FOR_PROJECT[$PROJECT]:-$HOME/dev/libre/$PROJECT}"
  export MAILING_LIST="${ML_FOR_PROJECT[$PROJECT]:-public-inbox}"
  export PROJECT_UC="${PROJECT_NAMES[$PROJECT]:-$PROJECT}"

  if [ -f "$PPREFIX/Makefile" ] && [ "$PROJECT" != website ]; then
    export ENABLE_CI=1
  else
    export ENABLE_CI=
  fi

  if [ -n "${GUILE_PROJECTS[$PROJECT]}" ]; then
    ENABLE_GUILE=1
  else
    ENABLE_GUILE=
  fi
}

ln_init() {
  if ! grep -q "$PROJECT" ~/annex/bin/misc/git/mrconfig.ini; then
    red "$(printf '%s missing from mrconfig.ini!\n' "$PROJECT")\n"
  fi

  if [ ! -d "$PPREFIX" ]; then
    git init "$PPREFIX"
  fi
  cp_if_not description long-description ..gitignore
}

ln_build_aux() {
  cp_all aux/assert-shellcheck.sh         \
         aux/tld.txt                      \
         aux/workflow/assert-todos.sh     \
         aux/workflow/assert-changelog.sh \
         aux/workflow/assert-readme.sh    \
         aux/workflow/TODOs.sh            \
         aux/workflow/style.css           \
         aux/workflow/favicon.html        \
         aux/workflow/preamble.md         \
         aux/workflow/commonmark.sh       \
         aux/workflow/dist.sh             \
         aux/workflow/sign-tarballs.sh    \
         aux/workflow/public.sh           \
         aux/workflow/favicon.svg         \
         aux/workflow/favicon.png

  cp_if_not TODOs.md

  cp_if \
		aux/assert-perltidy.sh
  	aux/tests-lib.sh
}

ln_agpl() {
  cp_all COPYING
}

ln_guix_files() {
  cp_all aux/guix/with-container.sh \
         aux/assert-shellcheck.sh
  cp_if_not aux/guix/manifest.scm \
            aux/guix/pinned-channels.scm
}

ln_ci() {
  rm -f "$PPREFIX/.git/hooks/pre-push"
  if [ -n "$ENABLE_CI" ]; then
    EXECUTABLE=1 sed_all aux/ci/git-pre-push.sh
    cp_all aux/assert-shellcheck.sh \
           aux/tld.txt              \
           aux/ci/ci-build.sh       \
           aux/ci/report.sh         \
           aux/ci/git-post-receive.sh
    ln -s "$PPREFIX/aux/ci/git-pre-push.sh" "$PPREFIX/.git/hooks/pre-push"
  else
    EXECUTABLE=1 sed_all ..git/hooks/pre-push
  fi
}

ln_simple_makefile() {
  sed_if_not Makefile
}

enforce_uniform_manpages() {
  if [ -d "$PPREFIX/doc" ]; then
    for f in $(find "$PPREFIX/doc" -type f -name '*.[0-9]'); do
      if grep -Eq '^\.SH AUTHORS$' "$f"; then
        EXPECTED="$(cat <<EOF
.
.
.SH AUTHORS
.P
EuAndreh
.MT eu@euandre.org
.ME
and contributors.
.
.
.SH BUGS
Report bugs to:
.MT ~euandreh/$MAILING_LIST@lists.sr.ht
.ME
.br
Browse bugs at:
.UR https://$PROJECT.euandreh.xyz/TODOs.html
.UE
.br
Home page:
.UR https://$PROJECT.euandreh.xyz
.UE
.br
Discussions:
.UR https://lists.sr.ht/~euandreh/$MAILING_LIST?search=[$PROJECT]
.UE
EOF
)"
        if ! diff <(tail -n "$(wc -l <<< "$EXPECTED")" "$f") <(echo "$EXPECTED"); then
          cat "$f" <(echo "$EXPECTED") | sponge "$f"
          echo "$f"
        fi
      fi
    done
  fi
}

ln_makefile_only_project() {
  ln_env "$1"
  ln_init
  ln_agpl
  ln_ci
  ln_simple_makefile
  enforce_uniform_manpages
}

ln_makefile_only_guix_project() {
  ln_makefile_only_project "$1"
  ln_guix_files
  ln_build_aux
}

ln_bare_project() {
  ln_env "$1"
  ln_agpl
  ln_ci
}

ln_description_foreign_project() {
  ln_env "$1"
  # Foreign projects may have Makefiles and alike, and I don't want
  # to have CI files copied to the repository
  ENABLE_CI=
  ln_ci
}

declare -A PROJECT_NAMES=(
  [servers]=Servers
  [cement]=Cement
  [songbooks]=Songbooks
  [mediator]=Mediator
  [byopds]=BYOPDS
  [pires]=Pires
)

declare -A ML_FOR_PROJECT=(
  [cement]=byopds
  [byopds]=byopds
  [guile-pds]=byopds
  [x-bindgen]=mediator
  [mediator]=mediator
  [libedn]=mediator
  [konformigado]=mediator
  [gluilo]=mediator
  [fallible]=mediator
  [eq]=mediator
  [xq]=mediator
  [songbooks]=songbooks
  [pires]=pires
)

declare -A PPREFIX_FOR_PROJECT=(
  [guix]="$HOME/dev/guix/guix"
)

declare -A GUILE_PROJECTS=(
  [guile-quickcheck]=1
  [guile-pds]=1
  [songbooks]=1
)

ln_all() {
  LN_FN="$1"
  shift
  for f in "$@"; do
    "$LN_FN" "$f"
  done
}

ln_all ln_description_foreign_project     guix               \
                                          apollo-server-demo \
                                          ml-archives        \
                                          3rd-party-archives
ln_all ln_makefile_only_project           boneco          \
                                          pdfs-da-d-maria
ln_all ln_makefile_only_guix_project      servers            \
                                          pires              \
                                          remembering        \
                                          website            \
                                          dotfiles           \
                                          gluilo             \
                                          konformigado       \
                                          libedn             \
                                          eq                 \
                                          xq                 \
                                          fallible           \
                                          standardify        \
                                          autoqemu           \
                                          yoctoauth          \
                                          mediator           \
                                          songbooks          \
                                          cement             \
                                          guile-quickcheck   \
                                          guile-pds          \
                                          byopds             \
                                          discussions-site   \
                                          package-repository \
                                          paku               \
                                          std-tools          \
                                          gistatic           \
                                          listatic           \
                                          cl-fun             \
                                          git-permalink      \
                                          lisp-cli           \
                                          caju               \
                                          libpds             \
                                          libmustache        \
                                          libjson            \
                                          yoctoparsec        \
                                          sys-langs          \
                                          r2h                \
                                          book-queue         \
                                          makecheck
ln_all ln_bare_project                    brinquedoteca         \
                                          casa-do-caminho       \
                                          music                 \
                                          swift2nix             \
                                          swift2nix-demo        \
                                          cargo2nix             \
                                          cargo2nix-demo

popd &> /dev/null || exit 1
