#!/bin/sh
set -eux

cleanup() {
    echo ""
    if [ "${FAIL}" = "1" ]; then
        echo "Test failed"
        exit 1
    fi

    echo "Test passed"
    exit 0
}

FAIL=1
trap cleanup EXIT HUP INT TERM

# Install test dependencies
apt-get remove --purge cloud-init --yes
apt-get install --yes curl jq

# Install Incus
curl -sL https://pkgs.zabbly.com/get/incus-daily | sh

waitVMAgent() (
  set +x
  # shellcheck disable=SC3043
  local vmName="$1"
  for i in $(seq 90) # Wait up to 90s.
  do
    if incus info "${vmName}" | grep -qF 127.0.0.1; then
      return 0 # Success.
    fi

    sleep 1
  done

  echo "VM ${vmName} agent not running after ${i}s"
  return 1 # Failed.
)

# Configure Incus
incus network create incusbr0
incus profile device add default eth0 nic network=incusbr0

poolName="vmpool$$"
poolDriver=dir

echo "==> Create storage pool using driver ${poolDriver}"
incus storage create "${poolName}" "${poolDriver}"

echo "==> Create VM and boot"
incus init images:ubuntu/22.04/cloud v1 --vm -s "${poolName}"
incus start v1
waitVMAgent v1
incus info v1

# Install curl
incus exec v1 -- sh -c "apt-get update && apt-get install --no-install-recommends --yes curl"

echo "==> Checking guestapi is working"

# guestapi is enabled by default and should work
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0 | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/devices | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/config | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/meta-data | grep -q '#cloud-config'

# Run sync before forcefully restarting the VM otherwise the filesystem will be corrupted.
incus exec v1 -- "sync"
incus restart -f v1
waitVMAgent v1

# guestapi should be running after restart
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0 | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/devices | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/config | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/meta-data | grep -q '#cloud-config'

# Disable guestapi
incus config set v1 security.guestapi false

echo "==> Checking guestapi is not working"

! incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0 || false

incus exec v1 -- "sync"
incus restart -f v1
waitVMAgent v1

# guestapi should not be running after restart
! incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0 || false

echo "==> Checking guestapi can be enabled live"

# Enable guestapi
incus config set v1 security.guestapi true

# guestapi should be running after the config is enabled
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0 | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/devices | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/config | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/meta-data | grep -q '#cloud-config'

# test instance Ready state
incus exec v1 -- curl -s --unix-socket /dev/incus/sock -X PATCH -d '{"state":"Ready"}' http://custom.socket/1.0
[ "$(incus config get v1 volatile.last_state.ready)" = "true" ]

incus exec v1 -- curl -s --unix-socket /dev/incus/sock -X PATCH -d '{"state":"Started"}' http://custom.socket/1.0
[ "$(incus config get v1 volatile.last_state.ready)" = "false" ]

incus exec v1 -- curl -s --unix-socket /dev/incus/sock -X PATCH -d '{"state":"Ready"}' http://custom.socket/1.0
[ "$(incus config get v1 volatile.last_state.ready)" = "true" ]
incus stop -f v1
sleep 5
[ "$(incus config get v1 volatile.last_state.ready)" = "false" ]

# Test nested VM functionality.
incus start v1
waitVMAgent v1
sleep 30

# Configure to use the proxy
curl -sL https://pkgs.zabbly.com/get/incus-daily | incus exec v1 -- sh
incus exec v1 -- incus admin init --auto
incus exec v1 -- incus launch images:ubuntu/22.04/cloud v1v1 --vm
sleep 30
incus exec v1 -- incus info v1v1 | grep -F RUNNING

echo "==> Deleting VM"
incus delete -f v1
incus profile device remove default eth0

echo "==> Deleting storage pool"
incus storage delete "${poolName}"

echo "==> Deleting storage pool"
incus network delete incusbr0

FAIL=0
