#!/bin/bash
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-

[ -f /usr/local/bin/usr_local_tput.bash ] && \
    . /usr/local/bin/usr_local_tput.bash || {
	DBUG() { echo DEBUG $* ; }
	INFO() { echo INFO $* ; }
	WARN() { echo WARN $* ; }
	ERROR() { echo ERROR $* ; }
    }

prog=`basename $0 .bash`
PREFIX=/usr/local
ROLE=toxcore

#[ $# -eq 0 ] && set - Whonix-Gateway /bin/cat /proc/cmdline
[ $# -eq 0 ] && set - Whonix-Gateway /bin/netstat -lnp4
[ $# -lt 2 ] && echo USAGE: $0 domain command arguments

# https://access.redhat.com/solutions%2F732773
HOST=$1
shift
if [ $# -eq 0 ] ; then
    RCMD=guest-info
elif [[ $@ =~ guest- ]] ; then
    RCMD=$1
    shift
else
    RCMD=guest-exec
    CMD=$1
    fi
shift

# FixMe
if [ $# -lt 1 ]  ; then
    ARGS=""
  elif [ $# -gt 1 ] ; then
    ARGS=`echo "$@" | sed -e 's/ /","/g'`
  else
    ARGS="$1"
fi

[ -z "$CMD" ] && CMD=/usr/sbin/qemu-ga && ARGS=-D

INFO $0 $HOST $CMD $ARGS

rc=0
if [ RCMD = guest-info ] ; then
    DBUG virsh qemu-agent-command $HOST \
	 '{"execute":"'$RCMD'"}'
    virsh qemu-agent-command $HOST \
	  '{"execute":"'$RCMD'"}' \
	  >/tmp/Q$$.out || exit 1$?
    jq . < /tmp/Q$$.out # /tmp/R$$.out
    
elif [ $RCMD = guest-get-time ] || \
	 [ $RCMD = guest-get-cpustats ] || \
	 [ $RCMD = guest-get-diskstats ] || \
	 [ $RCMD = guest-get-devices ] || \
	 [ $RCMD =  guest-get-fsinfo ] || \
	 [ $RCMD =  guest-get-disks ] || \
	 [ $RCMD =  guest-get-hostname ] || \
	 [ $RCMD =  guest-get-timezone ] || \
	 [ $RCMD =  guest-get-users ] || \
	 [ $RCMD =  guest-get-vcpus ] || \
	 [ $RCMD = guest-network-get-interfaces ] || \
	 [ $RCMD = guest-ping ] || \
	 [ $RCMD = guest-sync ] \
   ; then
    DBUG virsh qemu-agent-command $HOST \
	 '{"execute":"'$RCMD'"}'
    virsh qemu-agent-command $HOST \
	  '{"execute":"'$RCMD'"}' \
	  >/tmp/Q$$.out || exit 1$?
    jq .return < /tmp/Q$$.out # /tmp/R$$.out
elif [ $RCMD = guest-exec ] ; then
    # timeout?
    DBUG virsh qemu-agent-command $HOST \
	 '{"execute":"'$RCMD'", "arguments": {"capture-output": true,"path":"'$CMD'","arg":["'"$ARGS"'"]}}'
    virsh qemu-agent-command $HOST \
	  '{"execute":"'"$RCMD"'", "arguments": {"capture-output": true,"path":"'$CMD'","arg":["'"$ARGS"'"]}}' \
	  >/tmp/Q$$.out || exit 1$?

    grep -q return /tmp/Q$$.out || exit 2
    # pid=`sed -e 's/.*://' -e 's/}.*//' /tmp/Q$$.out` 
    pid=`jq .return.pid < /tmp/Q$$.out`
    [ $? -eq 0 -a -n "$pid" ] || exit 3
    
    DBUG virsh qemu-agent-command $HOST "$CMD $pid"

    # echo DEBUG: virsh qemu-agent-command $HOST \
	#  '{"execute":"guest-exec-status", "arguments": {"pid": '$pid'}}'
    #virsh qemu-agent-command $HOST \
	#  '{"execute":"guest-exec-status", "arguments": {"pid": '$pid'}}' \
	#  >/tmp/R$$.out || exit 4$?

    TRIES=10
    i=0
    while [ $i -lt $TRIES ] ; do
	i=`expr $i + 1`
	virsh qemu-agent-command $HOST \
	      '{"execute":"guest-exec-status", "arguments": {"pid": '"$pid"'}}' \
	      >/tmp/R$$.out || exit 4$i$?
	grep -q '"exitcode":' /tmp/R$$.out && break
	sleep 5
	echo DEBUG: $i
    done
    [ $i -lt $TRIES ] || \
	{ echo ERROR: $i no exitcode in  /tmp/R$$.out; exit 5 ; }

    rc=`jq '.return.exitcode' < /tmp/R$$.out`
    #b64=`jq '.return.out_data' < /tmp/R$$.out`
    DBUG rc=$rc  /tmp/R$$.out
    if grep -q err-data /tmp/R$$.out ; then
	sed -e 's/{"return":{"exitcode":[0-9]*,"err-data":"//' -e 's/",".*//' /tmp/R$$.out | base64 -d - 2>/dev/null
#	[ $? -eq 0 ] && WARN $b64_err
    fi
    if grep -q out-data /tmp/R$$.out ; then
	sed -e 's/{"return":{"exitcode":[0-9]*,"out-data":"//' -e 's/",".*//' /tmp/R$$.out | base64 -d - 2>/dev/null
#	[ $? -eq 0 ] && INFO $b64_out
    fi
    
    #b64=`jq '.return.out_data' < /tmp/R$$.out`
    #[ $rrc -eq 0 ] || { ERROR b64 $b64 ; exit 7 ; }
fi

rm -f /tmp/{Q,R}$$.out
exit $rc
# 
#  guest-get-cpustats
#  guest-get-diskstats
# guest-ssh-remove-authorized-keys
# guest-ssh-add-authorized-keys
# guest-ssh-get-authorized-keys
#  guest-get-devices
#  guest-get-osinfo
#  guest-get-timezone
#  guest-get-users
#  guest-get-host-name
#  guest-exec
#  guest-exec-status
# guest-get-memory-block-info
# guest-set-memory-blocks
# guest-get-memory-blocks
# guest-set-user-password
#  guest-get-fsinfo
#  guest-get-disks
# guest-set-vcpus
# guest-get-vcpus
# guest-network-get-interfaces
# guest-suspend-hybrid
# guest-suspend-ram
# guest-suspend-disk
# guest-fstrim
# guest-fsfreeze-thaw
# guest-fsfreeze-freeze-list
# guest-fsfreeze-freeze
# guest-fsfreeze-status
# guest-file-flush
# guest-file-seek
# guest-file-write
# guest-file-read
# guest-file-close
# guest-file-open
# guest-shutdown
#  guest-info
# guest-set-time
# guest-get-time
# guest-ping
# guest-sync
# guest-sync-delimited
