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

. "$LIBDIR/tiny-cloud/document"

: "${IMDS_API_VERSION:=v1}"
IMDS_BASE_URI="hetzner/$IMDS_API_VERSION"
IMDS_URI="$IMDS_BASE_URI/metadata"

IMDS_HOSTNAME="hostname"
IMDS_LOCAL_HOSTNAME="$IMDS_HOSTNAME"
IMDS_SSH_KEYS="public-keys"
IMDS_USERDATA="userdata"
IMDS_NICS="private-networks"
IMDS_MAC="mac_address"
IMDS_IPV4="ip"
IMDS_IPV4_NET="subnet"

: "${DEFAULT_NAMESERVERS=
	185.12.64.1
	185.12.64.2
	2a01:4ff:ff00::add:1
	2a01:4ff:ff00::add:2
}"

_imds_nic_data() {
	_imds_fetch_cached "$IMDS_CACHE_DIR/nics" _imds "$IMDS_NICS" || return
	cat "$IMDS_CACHE_DIR/nics"
}

_imds_init() { _imds_cache_init; }

_imds_ssh_keys() {
	_imds "$IMDS_SSH_KEYS" | sed 's/"/\n/g' | grep -E -v '(\[|\]|,)' | sort -u
}

_imds_userdata() {
	_imds_http "$IMDS_BASE_URI/$IMDS_USERDATA" $(_imds_endpoints)
}

_imds_nics() {
	local data indexes
	data=$(_imds_nic_data) || return 1
	indexes=$(printf '%s' "$data" | yx) || return 1
	[ -z "$indexes" ] || printf '%s\n' "$indexes"
}

_imds_nic_index() {
	local mac data indexes index address

	mac=$(cat "$SYS/class/net/$1/address") || return 1
	mac=$(printf '%s' "$mac" | lower)
	[ -n "$mac" ] || return 1
	data=$(_imds_nic_data) || return 1
	indexes=$(printf '%s' "$data" | yx) || return 1
	for index in $indexes; do
		address=$(printf '%s' "$data" | yx -- "$index" mac_address) || return 1
		address=$(printf '%s' "$address" | lower)
		[ "$address" = "$mac" ] || continue
		echo "$index"
		return 0
	done
	return 1
}

_imds_nic_value() {
	local data address keys indexes index
	data=$(_imds_nic_data) || return 1
	case "$2" in
		@mac)
			address=$(printf '%s' "$data" | yx -- "$1" "$3") || return 1
			printf '%s\n' "$address" | lower
			;;
		@ipv4-net)
			address=$(printf '%s' "$data" | yx -- "$1" "$3") || return 1
			printf '%s\n' "$address"
			;;
		@ipv4)
			address=$(printf '%s' "$data" | yx -- "$1" "$3") || return 1
			case "$address" in ''|null) ;; *) printf '%s\n' "$address";; esac
			keys=$(printf '%s' "$data" | yx -- "$1") || return 1
			printf '%s\n' "$keys" | grep -qxF alias_ips || return 0
			indexes=$(printf '%s' "$data" | yx -- "$1" alias_ips) || return 1
			case "$indexes" in ''|null) return 0;; esac
			for index in $indexes; do
				address=$(printf '%s' "$data" |
					yx -- "$1" alias_ips "$index") || return 1
				case "$address" in ''|null) continue;; esac
				printf '%s\n' "$address"
			done
			;;
		*)
			document_select "$IMDS_CACHE_DIR/nics" "$1${3:+/$3}"
			;;
	esac
}
