# DigitalOcean Instance MetaData Service variables and functions
# vim: set filetype=sh:
# shellcheck shell=sh

IMDS_HOSTNAME="hostname"
IMDS_LOCAL_HOSTNAME="$IMDS_HOSTNAME"
IMDS_SSH_KEYS="public-keys"
IMDS_USERDATA="user-data"
: "${IMDS_NAMESERVERS:=dns/nameservers}"

_imds_init() {
	[ -z "$IMDS_SELECTED_SOURCE" ] || return 0
	IMDS_SELECTED_SOURCE=$(_digitalocean_select_source) || return
	if [ "$IMDS_SELECTED_SOURCE" = configdrive ]; then
		IMDS_DOCUMENT_DIR=$(configdrive_directory digitalocean native \
			"${IMDS_API_VERSION:-latest}") || return
		IMDS_SELECTED_FORMAT=native
		IMDS_HOSTNAME="meta_data.json/hostname"
		IMDS_LOCAL_HOSTNAME="$IMDS_HOSTNAME"
		IMDS_SSH_KEYS="meta_data.json/public_keys"
		IMDS_USERDATA=user_data
		unset IMDS_NAMESERVERS

		_imds() {
			imds_document "$IMDS_DOCUMENT_DIR" "$1"
		}
		. "$LIBDIR/tiny-cloud/imds-network-openstack"
	else
		. "$LIBDIR/tiny-cloud/imds-network"
		IMDS_URI="metadata/${IMDS_API_VERSION:-v1}"
		IMDS_NICS="interfaces"
		IMDS_MAC="mac"
		IMDS_IPV4="ipv4/address"
		IMDS_IPV6="ipv6/address"
		IMDS_IPV4_NET="ipv4"
		IMDS_IPV6_NET="ipv6"
	fi
}

_imds_ssh_keys() {
	if [ "$IMDS_SELECTED_SOURCE" = configdrive ]; then
		configdrive_ssh_keys "$IMDS_DOCUMENT_DIR" "$IMDS_SSH_KEYS" native
	else
		_imds "$IMDS_SSH_KEYS"
	fi
}

_imds_nic_index() {
	local mac groups group indexes index address

	mac=$(cat "$SYS/class/net/$1/address") || return 1
	mac=$(printf '%s' "$mac" | lower)
	[ -n "$mac" ] || return 1

	groups=$(_imds "$IMDS_NICS/") || return 1
	for group in $groups; do
		group="${group%/}"
		indexes=$(_imds "$IMDS_NICS/$group/") || return 1
		for index in $indexes; do
			index="${index%/}"
			address=$(_imds "$IMDS_NICS/$group/$index/mac") || return 1
			address=$(printf '%s' "$address" | lower)
			[ "$address" = "$mac" ] || continue
			printf '%s/%s\n' "$group" "$index"
			return 0
		done
	done
	return 1
}

_imds_nic_value() {
	local path="$IMDS_NICS/$1" key="$3" keys address mask

	case "$2" in
		@ipv6|@ipv6-net)
			keys=$(_imds "$path/") || return 1
			printf '%s\n' "$keys" | grep -qxE 'ipv6/?' || return 0
			;;
	esac
	case "$2" in
		@mac)
			address=$(_imds "$path/$key") || return 1
			printf '%s\n' "$address" | lower
			;;
		@ipv4-net)
			address=$(_imds "$path/$key/address") || return 1
			mask=$(_imds "$path/$key/netmask") || return 1
			_imds_ipv4_network "$address" "$mask"
			;;
		@ipv6-net)
			address=$(_imds "$path/$key/address") || return 1
			mask=$(_imds "$path/$key/cidr") || return 1
			_imds_ipv6_network "$address" "$mask"
			;;
		*) _imds "$path/$key";;
	esac
}
