#!/bin/sh
# Detect OS installations in btrfs subvolumes.
# Runs before 50mounted-tests to handle btrfs subvolume layouts
# (e.g. @, @home, @var) where the default subvolume may not be the root.
set -e

partition="$1"

. /usr/share/os-prober/common.sh

require_tmpdir

# Only handle btrfs partitions
types="$(fs_type "$partition")"
if [ "$types" != btrfs ]; then
	exit 1
fi

# Require btrfs CLI for subvolume enumeration
if ! type btrfs >/dev/null 2>&1; then
	debug "btrfs command not found; skipping btrfs subvolume detection"
	exit 1
fi

tmpmnt="$OS_PROBER_TMP/btrfs-mount"
if [ ! -d "$tmpmnt" ]; then
	mkdir "$tmpmnt"
fi

mounted=
do_unmount() {
	if [ "$mounted" ]; then
		umount "$tmpmnt" 2>/dev/null || true
	fi
	mounted=
	rmdir "$tmpmnt" 2>/dev/null || true
	rm -f "$OS_PROBER_TMP/btrfs-candidates" 2>/dev/null || true
}
trap 'do_unmount; cleanup' EXIT HUP INT QUIT TERM

# Mount the partition to enumerate subvolumes
if ! mount -t btrfs -o ro "$partition" "$tmpmnt" 2>/dev/null; then
	debug "$partition: failed to mount btrfs partition"
	exit 1
fi
mounted=1

# Get all subvolumes and read-only subvolumes
subvol_list="$(btrfs subvolume list "$tmpmnt" 2>/dev/null)" || true
subvol_ro_list="$(btrfs subvolume list -r "$tmpmnt" 2>/dev/null)" || true

do_unmount

# No subvolumes — nothing to do
if [ -z "$subvol_list" ]; then
	debug "$partition: no btrfs subvolumes found"
	exit 1
fi

# Extract top-level (top level 5) subvolume IDs and paths
# Format: ID <id> gen <gen> top level <tl> path <path>
# Use a temp file for candidate list (POSIX sh — no arrays, no pipeline var export)
: >"$OS_PROBER_TMP/btrfs-candidates"

echo "$subvol_list" | while read _id id _gen gen _top _level toplevel _path path; do
	# Only top-level subvolumes (direct children of btrfs root)
	# Format: ID <id> gen <gen> top level <toplevel> path <path>
	# Note: "top level" is two words, hence _top and _level are separate
	if [ "$toplevel" != "5" ]; then
		continue
	fi

	# Skip read-only subvolumes (snapshots)
	if echo "$subvol_ro_list" | grep -q "^ID $id "; then
		continue
	fi

	# Get the subvolume name (last component of path, though for
	# top-level subvols path is typically a single component)
	name="${path##*/}"

	# Skip well-known non-root subvolumes
	case "$name" in
		@home|@cache|@log|@tmp|@var|@srv|@boot|@swap)
			continue
			;;
		@snapshots|.snapshots|@snapper)
			continue
			;;
	esac

	# Skip names containing "snap" (also matches "snapshot")
	if echo "$name" | grep -qi 'snap'; then
		continue
	fi

	# Skip purely numeric names (snapper snapshot IDs)
	case "$name" in
		*[!0-9]*)
			# Contains non-digit — not purely numeric, keep it
			;;
		"")
			continue
			;;
		*)
			# Purely numeric — skip
			continue
			;;
	esac

	echo "$id $path" >>"$OS_PROBER_TMP/btrfs-candidates"
done

# Check if we have any candidates
if [ ! -s "$OS_PROBER_TMP/btrfs-candidates" ]; then
	debug "$partition: no btrfs root subvolume candidates found"
	exit 1
fi

found=
btrfs_uuid=$(blkid -s UUID -o value "$partition" 2>/dev/null) || true

while read subvol_id subvol_path; do
	# Ensure mount point exists (do_unmount removes it)
	if [ ! -d "$tmpmnt" ]; then
		mkdir "$tmpmnt"
	fi
	# Mount this subvolume
	if ! mount -t btrfs -o "subvolid=$subvol_id,ro" "$partition" "$tmpmnt" 2>/dev/null; then
		debug "$partition: failed to mount subvolume $subvol_path (id=$subvol_id)"
		continue
	fi
	mounted=1

	debug "probing btrfs subvolume $subvol_path (id=$subvol_id) on $partition"

	# Only run the linux-distro test — btrfs is a Linux filesystem
	# Capture output to append btrfs subvolume info for GRUB
	test=/usr/lib/os-probes/mounted/90linux-distro
	if [ -f "$test" ] && [ -x "$test" ]; then
		debug "running $test on btrfs subvol $subvol_path"
		output=$("$test" "$partition" "$tmpmnt" btrfs)
		if [ $? -eq 0 ] && [ -n "$output" ]; then
			debug "os found by $test on btrfs subvol $subvol_path"
			result "${output}:btrfs:UUID=${btrfs_uuid}:subvol=${subvol_path}"
			found=1
		fi
	fi

	do_unmount
done <"$OS_PROBER_TMP/btrfs-candidates"

rm -f "$OS_PROBER_TMP/btrfs-candidates"

if [ "$found" ]; then
	exit 0
fi
exit 1
