#!/bin/bash

shopt -s extglob nullglob
set -e

setup()
{
	while read -r k v; do
		k="${k%:}"
		case "$k" in
			KERNEL_INSTALL_ENTRY_TOKEN|KERNEL_INSTALL_BOOT_ROOT|ENTRY_DIR_ABS)
				eval $k="'$v'"
			;;
		esac
	done < <(/usr/bin/kernel-install inspect)
	[ -n "$KERNEL_INSTALL_ENTRY_TOKEN" ]
	[ -n "$KERNEL_INSTALL_BOOT_ROOT" ]
	[ -n "$ENTRY_DIR_ABS" ]
}

_add_kernels()
{
	local subvol="$1"
	local num="$2"

	export KERNEL_INSTALL_DRACUT_SKIP_IF_EXIST=1
	export SNAPSHOT="$num"
	export SUBVOL="@/.snapshots/$num/snapshot"
	for k in "$subvol/.snapshots/$num"/snapshot/usr/lib/modules/*/vmlinuz; do
		v="${k%/*}"
		v="${v##*/}"
		/usr/bin/kernel-install add "$v" "$k"
	done
}

is_transactional()
{
	# don't handle this here if called within transactional-update. We have
	# to run after it's done doing it's thing.
	[ "$(stat -f -c %T /etc)" = "overlayfs" ]
}

# when creating a snapshot we fetch all bls configs from previous snapshot dir,
# mangle them to contain current snapshot number, then install to efi partition.
create_snapshot()
{
	subvol="$1"
	fs="$2"
	num="$3"

	[ "$fs" = btrfs ] || return 1

	is_transactional && return 0

	_add_kernels "$subvol" "$num"
}

delete_snapshot()
{
	subvol="$1"
	fs="$2"
	num="$3"

	[ "$fs" = btrfs ] || return 1

	export SNAPSHOT="$num"
	export SUBVOL="@/.snapshots/$num/snapshot"
	for k in "$subvol/.snapshots/$num"/snapshot/usr/lib/modules/*/vmlinuz; do
		v="${k%/*}"
		v="${v##*/}"
		/usr/bin/kernel-install remove "$v" "$k" || :
		/usr/bin/bootctl unlink "$KERNEL_INSTALL_ENTRY_TOKEN-$v-$num.conf" || :
	done
}

set_default_snapshot()
{
	subvol="$1"
	fs="$2"
	num="$3"

	[ "$fs" = btrfs ] || return 1

	configs=("$subvol/.snapshots/$num"/bls-*.conf)
	configs=("${configs##*/bls-}")
	# if there aren't any configs for this snapshot we are probably called
	# by transactional-update for the first time. Run kernel-install and re-try.
	if [ -z "${configs[0]}" ] && is_transactional; then
		_add_kernels "$subvol" "$num"
		configs=("$subvol/.snapshots/$num"/bls-*.conf)
		configs=("${configs##*/bls-}")
	fi

	# FIXME: somehow we should know which kernel is default
	# bootctl list --json=short| jq '.[]|select(.isDefault == true)|[.version]|join(" ")' -r
	configs=($(printf '%s\n' "${configs[@]}"|sort))
	conf="${configs[0]}"
	if [ -n "$conf" ]; then
		bootctl set-default "$conf"
	fi
}

h()
{
	echo "Available commands:"
	echo "${!commands[@]}"
}

declare -A commands

commands['create-snapshot-post']=create_snapshot
commands['delete-snapshot-pre']=delete_snapshot
commands['set-default-snapshot-post']=set_default_snapshot
commands['help']=h

logger -t snapper "$0 $@"

setup

cmd="$1"
shift
[ -n "$cmd" ] || cmd=help
if [ "${#commands[$cmd]}" -gt 0 ]; then
	${commands[$cmd]} "$@"
fi
