#!/usr/bin/env zsh
emulate -L zsh
setopt pipefail

program="${0:t}"

remote="${MUSICBOX_REMOTE:-NytegearMusic}"
inbox="${MUSICBOX_INBOX:-/music/inbox/Unchecked}"
delete_source=1

usage() {
  cat >&2 <<EOF
usage:
  $program [options] /path/to/folder

Options:
  --keep-source          Keep the source folder after verified transfer.
  --delete-source        Delete the source folder after verified transfer. Default.
  --remote HOST          SSH host alias/name. Default: $remote
  --inbox PATH           Remote inbox path. Default: $inbox
  -h, --help             Show this help.

Environment:
  MUSICBOX_REMOTE        Default remote host.
  MUSICBOX_INBOX         Default remote inbox path.
  MUSICBOX_RSYNC         Explicit rsync binary to use.
EOF
}

die() {
  print -u2 "$program: $*"
  exit 1
}

have_cmd() {
  command -v "$1" >/dev/null 2>&1
}

rsync_supports() {
  local opt="$1"
  "$rsync_bin" --help 2>/dev/null | grep -q -- "$opt"
}

typeset -a positional

while (( $# )); do
  case "$1" in
    --keep-source)
      delete_source=0
      shift
      ;;
    --delete-source)
      delete_source=1
      shift
      ;;
    --remote)
      (( $# >= 2 )) || die "--remote requires a value"
      remote="$2"
      shift 2
      ;;
    --remote=*)
      remote="${1#--remote=}"
      shift
      ;;
    --inbox)
      (( $# >= 2 )) || die "--inbox requires a value"
      inbox="$2"
      shift 2
      ;;
    --inbox=*)
      inbox="${1#--inbox=}"
      shift
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    --)
      shift
      positional+=("$@")
      break
      ;;
    -*)
      die "unknown option: $1"
      ;;
    *)
      positional+=("$1")
      shift
      ;;
  esac
done

if (( ${#positional} != 1 )); then
  usage
  exit 2
fi

[[ -n "$remote" ]] || die "remote may not be empty"
[[ -n "$inbox" ]] || die "inbox may not be empty"

have_cmd ssh || die "ssh not found"
have_cmd base64 || die "base64 not found"
have_cmd grep || die "grep not found"

if [[ -n "${MUSICBOX_RSYNC:-}" ]]; then
  rsync_bin="$MUSICBOX_RSYNC"
else
  rsync_bin="$(command -v rsync 2>/dev/null || true)"
fi

[[ -n "$rsync_bin" && -x "$rsync_bin" ]] || die "rsync not found"

if "$rsync_bin" --version 2>&1 | grep -qi 'openrsync'; then
  die "OpenRsync detected at $rsync_bin. This script needs GNU rsync for --secluded-args and reliable remote path handling. Install GNU rsync and set MUSICBOX_RSYNC if needed."
fi

if ! "$rsync_bin" --help 2>/dev/null | grep -q -- '--secluded-args'; then
  die "rsync at $rsync_bin does not support --secluded-args; refusing because remote paths may contain spaces/special characters"
fi

src="${positional[1]:A}"

[[ "$src" != "/" ]] || die "refusing to upload /"
[[ -d "$src" ]] || die "source must be an existing folder: ${positional[1]}"

name="${src:t}"
[[ -n "$name" ]] || die "could not determine folder name from source: $src"

target="${inbox%/}/$name"
marker="$target/.musicbox-rsync-in-progress"

b64() {
  printf '%s' "$1" | base64 | tr -d '\n'
}

target_b64="$(b64 "$target")"
marker_b64="$(b64 "$marker")"

print "musicbox: source: $src"
print "musicbox: remote: $remote"
print "musicbox: target: $target"

ssh "$remote" "TARGET_B64='$target_b64' MARKER_B64='$marker_b64' sh -s" <<'EOF'
decode_b64() {
  printf '%s' "$1" | base64 -d 2>/dev/null || printf '%s' "$1" | base64 -D
}

target="$(decode_b64 "$TARGET_B64")"
marker="$(decode_b64 "$MARKER_B64")"

if [ -e "$target" ]; then
  if [ -f "$marker" ]; then
    echo "musicbox: resuming interrupted transfer: $target" >&2
    exit 0
  else
    echo "musicbox: destination already exists, refusing to overwrite: $target" >&2
    exit 17
  fi
fi

mkdir -p "$target" || exit 1
touch "$marker" || exit 1
EOF

prep_status=$?
if (( prep_status != 0 )); then
  exit "$prep_status"
fi

typeset -a transfer_opts
transfer_opts=(
  -a
  -h
  -v
  --partial
  --append-verify
  --secluded-args
)

if "$rsync_bin" --help 2>/dev/null | grep -q -- '--no-i-r'; then
  transfer_opts+=(--no-i-r)
fi

if "$rsync_bin" --help 2>/dev/null | grep -q -- '--info='; then
  transfer_opts+=(--info=progress2,stats2,name0)
else
  transfer_opts+=(--progress --stats)
fi

if "$rsync_bin" --help 2>/dev/null | grep -q -- '--outbuf='; then
  transfer_opts+=(--outbuf=L)
fi

print "musicbox: transferring..."

echo "$rsync_bin" "${transfer_opts[@]}" -- \
  "$src"/ \
  "$remote:$target"/

"$rsync_bin" "${transfer_opts[@]}" -- \
  "$src"/ \
  "$remote:$target"/

rsync_status=$?

if (( rsync_status != 0 )); then
  print -u2 "musicbox: transfer interrupted or failed. Re-run the same command to resume."
  print -u2 "musicbox: source was NOT deleted."
  exit "$rsync_status"
fi

print "musicbox: verifying destination..."

verify_output="$(
  "$rsync_bin" -a -h -n -c \
    --delete \
    --itemize-changes \
    --exclude='.musicbox-rsync-in-progress' \
    --secluded-args \
    -- \
    "$src"/ \
    "$remote:$target"/
)"

verify_status=$?

if (( verify_status != 0 )); then
  print -u2 "musicbox: verification failed. Source was NOT deleted."
  exit "$verify_status"
fi

if [[ -n "$verify_output" ]]; then
  print -u2 "musicbox: verification found differences. Source was NOT deleted."
  print -u2 "$verify_output"
  exit 1
fi

ssh "$remote" "MARKER_B64='$marker_b64' sh -s" <<'EOF'
decode_b64() {
  printf '%s' "$1" | base64 -d 2>/dev/null || printf '%s' "$1" | base64 -D
}

marker="$(decode_b64 "$MARKER_B64")"
rm -f -- "$marker"
EOF

cleanup_status=$?
if (( cleanup_status != 0 )); then
  print -u2 "musicbox: warning: transfer verified, but failed to remove remote marker: $marker"
  exit "$cleanup_status"
fi

print "musicbox: transfer verified."

if (( delete_source )); then
  print "musicbox: deleting source folder: $src"
  rm -rf -- "$src"
  print "musicbox: done."
else
  print "musicbox: source kept in place."
  print "musicbox: done."
fi
