#!/usr/bin/env bash
set -euo pipefail

data=.
args=()

argToRequest() {
  arg="$1"
  if [ "${arg:0:1}" = "{" ]; then
    argToPostCommand "$arg"
  else
    argToGet "$arg"
  fi
}

argToGet() {
  arg="$1"
  echo -e "GET $uriPath/api$arg HTTP/1.1\r
Host: $uriIP\r
Connection: close\r
x-js7-session: $(cat "$sessionTokenFile")\r
Accept: application/json\r
Accept-Charset: UTF-8\r
\r
\r"
}

argToPostCommand() {
  arg="$1"
  echo -en "POST $uriPath/api/command HTTP/1.1\r
Host: $uriIP\r
Connection: close\r
x-js7-session: $(cat "$sessionTokenFile")\r
Content-Type: application/json\r
Content-Length: ${#arg}\r
Accept: application/json\r
\r
$arg"
}

for arg in "$@"; do :
  case "$arg" in
    --data-directory=*)
      data="${arg#*=}"
      ;;
    *)
      args+=("$arg")
      ;;
  esac
done

sessionTokenFile="$data/work/session-token"
if [ ! -f "$sessionTokenFile" ]; then
  echo "Invalid argument --data-directory=$data (or missing file $data/work/session-token)"
  exit 1
fi

httpUri="$(cat "$data/work/http-uri")"
if ! [[ "$httpUri" =~ ^http://([^:]+):([0-9]+)(/.*)$ ]]; then
  echo File "$data/work/http-uri does not contain a valid HTTP URI. Maybe JS7 is not running or does not provide a HTTP port on localhost"
  exit 1
else
  uriIP="${BASH_REMATCH[1]}"
  uriPort="${BASH_REMATCH[2]}"
  uriPath="${BASH_REMATCH[3]}"
fi

for arg in "${args[@]}"; do
  # Try until connected
  for i in {10..0}; do
    exec 3<>"/dev/tcp/$uriIP/$uriPort" && break
    test $i -gt 0 || exit 1
    sleep 1
  done
  request=$(argToRequest "$arg")
  echo -n "$request" >&3

  IFS=' ' read -t 10 -r httpVersion status remainder <&3
  if [ "$status" != '200' ]; then
    echo "$status $remainder"
    echo
  fi
  # Skip headers
  while IFS='' read -r line && [ "$line" != "$(echo -e '\r')" ]; do :; done <&3

  cat <&3
  exec 3>&-
  echo
  if [ "$status" != '200' ]; then
    exit 1
  fi
done
