#!/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"

NAME="$1"
REMOTE_ARG="$2"
V_ARG="$3"

# Help message
if [ -z "$NAME" ] || [ -z "$REMOTE_ARG" ] || [ -n "$HELP" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
  say "
  USAGE:
    $(g "${BASH_SOURCE##*/}")  $(c name)  $(c remote)  [$(c version)]

  DESCRIPTION:
    $(g "${BASH_SOURCE##*/}") uploads $(c version) of
    component $(c name) to $(c remote) via rsync.

    The latest local version will be used by default if $(c version) is omitted.
"
  exit 1
fi

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

DIR="/srv/$NAME"
REMOTE_NAME="$(echo "$REMOTE_ARG" | awk -F '://' '{print $NF}')"

say "Syncing local and remote versions"
run "$ROOT/bin/tl-comp-sync" "$NAME"
run "$ROOT/bin/tl-comp-sync" "$NAME" "$REMOTE_ARG"

V_LOCAL="$("$ROOT/bin/tl-comp-latest" "$NAME")"
V_TARGET="${V_ARG:-"$V_LOCAL"}"

# Desktop needs MAJOR and MINOR versions too
VERSIONS=("$V_TARGET")
if [[ "$NAME" =~ desktop ]]; then
  PATCH="$V_TARGET"
  MINOR="$(echo "$PATCH" | cut -d. -f-2).0"
  MAJOR="$(echo "$PATCH" | cut -d. -f-1).0.0"
  VERSIONS=("$MAJOR" "$MINOR" "$PATCH")
fi

REMOTE_DIR="/srv/$NAME"

for ver in "${VERSIONS[@]}"; do
  say "Pushing $(c "$ver") to $(c "$REMOTE_NAME")"
  
  # Push all files related to this version
  # We use -avzP which includes --partial and --progress for resumability.
  # Rsync will autonomously decide if it needs to transfer data.
  success=true
  for src in "$DIR/v$ver"*; do
    [ -e "$src" ] || continue
    run rsync --cc=xxh3 -avzP "$src" "$REMOTE_NAME:$REMOTE_DIR/"
    if [ $? -ne 0 ]; then
      success=false
      break
    fi
  done

  if ! $success; then
    err "Push failed for $(c "$ver")"
    exit 1
  fi
done

# Final sync to refresh our records properly from the source of truth
say "Refreshing remote records..."
run "$ROOT/bin/tl-comp-sync" "$NAME" "$REMOTE_ARG"

say "All components up-to-date."
