#!/bin/bash
# shellcheck disable=SC1091 # Runtime-resolved path; intentionally not followed.
. "$(dirname "$(realpath "${BASH_SOURCE[0]}")")/../local-snap.sh" || return 1
set -eux

# Install LXD
install_lxd

if ! hasNeededAPIExtension "cloud_init"; then
  echo "Skipping cloud-init tests on LXD $(lxd version) as \"cloud-init\" extension is not present"
  # shellcheck disable=SC2034
  FAIL=0
  exit 0
fi

# Configure LXD
lxd init --auto

IMAGE="${TEST_IMG:-ubuntu-minimal-daily:26.04}"

echo "==> Create key pairs for tests"
ssh-keygen -t ed25519 -f "./profile-key" -N ""
ssh-keygen -t ed25519 -f "./ignored-key" -N ""
ssh-keygen -t ed25519 -f "./additional-key" -N ""

echo "==> Create configure profile for tests"
lxc profile set default cloud-init.user-data "$(cat <<EOF
#cloud-config
users:
  - name: root
    ssh_authorized_keys: $(cat ./profile-key.pub)
  - name: ubuntu
    ssh_authorized_keys: $(cat ./profile-key.pub)
EOF
)"

echo "==> Create test instance"
lxc init "${IMAGE}" c1

if hasNeededAPIExtension "cloud_init_ssh_keys"; then
  lxc profile set default cloud-init.ssh-keys.ignored="root:$(cat ./ignored-key.pub)"
  lxc config set c1 cloud-init.ssh-keys.ignored="none"
  lxc config set c1 cloud-init.ssh-keys.mykey="root:$(cat ./additional-key.pub)"
fi

lxc start c1
waitInstanceBooted c1

echo "==> Test SSH after cloud-init seeded the authorized_keys files of the respective users"
C_IPV4="$(lxc list c1 -c4 --format=csv | cut -d' ' -f1)"
[ "$(ssh -o StrictHostKeyChecking=no -q -i ./profile-key "root@${C_IPV4}" whoami)" = "root" ]
[ "$(ssh -o StrictHostKeyChecking=no -q -i ./profile-key "ubuntu@${C_IPV4}" whoami)" = "ubuntu" ]
! ssh -o StrictHostKeyChecking=no -q -i ./additional-key "ubuntu@${C_IPV4}" whoami || false

if hasNeededAPIExtension "cloud_init_ssh_keys"; then
  [ "$(ssh -o StrictHostKeyChecking=no -q -i ./additional-key "root@${C_IPV4}" whoami)" = "root" ]
  ! ssh -o StrictHostKeyChecking=no -q -i ./ignored-key "root@${C_IPV4}" whoami || false
fi

# Cleanup
rm ./profile-key ./profile-key.pub ./ignored-key ./ignored-key.pub ./additional-key ./additional-key.pub
lxc profile unset default cloud-init.user-data
lxc profile unset default cloud-init.ssh-keys.ignored
lxc delete -f c1

echo "==> Create test instance"
lxc init "${IMAGE}" c1 -c cloud-init.user-data="$(cat <<EOF
## template: jinja
#cloud-config
runcmd:
  - echo {{c1.local_hostname}} > /var/tmp/runcmd_output
EOF
)"

if hasNeededAPIExtension "cloud_init_ssh_keys"; then
  lxc config set c1 cloud-init.ssh-keys.mykey=root:lp:someuser
fi

lxc start c1

waitInstanceBooted c1 # Need networking for apt-get
lxc exec c1 -- apt-get update
lxc exec c1 -- apt-get install --no-install-recommends --yes curl

echo "==> Test the cloud-init template is in effect in container"
USERDATA=$(lxc exec c1 -- curl -s --unix-socket /dev/lxd/sock http://custom.socket/1.0/config/cloud-init.user-data)
echo "${USERDATA}" | grep "## template"
if hasNeededAPIExtension "cloud_init_ssh_keys"; then
  echo "${USERDATA}" | grep "lp:someuser"
fi

# Cleanup
lxc delete -f c1

echo "==> Use the NoCloud datasource by using a disk device with a \"cloud-init:config\" source"
lxc init "${IMAGE}" v1 --vm -c cloud-init.user-data="$(cat <<EOF
## template: jinja
#cloud-config
users:
  - name: {{ ds.meta_data.user_user }}
EOF
)"

if hasNeededAPIExtension "cloud_init_ssh_keys"; then
  lxc config set v1 user.user=user
else
  lxc config set v1 user.meta-data="$(cat <<EOF
user_user: user
EOF
)"
fi
lxc config device add v1 config disk source=cloud-init:config
lxc start v1
waitInstanceBooted v1
setup_instance_gocoverage v1
lxc exec v1 -- cloud-init status --wait --long
lxc exec v1 -- cloud-init status --long | grep "detail: DataSourceNoCloud"
lxc exec v1 -- getent passwd user
! lxc exec v1 -- getent passwd ubuntu || false

# Cleanup
prepare_vm_for_hard_stop v1
lxc delete -f v1

# shellcheck disable=SC2034
FAIL=0
