#!/usr/bin/env bash

cd "$DOTFILES/sh/templates/" || exit 1

mkdir -p "$DOTFILES/cron/generated/"
for job in report-summary annex 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/$job-job.sh"
  chmod +x "$HOME/annex/bin/cron/$job.sh"
  chmod +x "$HOME/annex/bin/cron/generated/$job-job.sh"
done

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="$PREFIX/$(normalize_name "$f")"
    mkdir -p "$(dirname "$OUT")"
    cp "$f" "$OUT"
  done
}

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

envsubst_all() {
  for f in "$@"; do
    OUT="$PREFIX/$(normalize_name "$f")"
    mkdir -p "$(dirname "$OUT")"
    envsubst < "$f" > "$OUT"

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

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

sed_all() {
  for f in "$@"; do
    OUT="$PREFIX/$(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="$PREFIX/$(normalize_name "$f")"
    if [ ! -f "$OUT" ]; then
      sed_all "$f"
    fi
  done
}

ln_env() {
  export PROJECT="$1"
  export PREFIX="${PREFIX_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 "$PREFIX/Makefile.am" ]; then
    export ENABLE_AUTOTOOLS=1
  else
    export ENABLE_AUTOTOOLS=
  fi

  if [ -f "$PREFIX/Makefile" ] || [ -f "$PREFIX/Makefile.am" ]; then
    export ENABLE_CI=1
  else
    export ENABLE_CI=
  fi

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

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

  if [ -f "$PREFIX/guix/pinned-channels.scm" ] &&
       [ "$(wc -l < "$PREFIX/guix/pinned-channels.scm")" = 11 ]; then
    ENABLE_OVERWRITE_PINNED_CHANNELS=1
  else
    ENABLE_OVERWRITE_PINNED_CHANNELS=
  fi

  if [ -f "$PREFIX/README.md" ]; then
    ENABLE_README_SH=1
  else
    ENABLE_README_SH=
  fi

  if [ -f "$PREFIX/CHANGELOG.md" ]; then
    ENABLE_CHANGELOG_SH=1
  else
    ENABLE_CHANGELOG_SH=
  fi
}

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

  if [ ! -d "$PREFIX" ]; then
    git init "$PREFIX"
  fi
}

ln_autotools() {
  chmod +w "$PREFIX/INSTALL" 2> /dev/null ||:
  cp_all AUTHORS                                 \
         bootstrap                               \
         ChangeLog                               \
         aux/automake/dev-checks.am              \
         aux/automake/default-extra-dist.am      \
         aux/automake/html-files-from-sources.am \
         aux/m4/programmer-mode.m4

  # dev-cheks.am: test maintainer mode
  # https://www.gnu.org/software/automake/manual/html_node/maintainer_002dmode.html
  cp_if_not description

  # assumes:
  # - ln_workflow for .gitignore
  # - ln_git_notes_release for Makefile.am
  # - ln_guix_files for Makefile.am
  envsubst_if_not ..gitignore README.in
  sed_if_not configure.ac Makefile.am
}

ln_build_aux() {
  cp_all aux/assert-shellcheck.sh     \
         aux/workflow/assert-todos.sh \
         aux/workflow/TODOs.sh        \
         aux/workflow/style.css       \
         aux/workflow/preamble.md

  if [ "$ENABLE_README_SH" ]; then
    cp_all aux/workflow/README.sh
  fi

  if [ "$ENABLE_CHANGELOG_SH" ]; then
    cp_all aux/workflow/CHANGELOG.sh
  fi

  cp_if_not TODOs.md
}

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

  if [ -n "$ENABLE_OVERWRITE_PINNED_CHANNELS" ]; then
    cp_all aux/guix/pinned-channels.scm
  else
    cp_if_not aux/guix/pinned-channels.scm
  fi
}

ln_ci() {
  rm -f "$PREFIX/.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/ci/ci-build.sh       \
           aux/ci/git-post-receive.sh
    ln -s "$PREFIX/aux/ci/git-pre-push.sh" "$PREFIX/.git/hooks/pre-push"
  else
    EXECUTABLE=1 sed_all ..git/hooks/pre-push
  fi
}

ln_git_notes_release() {
  cp_all aux/automake/git-notes-release.am aux/automake/git-notes-release.sh
  cp_if_not NEWS
}

ln_dicts() {
  cp_if_not doc/dictionaries/international.txt doc/dictionaries/en.txt
}

ln_web_assets_file() {
  mkdir -p "$PREFIX/aux/"
  cp "aux/$1-build-web-assets.sh" "$PREFIX/aux/build-web-assets.sh"
}

ln_scribble() {
  ln_dicts
}

ln_antora() {
  ln_dicts
}

ln_base_autotools_guix_project() {
  ln_env "$1"
  ln_init

  ln_build_aux
  ln_guix_files
  ln_git_notes_release
  ln_autotools
  ln_generated_readme

  ln_agpl
  ln_ci

  ln_dicts

  if [ -n "$ENABLE_GUILE" ]; then
    cp_all aux/automake/guile.am aux/m4/guile.m4
  fi

  if [ -n "$ENABLE_RUST" ]; then
    cp_all aux/automake/rust.am
  fi
}

ln_texinfo_autotools_guix_project() {
  ln_base_autotools_guix_project "$1"
  RENAME_TO="doc/$PROJECT.texi" envsubst_if_not rename/empty-texinfo.texi
  ln_web_assets_file texinfo
  cp_all aux/docbook-xsl.tar.gz
}

ln_sphinx_autotools_guix_project() {
  ln_base_autotools_guix_project "$1"
  cp_all aux/assert-docs-spelling.sh doc/_templates/footer.html doc/favicon.ico
  envsubst_all doc/conf.py.in doc/_templates/layout.html
  envsubst_if_not doc/index.rst
  cp_if_not doc/i18n-pagenames.json doc/Makefile
}

ln_scribble_autotools_guix_project() {
  ln_base_autotools_guix_project "$1"
  ln_scribble
}

ln_antora_autotools_guix_project() {
  ln_base_autotools_guix_project "$1"
  ln_antora
}

ln_simple_makefile() {
  envsubst_if_not Makefile
}

ln_generated_readme() {
  if [ ! -f "$PREFIX/README" ]; then
    cat <(printf "%s\n\n" "$PROJECT_UC")                        \
        <(fold < "$PREFIX/description")                         \
        <(printf "\nSee: https://%s.euandreh.xyz\n" "$PROJECT") \
        > "$PREFIX/README"
  fi
}

ln_makefile_only_guix_project() {
  ln_env "$1"
  ln_agpl
  ln_build_aux
  ln_guix_files
  ln_ci
  ln_simple_makefile
}

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=(
  [vps]=VPS
  [cement]=Cement
  [parsecc]=ParsecC
  [songbooks]=Songbooks
  [mediator]=Mediator
  [byopds]=BYOPDS
  [pires]=Pires
)

declare -A ML_FOR_PROJECT=(
  [cement]=byopds
  [byopds]=byopds
  [guile-pds]=byopds
  [parsecc]=mediator
  [parseclj]=mediator
  [x-bindgen]=mediator
  [mediator]=mediator
  [libedn]=mediator
  [eq]=mediator
  [songbooks]=songbooks
  [guile-clap]=songbooks
  [pires]=pires
)

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

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

declare -A RUST_PROJECT=(
  [spalc]=1
  [libedn]=1
  [x-bindgen]=1
)

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

ln_all ln_texinfo_autotools_guix_project  guile-quickcheck guile-pds guile-clap cement songbooks
ln_all ln_sphinx_autotools_guix_project   libedn x-bindgen eq mediator
# ln_all ln_scribble_autotools_guix_project
ln_all ln_antora_autotools_guix_project   byopds spalc
ln_all ln_makefile_only_guix_project      vps pires remembering website
ln_all ln_description_foreign_project     guix parsecc
ln_all ln_bare_project                    parseclj              \
                                          boneco                \
                                          brinquedoteca         \
                                          casa-do-caminho       \
                                          dotfiles              \
                                          euandreh-guix-channel \
                                          music                 \
                                          pdfs-da-d-maria       \
                                          swift2nix             \
                                          swift2nix-demo        \
                                          cargo2nix             \
                                          cargo2nix-demo

cd - > /dev/null || exit 1
