#!/bin/sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin

mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev 2>/dev/null || true

echo "[rollback] initramfs started"

device_tree_model() {
	tr -d '\0' < /sys/firmware/devicetree/base/model 2>/dev/null || true
}

preferred_mmc_disks() {
	case "$(device_tree_model)" in
		"Khadas VIM1S")
			echo "/dev/mmcblk2 /dev/mmcblk1 /dev/mmcblk0"
			;;
		*)
			echo "/dev/mmcblk1 /dev/mmcblk0 /dev/mmcblk2"
			;;
	esac
}

boot_disk_score() {
	disk="$1"
	score=0

	[ -b "${disk}p1" ] || {
		echo 0
		return 0
	}

	mkdir -p /boot-test

	if ! mount -t vfat "${disk}p1" /boot-test 2>/dev/null; then
		echo 0
		return 0
	fi

	if [ -f /boot-test/extlinux/extlinux.conf ]; then
		score=$((score + 50))
	fi

	if [ -f /boot-test/fitImage ] || [ -f /boot-test/uImage ]; then
		score=$((score + 25))
	fi

	if [ -f /boot-test/initramfs-rollback.cpio.gz ]; then
		score=$((score + 20))
	fi

	if [ -f /boot-test/dtb.img ] || ls /boot-test/*.dtb >/dev/null 2>&1; then
		score=$((score + 10))
	fi

	if [ -f /boot-test/s905_autoscript ] || [ -f /boot-test/aml_autoscript ] || [ -f /boot-test/boot.scr.uimg ]; then
		score=$((score + 20))
	fi

	if [ -d /boot-test/ota ]; then
		score=$((score + 10))
	fi

	if [ -d /boot-test/recovery ]; then
		score=$((score + 10))
	fi

	umount /boot-test 2>/dev/null || true

	[ -b "${disk}p2" ] && score=$((score + 15))
	[ -b "${disk}p3" ] && score=$((score + 15))
	[ -b "${disk}p4" ] && score=$((score + 10))

	echo "$score"
}

find_boot_disk() {
	best_disk=""
	best_score=0

	for d in $(preferred_mmc_disks); do
		score="$(boot_disk_score "$d")"

		case "$score" in
			''|*[!0-9]*)
				score=0
				;;
		esac

		if [ "$score" -gt "$best_score" ]; then
			best_disk="$d"
			best_score="$score"
		fi
	done

	[ -n "$best_disk" ] || return 1
	echo "$best_disk"
	return 0
}

DISK="$(find_boot_disk)" || {
	echo "[rollback] ERROR: could not find boot disk"
	exec sh
}

BOOT_PART="${DISK}p1"
ROOT_A_PART="${DISK}p2"
ROOT_B_PART="${DISK}p3"
HOME_PART="${DISK}p4"

BOOT_MNT="/boot"
OTA_DIR="$BOOT_MNT/ota"
REPORT_DIR="$OTA_DIR/report"

RECOVERY_DIR="$BOOT_MNT/recovery"
RECOVERY_TAR="$RECOVERY_DIR/rootfs.tar.xz"
RECOVERY_SUM="$RECOVERY_DIR/rootfs.tar.xz.sha256"

MAX_BOOT_ATTEMPTS=3
ROOTFS_SIZE_MIB=4096
PARTITION_ALIGN_MIB=4

mkdir -p "$BOOT_MNT"
mkdir -p /newroot

i=0
while [ ! -b "$BOOT_PART" ] && [ "$i" -lt 100 ]; do
	sleep 0.1
	i=$((i + 1))
done

fsck.vfat -a "$BOOT_PART" 2>/dev/null || true

mount -t vfat "$BOOT_PART" "$BOOT_MNT" || {
	echo "[rollback] ERROR: cannot mount /boot"
	exec sh
}

mkdir -p "$OTA_DIR"
mkdir -p "$REPORT_DIR"

LOG_FILE="$OTA_DIR/initramfs.log"

log() {
	echo "[rollback] $*" | tee -a "$LOG_FILE"
	sync
}

disk_name() {
	echo "${1##*/}"
}

disk_logical_block_size() {
	size="$(cat "/sys/class/block/$(disk_name "$1")/queue/logical_block_size" 2>/dev/null || true)"

	case "$size" in
		''|*[!0-9]*)
			echo 512
			;;
		*)
			echo "$size"
			;;
	esac
}

sectors_per_mib() {
	block_size="$(disk_logical_block_size "$1")"
	echo $((1048576 / block_size))
}

align_up() {
	value="$1"
	alignment="$2"
	echo $((((value + alignment - 1) / alignment) * alignment))
}

is_uint() {
	case "$1" in
		''|*[!0-9]*)
			return 1
			;;
		*)
			return 0
			;;
	esac
}

disk_partition_type_code() {
	label="$(fdisk -l "$1" 2>/dev/null | awk -F': ' '/Disklabel type:/{print $2; exit}')"

	case "$label" in
		gpt)
			echo "0FC63DAF-8483-4772-8E79-3D69D8477DE4"
			;;
		*)
			echo "83"
			;;
	esac
}

write_target_fstab() {
	target_root="$1"

	mkdir -p "$target_root/etc"

	cat > "$target_root/etc/fstab" <<EOF
/dev/root      /             auto   defaults                           1 1
proc           /proc         proc   defaults                           0 0
devpts         /dev/pts      devpts mode=0620,ptmxmode=0666,gid=5      0 0
tmpfs          /run          tmpfs  mode=0755,nodev,nosuid,strictatime 0 0
tmpfs          /var/volatile tmpfs  defaults                           0 0
$BOOT_PART     /boot         vfat   defaults                           0 0
$HOME_PART     /home         btrfs  defaults                           0 0
EOF
}

log "initramfs started from active boot partition"
log "cmdline=$(cat /proc/cmdline 2>/dev/null || true)"

boot_root="$ROOT_A_PART"

ROLLBACK_FLAG="$OTA_DIR/rollback.flag"
PENDING_ROOT="$OTA_DIR/pending-root"
PREVIOUS_ROOT="$OTA_DIR/previous-root"
CURRENT_ROOT="$OTA_DIR/current-root"
ATTEMPTED_ROOT="$OTA_DIR/attempted-root"
BOOT_ATTEMPTS="$OTA_DIR/boot-attempts"
LAST_FAILED_ROOT="$OTA_DIR/last-failed-root"
LAST_BOOTED_ROOT="$OTA_DIR/last-booted-root"
PARTITION_LAYOUT_PENDING="$OTA_DIR/partition-layout-pending"

log "checking partitions"
[ -b "$ROOT_A_PART" ] && log "rootA exists" || log "rootA missing"
[ -b "$ROOT_B_PART" ] && log "rootB exists" || log "rootB missing"
[ -b "$HOME_PART" ] && log "home exists" || log "home missing"
[ -f "$RECOVERY_TAR" ] && log "recovery rootfs exists" || log "recovery rootfs missing"
[ -f "$RECOVERY_SUM" ] && log "recovery checksum exists" || log "recovery checksum missing"
command -v sfdisk >/dev/null 2>&1 && log "sfdisk exists" || log "sfdisk missing"
command -v partprobe >/dev/null 2>&1 && log "partprobe exists" || log "partprobe missing"
command -v sgdisk >/dev/null 2>&1 && log "sgdisk exists" || log "sgdisk missing"
command -v mkfs.btrfs >/dev/null 2>&1 && log "mkfs.btrfs exists" || log "mkfs.btrfs missing"

root_label_for_part() {
	case "$1" in
		"$ROOT_A_PART") echo "rootA" ;;
		"$ROOT_B_PART") echo "rootB" ;;
		*) echo "rootA" ;;
	esac
}

increment_boot_attempts() {
	attempts=0

	if [ -f "$BOOT_ATTEMPTS" ]; then
		attempts="$(cat "$BOOT_ATTEMPTS" 2>/dev/null || echo 0)"
	fi

	case "$attempts" in
		''|*[!0-9]*)
			attempts=0
			;;
	esac

	attempts=$((attempts + 1))
	echo "$attempts" > "$BOOT_ATTEMPTS"
	echo "$attempts"
}

finish_partition_provisioning() {
	log "formatting rootB and home"

	mkfs.btrfs -f -L rootB "$ROOT_B_PART" >> "$LOG_FILE" 2>&1 || {
		echo "failed" > "$REPORT_DIR/partition-repair-result"
		echo "rootB_mkfs_failed" > "$REPORT_DIR/partition-repair-reason"
		return 1
	}

	mkfs.btrfs -f -L home "$HOME_PART" >> "$LOG_FILE" 2>&1 || {
		echo "failed" > "$REPORT_DIR/partition-repair-result"
		echo "home_mkfs_failed" > "$REPORT_DIR/partition-repair-reason"
		return 1
	}

	log "restoring rootA from recovery"
	repair_root_from_recovery "$ROOT_A_PART" || {
		echo "failed" > "$REPORT_DIR/partition-repair-result"
		echo "rootA_restore_failed" > "$REPORT_DIR/partition-repair-reason"
		return 1
	}

	echo "success" > "$REPORT_DIR/partition-repair-result"
	date -u +"%Y-%m-%dT%H:%M:%SZ" > "$REPORT_DIR/partition-repair-finished-at"

	rm -f "$PENDING_ROOT"
	rm -f "$PREVIOUS_ROOT"
	rm -f "$ROLLBACK_FLAG"
	rm -f "$ATTEMPTED_ROOT"
	rm -f "$BOOT_ATTEMPTS"
	rm -f "$PARTITION_LAYOUT_PENDING"
	rm -f "$OTA_DIR/pending-label"
	rm -f "$OTA_DIR/pending-partition"
	rm -f "$OTA_DIR/staged-at"

	echo "$ROOT_A_PART" > "$LAST_BOOTED_ROOT"
	echo "$ROOT_A_PART" > "$OTA_DIR/partition-repaired-root"
	date -u +"%Y-%m-%dT%H:%M:%SZ" > "$OTA_DIR/partition-repair-complete"

	sync

	log "partition repair complete, rebooting"
	reboot -f
	return 0
}

repair_root_from_recovery() {
	target_part="$1"
	target_label="$(root_label_for_part "$target_part")"

	log "attempting auto-repair of $target_part as $target_label"

	echo "$target_part" > "$REPORT_DIR/autorepair-root"
	echo "$target_label" > "$REPORT_DIR/autorepair-label"
	date -u +"%Y-%m-%dT%H:%M:%SZ" > "$REPORT_DIR/autorepair-started-at"

	if [ ! -f "$RECOVERY_TAR" ]; then
		log "ERROR recovery rootfs missing"
		echo "failed" > "$REPORT_DIR/autorepair-result"
		echo "recovery_rootfs_missing" > "$REPORT_DIR/autorepair-reason"
		return 1
	fi

	if [ ! -f "$RECOVERY_SUM" ]; then
		log "ERROR recovery checksum missing"
		echo "failed" > "$REPORT_DIR/autorepair-result"
		echo "recovery_checksum_missing" > "$REPORT_DIR/autorepair-reason"
		return 1
	fi

	cd "$RECOVERY_DIR" || {
		echo "failed" > "$REPORT_DIR/autorepair-result"
		echo "recovery_dir_missing" > "$REPORT_DIR/autorepair-reason"
		return 1
	}

	expected="$(awk '{print $1}' "$RECOVERY_SUM")"

	echo "$expected  $RECOVERY_TAR" | sha256sum -c - >> "$LOG_FILE" 2>&1 || {
		log "ERROR recovery checksum failed"
		echo "failed" > "$REPORT_DIR/autorepair-result"
		echo "recovery_checksum_failed" > "$REPORT_DIR/autorepair-reason"
		return 1
	}

	umount /newroot 2>/dev/null || true

	log "formatting $target_part"
	if ! mkfs.btrfs -f -L "$target_label" "$target_part" >> "$LOG_FILE" 2>&1; then
		log "ERROR mkfs.btrfs failed"
		echo "failed" > "$REPORT_DIR/autorepair-result"
		echo "mkfs_failed" > "$REPORT_DIR/autorepair-reason"
		return 1
	fi

	log "mounting repaired root"
	if ! mount -t btrfs -o rw "$target_part" /newroot; then
		log "ERROR repaired root mount failed"
		echo "failed" > "$REPORT_DIR/autorepair-result"
		echo "mount_after_mkfs_failed" > "$REPORT_DIR/autorepair-reason"
		return 1
	fi

	log "extracting recovery rootfs"
	if ! tar -xJpf "$RECOVERY_TAR" -C /newroot >> "$LOG_FILE" 2>&1; then
		log "ERROR recovery extract failed"
		echo "failed" > "$REPORT_DIR/autorepair-result"
		echo "extract_failed" > "$REPORT_DIR/autorepair-reason"
		umount /newroot 2>/dev/null || true
		return 1
	fi

	write_target_fstab /newroot

	sync
	umount /newroot 2>/dev/null || true

	echo "success" > "$REPORT_DIR/autorepair-result"
	echo "recovered_from_fat_rootfs" > "$REPORT_DIR/autorepair-reason"
	date -u +"%Y-%m-%dT%H:%M:%SZ" > "$REPORT_DIR/autorepair-finished-at"

	log "auto-repair completed"
	return 0
}

repair_partitions_if_needed() {
	log "partition repair check started"

	if [ -b "$ROOT_A_PART" ] && [ -b "$ROOT_B_PART" ] && [ -b "$HOME_PART" ]; then
		if [ -f "$PARTITION_LAYOUT_PENDING" ]; then
			log "partition layout is present after reprobe reboot, finishing provisioning"
			finish_partition_provisioning
			return $?
		fi

		log "expected partitions exist, no partition repair needed"
		return 0
	fi

	log "expected partitions missing, starting automatic partition repair"

	echo "started" > "$REPORT_DIR/partition-repair-result"
	date -u +"%Y-%m-%dT%H:%M:%SZ" > "$REPORT_DIR/partition-repair-started-at"

	if [ -f "$PARTITION_LAYOUT_PENDING" ]; then
		log "ERROR partition layout marker exists but partitions are still missing"
		echo "failed" > "$REPORT_DIR/partition-repair-result"
		echo "partitions_still_missing_after_reboot" > "$REPORT_DIR/partition-repair-reason"
		return 1
	fi

	[ -b "$DISK" ] || {
		log "ERROR disk missing: $DISK"
		echo "failed" > "$REPORT_DIR/partition-repair-result"
		echo "disk_missing" > "$REPORT_DIR/partition-repair-reason"
		return 1
	}

	[ -f "$RECOVERY_TAR" ] || {
		log "ERROR recovery rootfs missing"
		echo "failed" > "$REPORT_DIR/partition-repair-result"
		echo "recovery_rootfs_missing" > "$REPORT_DIR/partition-repair-reason"
		return 1
	}

	[ -f "$RECOVERY_SUM" ] || {
		log "ERROR recovery checksum missing"
		echo "failed" > "$REPORT_DIR/partition-repair-result"
		echo "recovery_checksum_missing" > "$REPORT_DIR/partition-repair-reason"
		return 1
	}

	cd "$RECOVERY_DIR" || {
		log "ERROR recovery directory missing"
		echo "failed" > "$REPORT_DIR/partition-repair-result"
		echo "recovery_dir_missing" > "$REPORT_DIR/partition-repair-reason"
		return 1
	}

	expected="$(awk '{print $1}' "$RECOVERY_SUM")"

	echo "$expected  $RECOVERY_TAR" | sha256sum -c - >> "$LOG_FILE" 2>&1 || {
		log "ERROR recovery checksum failed"
		echo "failed" > "$REPORT_DIR/autorepair-result"
		echo "recovery_checksum_failed" > "$REPORT_DIR/autorepair-reason"
		return 1
	}

	log "calculating dynamic p2/p3/p4 layout"

	BOOT_START_SECTORS="$(cat "/sys/class/block/$(disk_name "$BOOT_PART")/start" 2>/dev/null || true)"
	BOOT_SIZE_SECTORS="$(cat "/sys/class/block/$(disk_name "$BOOT_PART")/size" 2>/dev/null || true)"
	SECTORS_PER_MIB="$(sectors_per_mib "$DISK")"
	ALIGN_SECTORS=$((SECTORS_PER_MIB * PARTITION_ALIGN_MIB))
	ROOTFS_SIZE_SECTORS=$((SECTORS_PER_MIB * ROOTFS_SIZE_MIB))
	LINUX_PART_TYPE="$(disk_partition_type_code "$DISK")"

	if ! is_uint "$BOOT_START_SECTORS" || ! is_uint "$BOOT_SIZE_SECTORS" || ! is_uint "$SECTORS_PER_MIB"; then
		log "ERROR invalid boot partition geometry"
		log "BOOT_START_SECTORS=$BOOT_START_SECTORS BOOT_SIZE_SECTORS=$BOOT_SIZE_SECTORS SECTORS_PER_MIB=$SECTORS_PER_MIB"
		echo "failed" > "$REPORT_DIR/partition-repair-result"
		echo "invalid_boot_geometry" > "$REPORT_DIR/partition-repair-reason"
		return 1
	fi

	log "partition table type code: $LINUX_PART_TYPE"

	ROOT_A_START="$(align_up $((BOOT_START_SECTORS + BOOT_SIZE_SECTORS)) "$ALIGN_SECTORS")"
	ROOT_B_START="$(align_up $((ROOT_A_START + ROOTFS_SIZE_SECTORS)) "$ALIGN_SECTORS")"
	HOME_START="$(align_up $((ROOT_B_START + ROOTFS_SIZE_SECTORS)) "$ALIGN_SECTORS")"

	log "rootA start sector: $ROOT_A_START"
	log "rootB start sector: $ROOT_B_START"
	log "home start sector: $HOME_START"

	if command -v sgdisk >/dev/null 2>&1; then
		log "relocating GPT backup header if needed"
		sgdisk -e "$DISK" >> "$LOG_FILE" 2>&1 || true
	fi

	sfdisk --no-reread --append "$DISK" > "$REPORT_DIR/sfdisk.log" 2>&1 <<EOF || {
start=$ROOT_A_START, size=$ROOTFS_SIZE_SECTORS, type=$LINUX_PART_TYPE
start=$ROOT_B_START, size=$ROOTFS_SIZE_SECTORS, type=$LINUX_PART_TYPE
start=$HOME_START, type=$LINUX_PART_TYPE
EOF
		log "ERROR sfdisk append failed"
		echo "failed" > "$REPORT_DIR/partition-repair-result"
		echo "sfdisk_failed" > "$REPORT_DIR/partition-repair-reason"
		return 1
	}

	blockdev --rereadpt "$DISK" >> "$LOG_FILE" 2>&1 || true
	partprobe "$DISK" >> "$LOG_FILE" 2>&1 || true
	partx -u "$DISK" >> "$LOG_FILE" 2>&1 || true
	sleep 2

	i=0
	while { [ ! -b "$ROOT_A_PART" ] || [ ! -b "$ROOT_B_PART" ] || [ ! -b "$HOME_PART" ]; } && [ "$i" -lt 100 ]; do
		sleep 0.1
		i=$((i + 1))
	done

	if [ ! -b "$ROOT_A_PART" ] || [ ! -b "$ROOT_B_PART" ] || [ ! -b "$HOME_PART" ]; then
		log "new partition devices are not visible yet, scheduling reprobe reboot"
		echo "waiting_for_reboot_reprobe" > "$REPORT_DIR/partition-repair-reason"
		echo "$ROOT_A_START,$ROOT_B_START,$HOME_START" > "$PARTITION_LAYOUT_PENDING"
		sync
		reboot -f
		return 0
	fi

	finish_partition_provisioning
}

repair_partitions_if_needed || {
	log "ERROR partition repair failed"
	exec sh
}

if [ -f "$PENDING_ROOT" ] && [ ! -f "$ATTEMPTED_ROOT" ]; then
	boot_root="$(cat "$PENDING_ROOT")"
	log "first attempt booting pending root: $boot_root"
	echo "$boot_root" > "$ATTEMPTED_ROOT"

elif [ -f "$ROLLBACK_FLAG" ]; then
	log "rollback.flag exists"

	if [ -f "$PENDING_ROOT" ] && [ -f "$PREVIOUS_ROOT" ]; then
		pending="$(cat "$PENDING_ROOT")"
		previous="$(cat "$PREVIOUS_ROOT")"

		log "pending root failed: $pending"

		attempts="$(increment_boot_attempts)"
		log "boot attempts: $attempts"
		echo "$attempts" > "$REPORT_DIR/boot-attempts"

		echo "$pending" > "$REPORT_DIR/failed-root"
		echo "$previous" > "$REPORT_DIR/rolled-back-to"
		echo "boot_not_confirmed" > "$REPORT_DIR/reason"
		date -u +"%Y-%m-%dT%H:%M:%SZ" > "$REPORT_DIR/rollback-detected-at"

		echo "$pending" > "$LAST_FAILED_ROOT"

		if [ "$attempts" -ge "$MAX_BOOT_ATTEMPTS" ]; then
			log "max boot attempts reached, auto-repairing pending root"

			if repair_root_from_recovery "$pending"; then
				log "auto-repair succeeded, booting repaired root: $pending"

				echo "autorepair_after_repeated_failures" > "$REPORT_DIR/reason"
				echo "$pending" > "$REPORT_DIR/repaired-root"

				rm -f "$ROLLBACK_FLAG"
				rm -f "$ATTEMPTED_ROOT"
				rm -f "$BOOT_ATTEMPTS"

				boot_root="$pending"
			else
				log "auto-repair failed, rolling back to: $previous"

				echo "autorepair_failed_rollback" > "$REPORT_DIR/reason"

				rm -f "$PENDING_ROOT"
				rm -f "$PREVIOUS_ROOT"
				rm -f "$ROLLBACK_FLAG"
				rm -f "$ATTEMPTED_ROOT"
				rm -f "$BOOT_ATTEMPTS"
				rm -f "$OTA_DIR/pending-label"
				rm -f "$OTA_DIR/pending-partition"
				rm -f "$OTA_DIR/staged-at"

				boot_root="$previous"
			fi
		else
			log "rolling back to: $previous"

			rm -f "$PENDING_ROOT"
			rm -f "$PREVIOUS_ROOT"
			rm -f "$ROLLBACK_FLAG"
			rm -f "$ATTEMPTED_ROOT"
			rm -f "$OTA_DIR/pending-label"
			rm -f "$OTA_DIR/pending-partition"
			rm -f "$OTA_DIR/staged-at"

			boot_root="$previous"
		fi

	elif [ -f "$PREVIOUS_ROOT" ]; then
		previous="$(cat "$PREVIOUS_ROOT")"

		log "rollback.flag exists but pending-root missing"
		log "rolling back to: $previous"

		echo "unknown" > "$REPORT_DIR/failed-root"
		echo "$previous" > "$REPORT_DIR/rolled-back-to"
		echo "rollback_flag_without_pending_root" > "$REPORT_DIR/reason"
		date -u +"%Y-%m-%dT%H:%M:%SZ" > "$REPORT_DIR/rollback-detected-at"

		rm -f "$PREVIOUS_ROOT"
		rm -f "$ROLLBACK_FLAG"
		rm -f "$ATTEMPTED_ROOT"
		rm -f "$OTA_DIR/pending-label"
		rm -f "$OTA_DIR/pending-partition"
		rm -f "$OTA_DIR/staged-at"

		boot_root="$previous"
	else
		log "rollback.flag present but previous-root missing"

		echo "unknown" > "$REPORT_DIR/failed-root"
		echo "$ROOT_A_PART" > "$REPORT_DIR/rolled-back-to"
		echo "rollback_flag_without_previous_root" > "$REPORT_DIR/reason"
		date -u +"%Y-%m-%dT%H:%M:%SZ" > "$REPORT_DIR/rollback-detected-at"

		rm -f "$ROLLBACK_FLAG"
		rm -f "$ATTEMPTED_ROOT"

		boot_root="$ROOT_A_PART"
	fi

else
	if [ -f "$CURRENT_ROOT" ]; then
		boot_root="$(cat "$CURRENT_ROOT")"
		log "no pending-root, booting current-root: $boot_root"
	else
		log "no pending-root/current-root, defaulting to rootA"
		boot_root="$ROOT_A_PART"
	fi
fi

case "$boot_root" in
	"$ROOT_A_PART"|"$ROOT_B_PART")
		;;
	*)
		log "invalid root: $boot_root"
		boot_root="$ROOT_A_PART"
		;;
esac

echo "$boot_root" > "$LAST_BOOTED_ROOT"

sync

log "attempting mount of $boot_root"

if ! mount -t btrfs -o rw "$boot_root" /newroot; then
	log "mount failed for $boot_root"
	echo "$boot_root" > "$REPORT_DIR/mount-failed-root"
	echo "mount_failed" > "$REPORT_DIR/reason"

	if repair_root_from_recovery "$boot_root"; then
		log "mounting repaired root: $boot_root"

		mount -t btrfs -o rw "$boot_root" /newroot || {
			log "ERROR repaired root still cannot mount"
			echo "failed" > "$REPORT_DIR/autorepair-result"
			echo "repaired_root_mount_failed" > "$REPORT_DIR/autorepair-reason"
			exec sh
		}
	else
		log "ERROR auto-repair failed"
		exec sh
	fi
fi

log "mount successful"

ls -lah /newroot >> "$LOG_FILE" 2>&1 || true

if [ -x /newroot/sbin/init ]; then
	log "/sbin/init exists"
else
	log "/sbin/init missing"
	echo "$boot_root" > "$REPORT_DIR/invalid-root"
	echo "missing_sbin_init" > "$REPORT_DIR/reason"

	umount /newroot 2>/dev/null || true

	if repair_root_from_recovery "$boot_root"; then
		log "mounting repaired root after invalid-root repair: $boot_root"

		mount -t btrfs -o rw "$boot_root" /newroot || {
			log "ERROR repaired root still cannot mount"
			echo "failed" > "$REPORT_DIR/autorepair-result"
			echo "repaired_root_mount_failed" > "$REPORT_DIR/autorepair-reason"
			exec sh
		}
	else
		log "ERROR auto-repair failed"
		exec sh
	fi
fi

[ -d /newroot/etc ] && log "/etc exists" || log "/etc missing"
[ -f /newroot/etc/fstab ] && log "/etc/fstab exists" || log "/etc/fstab missing"

log "preparing switch_root"

mkdir -p /newroot/proc
mkdir -p /newroot/sys
mkdir -p /newroot/dev
mkdir -p /newroot/run
mkdir -p /newroot/boot

log "moving pseudo filesystems"

mount --move /proc /newroot/proc || log "WARN could not move /proc"
mount --move /sys /newroot/sys || log "WARN could not move /sys"
mount --move /dev /newroot/dev || log "WARN could not move /dev"

log "unmounting boot before switch_root"
umount "$BOOT_MNT" || log "WARN could not unmount /boot"

sync

echo "[rollback] switch_root starting"

exec switch_root /newroot /sbin/init
