#!/usr/bin/env bash

set -e

range_size=65536
first_subid=100000
max_subid=4294967294

say() {
	echo "$*" >&2
}
error() {
	say "[ERROR] $*"
}
die() {
	error "$*"
	exit 1
}

PGM=$(basename "$0")
dry_run=
if [ "${DRY_RUN:-}" = "yes" ]; then
	dry_run="say [DRY_RUN]"
fi
[ -z "${1:-}" ] && die "usage: $PGM <target_user>"
sudo true || die sudo is not allowed for $USER

target_user=$1
id $1 >/dev/null || exit $?

subuid_file=${PODMAN_SUBUID_FILE:-/etc/subuid}
subgid_file=${PODMAN_SUBGID_FILE:-/etc/subgid}
[[ -r "$subuid_file" && -r "$subgid_file" ]] || die "cannot read $subuid_file and $subgid_file"

if [ "$USER" = "$target_user" ]; then
	as_target=
else
	as_target="sudo -u $target_user"
fi
if [ "$USER" = "root" ]; then
	as_root=
else
	as_root="sudo"
fi
$as_target true || {
	echo "cannot act as $target_user"
	exit 1
}

candidate=$first_subid
while ((candidate + range_size - 1 <= max_subid)); do
	range_end=$((candidate + range_size - 1))
	if ! awk -F: -v start="$candidate" -v end="$range_end" \
		'$2 ~ /^[0-9]+$/ && $3 ~ /^[0-9]+$/ && start <= $2 + $3 - 1 && end >= $2 { found=1; exit } END { exit !found }' \
		"$subuid_file" "$subgid_file"; then
		break
	fi
	candidate=$((candidate + range_size))
done
((candidate + range_size - 1 <= max_subid)) || die "no free subuid/subgid range of $range_size IDs"
range_end=$((candidate + range_size - 1))

say target user: $target_user
say subuids: "$candidate-$range_end"

$dry_run $as_root usermod --add-subuids "$candidate-$range_end" --add-subgids "$candidate-$range_end" "$target_user" ||
	die "could not assign the subuid/subgid range to $target_user"

$dry_run $as_target podman system migrate ||
	die "could not refresh the rootless Podman namespace for $target_user"
$dry_run $as_target podman unshare cat /proc/self/uid_map ||
	die "could not verify the rootless UID map for $target_user"
$dry_run $as_target podman unshare cat /proc/self/gid_map ||
	die "could not verify the rootless GID map for $target_user"
