#!/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="$2"
DIR="${COMP_DIR:-/srv}/$NAME"

if [ -z "$NAME" ] || [ -n "$HELP" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
  say "
  USAGE:
  $(g "${BASH_SOURCE##*/}")  $(c component) [$(c remote)] [$(c /comp/dir)]

  DESCRIPTION:
    $(g "${BASH_SOURCE##*/}") updates list of remote versions for $(c component)

    $(c remote) is the address of a computer to download versions from.
    It can start with $(g "ssh://") or $(g "http://") (default is $(g "ssh://") ).

    EXAMPLES:

      # Looking for desktop updates from the local server
        $(c "$") $(g "${BASH_SOURCE##*/}")  $(c desktop)  $(c server.local)
        # => Downloading from $(c ssh://server.local:/srv/desktop)...

      # Looking for curriculum updates on another computer
        $(c "$") $(g "${BASH_SOURCE##*/}")  $(c curriculum)  $(c ssh://tl-0123.local)
        # => Downloading from $(c ssh://tl-0123.local:/srv/curriculum)...

      # Looking for admin updates from the internet
        $(c "$") $(g "${BASH_SOURCE##*/}")  $(c admin)  $(c http://bastion.techlitafrica.org)
        # => Dowloading from $(c http://bastion.techlitafrica.org/desktop)...

    Versions are saved to $(c "/srv/<component>/.v/<remote>")

    If $(c remote) is omitted, only local versions will be synced

  COMPONENTS:"
  say "$(ls -w 40 -m /srv | sed -e "s;^;    ;")
  "

  exit 1
fi

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

if ! [ -d "$DIR" ]; then
  err "Component $c$NAME$r is not installed"
  err ""
  err "  ($c$DIR$r is missing)"
  exit 1
fi

mkdir -p "$DIR/.v"

[ "$NAME" = "snapshots" ] && type="d" || type="f"

run find "$DIR/" -maxdepth 1 -name "v*.*.*.*" -type "$type" \
  | grep -v "\.tmp" \
  | sed -e 's;.*/v;;' \
  | sed -e 's/\.tar\.gz$//' -e 's/\.iso$//' -e 's/\.sha256$//' \
  | sort -V | uniq \
    >"$DIR/.v/local" || true

if [ -n "$REMOTE" ]; then

  REMOTE_NAME="$(echo "$REMOTE" | awk -F '://' '{print $NF}')"

  # Strip user@ if present for rsync remotes
  PING_TARGET="$REMOTE_NAME"
  if echo "$REMOTE" | grep -qvE '^(http|https)://' && echo "$PING_TARGET" | grep -q '@'; then
    PING_TARGET=$(echo "$PING_TARGET" | cut -d'@' -f2)
  fi

  if ! ping -c 1 -W 1 "$PING_TARGET" >/dev/null 2>&1; then
    err "Remote $c$REMOTE_NAME$r is not reachable"
    exit 1
  fi

  if echo "$REMOTE" | grep -Eq '^(http|https)://'; then
    run curl -s "$REMOTE/$NAME/" \
      | grep -oP '(?<=href=")v[0-9]+(\.[0-9]+)*(-[-a-zA-Z0-9]+)*\.(tar\.gz|iso|sha256)' \
      | sed -e 's/^v//' -e 's/\.tar\.gz$//' -e 's/\.iso$//' -e 's/\.sha256$//' \
      | sort -V | uniq \
        >"$DIR/.v/$REMOTE_NAME" || true

  else
    run ssh "$REMOTE_NAME" find "/srv/$NAME/" -maxdepth 1 -name "v*.*.*.*" -type "$type" \
      | grep -v "\.tmp" \
      | sed -e 's;.*/v;;' \
      | sed -e 's/\.tar\.gz$//' -e 's/\.iso$//' -e 's/\.sha256$//' \
      | sort -V | uniq \
        >"$DIR/.v/$REMOTE_NAME" || true
  fi
fi

date -Iseconds >"$DIR/.v/.synced-at"
