#!/usr/bin/env bash
# aufs-unwh
# Author: lcpterid, 2026
# License: GPL v3

prog_name="$(basename "$0")"
help_text="Syntax: $prog_name path_to_unwh

Removes whiteout deletion files for a path or directory that was
deleted in a writeable AUFS branch, allowing versions of the
path from lower branches to be seen again.
"

script_dir="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &>/dev/null && pwd )"
lib_path="$(realpath -m "${script_dir}/../lib/libaufs-dir-tools")"
if ! [ -x "$lib_path" ]; then
       echo "Couldn't find library file!" >&2
       exit 1
fi
. "$lib_path"

[ "$#" -ne 1 ] && error_quit 1 ""

if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
	show_help
	exit 0
fi

mount_check || error_quit 2 "AUFS mounts do not match requirements. This tool requires one AUFS branch system, mounted on root (/) and optionally sub-mounted elsewhere."
branch_files_check || error_quit 2 "could not find AUFS branch files in /sys/fs/. Are you on an AUFS file system?"

path_to_unwh="$(realpath -m -s "$1" | aufs_real_path)"
parent_folder="$(dirname "$1")"

aufs_folder_check "$parent_folder" || error_quit 3 "Parent folder of $path_to_unwh is not in the AUFS filesystem"

branch_list="$(find /sys/fs/aufs/si*/ -name 'br[[:digit:]]*' 2>/dev/null)"
branch_list_sorted="$(echo "$branch_list" | 
	while read -r brf; do printf "%d\t%s\n" "${brf##*br}" "$brf"; done |
		sort -n |
		cut -f 2)"
rw_image_path_list="$(echo "$branch_list_sorted" | xargs cat | grep '=rw\(+[a-z_]*\)\?$' | sed 's/=rw\(+[a-z_]*\)\?$//')"

[ -z "$rw_image_path_list" ] && error_quit 4 "Could not find any writeable AUFS branches!"

unwh_file () {

	parent_folder="$(dirname "$1")"
	file_to_unwh="$(basename "$1")"

	exit_status=5
	while read -r image_path; do
		wh_path="${image_path}${parent_folder}/.wh.${file_to_unwh}"
		if [ -f "$wh_path" ]; then
			rm "$wh_path" && echo "Deleted: $wh_path" && exit_status=0 || exit_status=6 
		fi
	done < <(echo "$rw_image_path_list")
	[ $exit_status -eq 5 ] && error_quit "$exit_status" "No whiteouts found for path $path_to_unwh" nohelp
	[ $exit_status -eq 6 ] && error_quit "$exit_status" "Couldn't delete all whiteouts for $path_to_unwh" nohelp
}

mount -o remount,udba=notify / || warning_msg "Can't remount aufs filesystem. Restored files may not be visible until you reboot."

unwh_file "$path_to_unwh"

mount -o remount,udba=none /
