#!/bin/sh

set -eu

export UKI_MODE=1

images_dir=/installimages
loopdev=''

cleanup() {
  {
    umount "$images_dir" || true
    dmsetup remove puavoinstaller-installimages || true

    # do not leak file descriptors to vgchange, hence "3>&- 4>&- 5>&-"
    vgchange -a n puavoinstaller 3>&- 4>&- 5>&- || true

    rmdir /installimages || true

    if [ -n "$loopdev" ]; then
      losetup -d "$loopdev" || true
    fi
  } > /dev/null 2>&1
}

calc_required_imagefile_gigabytes() {
  local source_image

  source_image=$1

  if [ -n "$source_image" ]; then
    ls --block-size=950M -ds "$source_image" | awk '{ print $1 + 1 }'
    return 0
  fi

  echo "$(($(df --block-size=950M --output=size /rofs | awk 'NR == 2') + 1))"
}

install_image() {
  # There should be no need to run the preinst-hook, because for now it
  # it only contains the grub update.  Because the installed image and the
  # current boot image are same, the grub configuration should be correct.
  puavo-install-and-update-ltspimages --hosttype diskinstaller   \
                                      --images-dir "$images_dir" \
                                      --no-preinst-hook          \
                                      "$@"
}

trap cleanup 0 INT TERM

usage() {
  cat <<EOF
Usage: puavo-make-install-disk [--source-image source]
                               [--target-image target]
                               [--with-vdi] (only when using --target-image)
EOF
}

if [ "$(id -u)" -ne 0 ]; then
  # root is required for loopback mounts
  echo 'Run me as root!' >&2
  exit 1
fi

if ! args=$(getopt -n "$0" -o +hos:t:v \
              -l 'help,source-image:,target-image:,with-vdi' \
              -- "$@"); then
  usage
  exit 1
fi

source_image=''
target_image=''
with_vdi=false

eval "set -- $args"
while [ $# -ne 0 ]; do
  case "$1" in
    -h|--help) usage; exit 0;;
    -s|--source-image) source_image="$2"; shift; shift ;;
    -t|--target-image) target_image="$2"; shift; shift ;;
    -v|--with-vdi)     with_vdi=true;            shift ;;
    --) shift; break;;
    *)  usage; exit 1;;
   esac
done

if [ -n "$source_image" -a ! -e "$source_image" ]; then
  echo "source image $source_image does not exist!" >&2
  exit 1
fi

if $with_vdi; then
  if [ -z "$target_image" ]; then
    echo 'No target image set, yet using --with-vdi' >&2
    exit 1
  fi
  if ! which VBoxManage >/dev/null 2>&1; then
    echo 'could not find VBoxManage, yet using --with-vdi' >&2
    exit 1
  fi
fi

if [ -n "$target_image" ]; then
  if [ -e "$target_image" ]; then
    echo "target file $target_image exists, not overwriting" >&2
    exit 1
  fi

  dd if=/dev/null "of=${target_image}" bs=1M \
     seek="$(calc_required_imagefile_gigabytes "$source_image")K"
  loopdev=$(losetup --show -P -f "$target_image")

  puavo-setup-filesystems --force-disk-device "${loopdev#/dev/}" \
                          --force-encryption none \
                          --force-partition whole \
                          --force-setup-windows no \
                          --force-wipe-partition no \
                          --force-write-partitions yes \
                          --hosttype diskinstaller \
                          --loopback-only
else
  puavo-setup-filesystems --force-encryption none \
                          --force-setup-windows no \
                          --hosttype diskinstaller
fi

puavo-install-grub --hosttype   diskinstaller  \
                   --images-dir "$images_dir"  \
                   --vgname     puavoinstaller

if [ -n "$source_image" ]; then
  install_image --install-from-file "$source_image" \
                "$(basename "$source_image")"
else
  read puavoimage_name < /etc/puavo-image/name
  if [ -e /run/puavo/nbd-server ]; then
    install_image --install-from-nbd /dev/nbd0 "$puavoimage_name"
  else
    install_image --install-from-file "/images/${puavoimage_name}" \
                  "$puavoimage_name"
  fi
fi

if $with_vdi; then
  vdi_image="${target_image%.*}.vdi"
  VBoxManage convertdd "$target_image" "${vdi_image}.tmp" --format VDI
  chmod 644 "${vdi_image}.tmp"
  mv "${vdi_image}.tmp" "$vdi_image"
fi

#R fix output file ownership in case run through sudo
if [ -n "$target_image" -a -n "${SUDO_USER:-}" ]; then
  chown "${SUDO_USER}:" "$target_image"
  if $with_vdi; then
    chown "${SUDO_USER}:" "$vdi_image"
  fi
fi
