#!/bin/bash

## Copyright (C) 2012 - 2025 ENCRYPTED SUPPORT LLC <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

set -x
set -o errexit
set -o nounset
set -o pipefail
set -o errtrace
shopt -s inherit_errexit
shopt -s shift_verbose
export LC_ALL=C

true "INFO: Currently running script: ${BASH_SOURCE[0]} $*"

MYDIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" && pwd )"

source "${MYDIR}/pre"
source "${MYDIR}/variables"

exception_handler_unmount_raw() {
   true "${red}${bold}BASH_COMMAND${reset}: ${BASH_COMMAND}
${red}${bold}ERROR ${BASH_SOURCE[0]}: | caller: $(caller)${reset}"
   exit 1
}

unmount_raw() {
   trap exception_handler_unmount_raw ERR INT TERM

   sync

   true "INFO: Start of ${FUNCNAME[0]}. Running losetup --all for debugging before running kpartx."
   ${SUDO_TO_ROOT} losetup --all

   if [ "${kpartx_only:-}" = "true" ]; then
      true "INFO: kpartx_only=${kpartx_only}, skipping unmount ${CHROOT_FOLDER}"
   else
      ${SUDO_TO_ROOT} "${dist_source_help_steps_folder}/mount-cleanup" -- "${CHROOT_FOLDER}"
      unmount_if_mounted "${CHROOT_FOLDER}"
   fi

   local img
   if [ "${dist_build_mount_raw_file:-}" = "" ]; then
      img="${binary_image_raw_file}"
   else
      img="${dist_build_mount_raw_file}"
   fi

   ## Sleep to work around some obscure bug.
   ## https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=734794
   sleep 2 &
   wait "$!"
   sync

   ## First pass is best-effort: a transient "loopNpM is in use. Not removing"
   ## here must NOT abort the build. loop_teardown_verify below force-removes any
   ## leftover and is the authoritative teardown verification.
   ${SUDO_TO_ROOT} kpartx -d -s -v -- "${img}" || true "INFO: first kpartx -d non-zero exit code (transient in-use); loop_teardown_verify handles it."
   sync

   ## Authoritative teardown + verification. loop_teardown_verify (misc-helpers.bsh)
   ## tolerates the benign Qubes/Xen/docker case where 'kpartx -d' leaves the
   ## backing loop attached (an explicit 'losetup --detach' plus a bounded re-poll
   ## releases it), but still fails the build on a genuinely stuck device.
   if ! loop_teardown_verify "${img}" ; then
      error "Unmount failed. Loop device(s) still associated with '${img}' after teardown."
   fi

   true "INFO: Middle of ${FUNCNAME[0]}. Running losetup --all for debugging after kpartx -d (Delete partition mappings.)"
   ${SUDO_TO_ROOT} losetup --all
   sync

   if [ "${kpartx_only:-}" = "true" ]; then
      true "INFO: kpartx_only=${kpartx_only}, skipping debugging: ls -la ${CHROOT_FOLDER}"
   else
      if test -d "${CHROOT_FOLDER}" ; then
         ls -la -- "${CHROOT_FOLDER}"
      else
         true "INFO: CHROOT_FOLDER is not a directory. Perhaps already unmounted?"
      fi
   fi

   if [ "${kpartx_only:-}" = "true" ]; then
      true "INFO: kpartx_only=${kpartx_only}, skipping rmdir."
   else
      ## Delete temporary folder.
      ## It did not contain anything. It was only a mount point.
      ${SUDO_TO_ROOT} rmdir -- "${CHROOT_FOLDER}" || true
      sync
   fi
}

main() {
   if [ "${dist_build_install_to_root:-}" = "true" ]; then
      true "${green}INFO: Skipping script, because dist_build_install_to_root is set to true: ${BASH_SOURCE[0]}${reset}"
      exit 0
   else
      unmount_raw
   fi
}

main "$@"
