#!/bin/bash
#set -x

# js9msg: send a command to JS9 using wget or curl
# node is not required, which makes the js9 app self-contained

# default variables
HELPER=${JS9_HELPER:-localhost}
ID=JS9
JS9WEBSITE="https://js9.si.edu:2718"
PORT=${JS9_HELPER_PORT:-2718}
TIMEOUT=600

usage(){
  XEQ=`basename $0`
  printf "$XEQ: send a command to JS9 (using wget or curl)\n\n"
  printf "  call:\n"
  printf "    %s [switches] [cmd] [arg1] [arg2] ... [argn]\n" $XEQ
  printf "\n"
  printf "  switches:\n"
  printf "    -d|--debug                 # output debugging info\n"
  printf "    -h|--helper|--host| [host] # helper host (def: $HELPER)\n"
  printf "    -i|--id [id]               # client id (def: $ID)\n"
  printf "    -m|--multi]                # send to multiple clients\n"
  printf "    --pageid [id]              # send to unique pageid\n"
  printf "    -t|--timeout               # connect timeout (def: $TIMEOUT)\n"
  printf "    -v|--verbose               # output debugging info\n"
  printf "    -W                         # connect to main JS9 web site\n"
  printf "\n  examples:\n"
  printf "    # load foo.fits, setting colormap and scale\n"
  printf "    %s Load foo.fits '{\"colormap\":\"heat\", \"scale\":\"log\"}'\n" $XEQ
  printf "    # get the colormap of the currently loaded image\n"
  printf "    %s GetColormap\n" $XEQ
  printf "    # set the colormap of the image loaded into %s\n" $JS9WEBSITE
  printf "    %s -W SetColormap viridis\n" $XEQ
  printf "\n"
}

error() {
  echo "ERROR: $1" 1>&2
  exit 1
}


# https://stackoverflow.com/questions/296536/how-to-urlencode-data-for-curl-command
rawurlencode() {
  local string="${1}"
  local strlen=${#string}
  local encoded=""
  local pos c o

  for (( pos=0 ; pos<strlen ; pos++ )); do
     c=${string:$pos:1}
     case "$c" in
        [-_.~a-zA-Z0-9] ) o="${c}" ;;
        * )               printf -v o '%%%02x' "'$c"
     esac
     encoded+="${o}"
  done
  echo "${encoded}"    # You can either set a return variable (FASTER) 
  REPLY="${encoded}"   #+or echo the result (EASIER)... or both... :p
}

while [ x"$1" != x ]; do
    case $1 in
    -d|--debug) shift
        DODEBUG=true;;
    -i|--id) shift
        ID="$1"
	shift;;
    -h|--helper|--host) shift
        HELPER="$1"
        shift;;
    -m|--multi) shift
        MULTI=',"multi":true';;
    --pageid) shift
        PAGEID=',"pageid":"'$1'"'
        shift;;
    -t|--timeout) shift
        TIMEOUT="$1"
        shift;;
    -v|--verbose) shift
        DODEBUG=true;;
    -W) shift
        HELPER="$JS9WEBSITE";;
     *) break;;
    esac
done

# arg1: cmd
if [ x"$1" = x ]; then
  usage
  exit 0
else
  CMD="$1"
  shift
fi

# arg2 ... argn: arguments
ARGS=""
while [ x"$1" != x ]; do
    ARG=$(echo $1 | sed 's/"/\\"/g')
    if [ x"$ARGS" = x ]; then
      ARGS="\"$ARG\""
    else
      ARGS="${ARGS},\"$ARG\""
    fi
    shift
done

# general form of message sent to JS9:
QUERY='{"id":"'$ID'","cmd":"'$CMD'","args":['$ARGS']'${MULTI}${PAGEID}'}'

# get target host (add port if necessary)
HOST=$HELPER
echo $HOST | egrep ':[0-9][0-9]*$' 1>/dev/null 2>&1
if [ $? = 1 ]; then
  HOST="$HOST:$PORT"
fi

# encode the query
URL=$HOST/msg?$( rawurlencode "$QUERY" )

command -v wget 1>/dev/null 2>&1
if [ $? = 0 ]; then
    if [ x"$DODEBUG" != xtrue ]; then
        XARGS="-q"
    fi
    wget $XARGS -O- -T $TIMEOUT "$URL"
else
    command -v curl 1>/dev/null 2>&1
    if [ $? = 0 ]; then
        if [ x"$DODEBUG" = xtrue ]; then
            XARGS="-v"
	else
            XARGS="-s"
        fi
        curl $XARGS --connect-timeout $TIMEOUT "$URL"
    else
        error "$0 requires either wget or curl"
    fi
fi
