#!/usr/bin/env bash
# vim:et:ts=2:sts=2:sw=2

# Get absolute repository root (especially when symlinked)
ROOT="$(realpath "$(dirname "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")")")"

# Load accompanying bash library
source "$ROOT/lib/lib.bash"

SUBJECT="${1:-all}" # Name of curriculum subject to download (or "all")
REMOTE="$2"         # Http or Rsync remote
VERSION_ARG="$3"    # Optional version

CURRICULUM_SUBJECTS=(docs sheets raster websites vector shell)

if [[ -z "$REMOTE" || "${1:-}" =~ ^(-h|--help)$ || -n "$HELP" ]]; then
  say "
  USAGE:
    $(g "${BASH_SOURCE##*/}")  [$(c subject)]  $(c remote)  [$(c version)]

  DESCRIPTION:
    Downloads a curriculum subject (or all subjects) from a remote.
    If $(c subject) is omitted or 'all', all standard subjects will be downloaded.
    If version is omitted, the latest remote version is used.

  EXAMPLES:
    $(g "${BASH_SOURCE##*/}")  $(c docs)    $(c http://bastion.techlitafrica.org)
    $(g "${BASH_SOURCE##*/}")  $(c raster)  $(c server.local) $(c 1.0.0)
    $(g "${BASH_SOURCE##*/}")  $(c all)     $(c server.local) (default)
  "
  exit 1
fi

# Exit now if run as root user
assert-is-user

if [[ "$REMOTE" =~ ^https?:// ]]; then
  CLIENT="${DOWNLOAD_CLIENT:-aria2}"
else
  CLIENT="${DOWNLOAD_CLIENT:-rsync}"
fi
REMOTE_NAME="${REMOTE#*://}"

# Track results for summary
SUCCESS_LIST=()
FAILED_LIST=()

download() {
  local sname="$1" ver="v$2" dir="$3"
  local base="$REMOTE/curriculum/$sname/$ver"

  if [[ "$CLIENT" == "aria2" ]]; then
    run aria2c --continue --allow-overwrite -d "$dir" -P -Z "$base.tar.gz" "$base.sha256"
  else
    run rsync --cc=xxh3 -avzP --partial --append-verify \
      "$REMOTE_NAME:/srv/curriculum/$sname/$ver".* "$dir"
  fi
  return # propagate exit code from run
}

pull_subject() {
  local sname="$1"
  local rname="$2"
  local varg="$3"
  local silent="${4:-false}"

  local dir="/srv/curriculum/$sname"
  mkdir -p "$dir/.v"

  if ! "$silent"; then say "Syncing versions for subject '$(c "$sname")'"; fi

  local v_local="$("$ROOT"/bin/tl-comp-latest curriculum "$sname")"
  local v_remote="$("$ROOT"/bin/tl-comp-latest curriculum "$sname" "$rname")"
  local v_target="${varg:-$v_remote}"

  if [[ -z "$v_target" ]]; then
    err "No target version found for subject $(c "$sname")."
    return 1
  fi

  if ! "$silent"; then
    say "Local: $(c "$v_local") | Remote: $(c "$v_remote") | Target: $(c "$v_target")"
  fi

  if download "$sname" "$v_target" "$dir"; then
    echo "$v_target" >"$dir/.v/local"
    if ! "$silent"; then
      say "Subject $(c "$sname") version $(c "$v_target") downloaded."
    fi
    return 0
  else
    err "Failed to pull subject $(c "$sname") version $(c "$v_target")"
    return 1
  fi
}

if [ "$SUBJECT" = "all" ]; then
  say "Pulling all standard curriculum subjects from $(c "$REMOTE")"
  for s in "${CURRICULUM_SUBJECTS[@]}"; do
    if pull_subject "$s" "$REMOTE" "$VERSION_ARG" true; then
      SUCCESS_LIST+=("$s")
    else
      FAILED_LIST+=("$s")
    fi
  done
else
  if pull_subject "$SUBJECT" "$REMOTE" "$VERSION_ARG"; then
    SUCCESS_LIST+=("$SUBJECT")
  else
    FAILED_LIST+=("$SUBJECT")
  fi
fi

# Final Summary
say ""
if [ ${#SUCCESS_LIST[@]} -gt 0 ]; then
  say "$(g SUCCESS:) Pulled subjects: ${SUCCESS_LIST[*]}"
fi
if [ ${#FAILED_LIST[@]} -gt 0 ]; then
  say "$(r FAILED:)  Failed subjects:  ${FAILED_LIST[*]}"
fi

say "All requested curriculum pulls complete."
exit 0
