#!/bin/bash

## Copyright (C) 2019 - 2025 ENCRYPTED SUPPORT LLC <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

#set -x
set -o errexit
set -o nounset
set -o pipefail
set -o errtrace
shopt -s inherit_errexit

benchmarktimestart=0
benchmarktimeend=0

## Thanks to perreal for the convertsecs function.
## http://stackoverflow.com/a/12199798
## NOTE: If uncommenting for some reason, use is_whole_number from strings.bsh
## to verify the safety of ${1}
#convertsecs() {
#   local h m s
#   ((h="${1}/3600"))
#   ((m="(${1}%3600)/60"))
#   ((s="${1}%60"))
#   printf "%02d:%02d:%02d\n" "$h" "$m" "$s"
#}

## TODO: rename to match derivative-maker's benchmark helpers
##   (benchmarktimestart / benchmarktimeend in this file are local
##   to the VBox test driver; derivative-maker's help-steps expose
##   the same notion under a different name). Aligning the function
##   names here with derivative-maker's would let this script reuse
##   the upstream helpers instead of redefining them.
benchmark_time_start() {
   benchmarktimestart="$(date +%s)"
}

benchmark_time_end() {
   benchmarktimeend="$(date +%s)"
   benchmark_took_seconds="$(( $benchmarktimeend - $benchmarktimestart ))"
}

variables() {
   vmname="Whonix-Gateway-LXQt"
   user_name="user"
   ## TODO: empty by default nowadays
   password="changeme"

   vboxmanage_cmd="VBoxManage --nologo"
   vboxheadless_cmd="vboxheadless"

   vm_wait_for_vm_start_timeout=60
   vm_wait_for_vm_shutdown_timeout=20

   vboxmanage_sudo_wrapper="$vboxmanage_cmd guestcontrol $vmname run --username $user_name --password $password --wait-stdout --wait-stderr --exe /usr/libexec/helper-scripts/sudo-askpass-wrapper -- apt/sudo-askpass-wrapper"
}

vm_is_running_test() {
   running_vms_list="$($vboxmanage_cmd list runningvms)" || true

   ## example running_vms_list:
   ##   "Whonix-Workstation-LXQt" {c504a345-8217-4954-8864-a5270a661b11}
   ## A previous version word-split $running_vms_list, which broke
   ## any VM name that contained spaces (the quoted name token was
   ## split across multiple words). Match the full quoted name +
   ## the following ` {uuid}` separator with grep -F instead.
   vm_running=false
   if grep -F -- "\"$vmname\" {" <<< "$running_vms_list" >/dev/null ; then
      vm_running=true
   fi
}

wait_vm_shutdown() {
   benchmark_time_start
   while true ; do
      vm_is_running_test
      benchmark_time_end
      if [ "$vm_running" = "false" ]; then
         printf '%s\n' "INFO: VM shutdown took $benchmark_took_seconds seconds."
         break
      fi
      if [ "$benchmark_took_seconds" -ge "$vm_wait_for_vm_shutdown_timeout" ]; then
         printf '%s\n' "ERROR: VM shutdown longer than $vm_wait_for_vm_shutdown_timeout seconds." >&2
         exit 1
      fi
      sleep 2
   done
}

error_out_if_vm_is_running() {
   vm_is_running_test
   if [ "$vm_running" = "true" ]; then
      printf '%s\n' "ERROR: VM not expected to be still running!" >&2
      exit 1
   fi
}

start_vm() {
   ## Does not exist but more debug output.
   #$vboxheadless_cmd --startvm "$vmname"

   $vboxmanage_cmd startvm "$vmname" --type headless
}

power_off_vm_audit() {
   $vboxmanage_cmd controlvm "$vmname" poweroff
}

power_off_vm_ignore() {
   $vboxmanage_cmd controlvm "$vmname" poweroff &>/dev/null || true
}

acpipowerbutton_vm() {
   VBoxManage controlvm "$vmname" acpipowerbutton
}

vm_guest_control_cmd() {
   $vboxmanage_cmd guestcontrol "$vmname" run --username "$user_name" --password "$password" --wait-stdout --wait-stderr --exe "$@"
}

wait_for_vm() {
   printf '%s\n' "INFO: Waiting for VM guestcontrol to get ready."
   benchmark_time_start
   while true ; do
      benchmark_time_end
      if vm_guest_control_cmd "/bin/ls" &>/dev/null ; then
         printf '%s\n' "INFO: VM was ready after $benchmark_took_seconds seconds."
         break
      fi
      if [ "$benchmark_took_seconds" -ge "$vm_wait_for_vm_start_timeout" ]; then
         printf '%s\n' "ERROR: VM took longer than $vm_wait_for_vm_start_timeout seconds to start." >&2
         exit 1
      fi
      sleep 2
   done
}

whonix_developer_repository_enable() {
   $vboxmanage_sudo_wrapper repository-dist --verbose --enable --repository developers
}

# kill_apt() {
#    pid="$($vboxmanage_sudo_wrapper pgrep apt)"
#
#    $vboxmanage_sudo_wrapper kill -s sigterm "$pid"
# }

apt_update() {
   $vboxmanage_sudo_wrapper dpkg --configure -a

   $vboxmanage_sudo_wrapper apt-get update
}

install_packages() {
   $vboxmanage_sudo_wrapper apt-get --yes install lkrg tirdad

   $vboxmanage_sudo_wrapper apt-get --yes autoremove
}

snapshot_vm_create() {
   #VBoxManage snapshot Whonix-Gateway-LXQt list --machinereadable

   #SnapshotName="before-dev-upgrade"
   #SnapshotUUID="23f0703b-79e7-436b-9a5e-67e8cc6aace0"
   #CurrentSnapshotName="before-dev-upgrade"
   #CurrentSnapshotUUID="23f0703b-79e7-436b-9a5e-67e8cc6aace0"
   #CurrentSnapshotNode="SnapshotName"

   snapshot_name="before-dev-upgrade"

   ## Do not create another snapshot with the same name.
   snapshot_list_output="$($vboxmanage_cmd snapshot "$vmname" list --machinereadable)"
   if printf '%s\n' "$snapshot_list_output" | grep -- "$snapshot_name" >/dev/null 2>/dev/null; then
      return 0
   fi

   $vboxmanage_cmd snapshot "$vmname" take "$snapshot_name"
}

snapshot_vm_restore() {
   snapshot_name="before-dev-upgrade"
   $vboxmanage_cmd snapshot "$vmname" restore "$snapshot_name"
}

variables

# power_off_vm_ignore
# error_out_if_vm_is_running
# start_vm
# wait_for_vm

#kill_apt
apt_update
install_packages

# acpipowerbutton_vm
# wait_vm_shutdown

#$vboxmanage_cmd guestcontrol "$vmname" run --username "$user_name" --password changeme --wait-stdout --wait-stderr --exe "/bin/ls" -- ls/arg0 vmtest arg1 "a test2"
