#!/usr/bin/env bash
#
# warpbox: command line uploader for Warpbox
#
# Set the server once, then upload anything:
#   export WARPBOX_HOST=https://your.warpbox.host
#   warpbox ./report.pdf
#
# Install:
#   curl -fsSL "$WARPBOX_HOST/static/api/warpbox.sh" -o ~/.local/bin/warpbox
#   chmod +x ~/.local/bin/warpbox
#   # make sure ~/.local/bin is on your PATH
#
set -eo pipefail

WARPBOX_HOST="${WARPBOX_HOST:-}"
AUTH="${WARPBOX_TOKEN:-}"
PASSWORD=""
EXPIRY=""
MAX_DOWNLOADS=""
OBFUSCATE=""
AS_JSON=0
FILES=()

usage() {
  cat <<'EOF'
warpbox: upload files to Warpbox from the terminal

USAGE:
  warpbox [options] <file> [file ...]

OPTIONS:
  -p, --password <pw>       Require a password to view/download the box
  -e, --expiry <dur>        Lifetime before expiry: 30m, 6h, 2d, 1w (or bare minutes)
  -n, --max-downloads <n>   Expire after N downloads
  -o, --obfuscate           Hide file names/counts until unlocked (needs --password)
      --host <url>          Warpbox server to upload to (or set WARPBOX_HOST)
      --auth <token>        API token (prefer the WARPBOX_TOKEN env var, see AUTH)
      --auth-file <path>    Read the API token from a file (safer than --auth)
      --json                Print the full JSON response instead of just the URL
  -h, --help                Show this help

AUTH:
  Uploads are anonymous unless a token is supplied. The most secure option is the
  WARPBOX_TOKEN environment variable, so the token never lands in your shell
  history or the process list:

    export WARPBOX_TOKEN=wbx_your_token
    warpbox ./photo.png

  Create a token under Account, Access tokens. Avoid --auth on shared machines.

EXAMPLES:
  warpbox ./report.pdf
  warpbox --password 123 --expiry 2d ./first_file.zip ./whatever.png ./all_*_photos.jpg
  warpbox --max-downloads 5 --json ./build.zip
EOF
}

expiry_to_minutes() {
  local v="$1" num unit
  num="${v%%[mhdw]*}"
  unit="${v##*[0-9]}"
  case "$unit" in
    h) echo $(( num * 60 )) ;;
    d) echo $(( num * 1440 )) ;;
    w) echo $(( num * 10080 )) ;;
    m|"") echo "$num" ;;
    *) echo "$num" ;;
  esac
}

while [ $# -gt 0 ]; do
  case "$1" in
    -p|--password) PASSWORD="$2"; shift 2 ;;
    -e|--expiry) EXPIRY="$2"; shift 2 ;;
    -n|--max-downloads) MAX_DOWNLOADS="$2"; shift 2 ;;
    -o|--obfuscate) OBFUSCATE="on"; shift ;;
    --host) WARPBOX_HOST="$2"; shift 2 ;;
    --auth) AUTH="$2"; shift 2 ;;
    --auth-file) AUTH="$(cat "$2")"; shift 2 ;;
    --json) AS_JSON=1; shift ;;
    -h|--help) usage; exit 0 ;;
    --) shift; while [ $# -gt 0 ]; do FILES+=("$1"); shift; done ;;
    -*) echo "warpbox: unknown option $1" >&2; exit 2 ;;
    *) FILES+=("$1"); shift ;;
  esac
done

if [ -z "$WARPBOX_HOST" ]; then
  echo "warpbox: no server set. Use --host <url> or export WARPBOX_HOST=<url>" >&2
  exit 2
fi

if [ ${#FILES[@]} -eq 0 ]; then
  echo "warpbox: no files given" >&2
  echo >&2
  usage >&2
  exit 2
fi

CURL_ARGS=()
for f in "${FILES[@]}"; do
  if [ ! -f "$f" ]; then
    echo "warpbox: not a file: $f" >&2
    exit 2
  fi
  CURL_ARGS+=(-F "file=@${f}")
done

[ -n "$PASSWORD" ] && CURL_ARGS+=(-F "password=${PASSWORD}")
[ -n "$EXPIRY" ] && CURL_ARGS+=(-F "expires_minutes=$(expiry_to_minutes "$EXPIRY")")
[ -n "$MAX_DOWNLOADS" ] && CURL_ARGS+=(-F "max_downloads=${MAX_DOWNLOADS}")
[ -n "$OBFUSCATE" ] && CURL_ARGS+=(-F "obfuscate_metadata=on")

HEADERS=()
[ -n "$AUTH" ] && HEADERS+=(-H "Authorization: Bearer ${AUTH}")
[ "$AS_JSON" -eq 1 ] && HEADERS+=(-H "Accept: application/json")

exec curl -fS "${HEADERS[@]}" "${CURL_ARGS[@]}" "${WARPBOX_HOST%/}/api/v1/upload"
