#!/bin/bash
#
# This script takes a GRML iso file as input and uses it to generate
# an iso that loads a speakup module during boot and optionally enables software speech. The
# result is a version of GRML that comes up speaking w/o user intervention..
#
# Copyright (C) 2025 John Heim
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#

function usage {
cat <<EOUsage
Usage
  `basename $0` <grml_iso> [synth_type] [ssh_password]
Parameters:
  grml_iso (required): The name of the GRML iso file to start with.
  synth_type (default=soft): Enable  specified speakup synthesizer type.
  ssh_password (no default): Enable ssh using the specified password.
EOUsage
  exit 1
  }

### MAIN ###
test -z "$DEBUG" && DEBUG=0
SELF=$(basename $0)

# handle arguments
test -n "$1" && grml_iso=$1
test -z "$grml_iso" && usage
test ! -r "$grml_iso" && { echo "The file '$grml_iso' is not readable or doesn't exist"; usage; }
test $DEBUG -gt 0 && echo "Using iso file $grml_iso"

test -n "$2" && synth_type=$2
test -z "$synth_type" && synth_type=soft
test $DEBUG -gt 0 && echo "Synth type is ${synth_type}."

test -n "$3" && ssh_password="$3"
test $DEBUG -gt 0 -a ! -z "$ssh_password" && echo "Enabling ssh with password, ${ssh_password}."

if [ "$synth_type" = "soft" -a $( echo "$grml_iso" | grep -c 'small') -gt 0 ]; then
  cat<<EOT
You are using a version of GRML that does not support software speech. If you continue,
the resulting ISO file may not work on some systems. It is
recommended that you use the full version of GRML instead.
EOT
  echo -n "Continue? (y/n, default=n}) "
  read answer
  test "$answer" != "y"  && exit
fi

# install dependencies
for package in xorriso arch-install-scripts squashfs-tools; do
  if ! dpkg -s "$package" &>/dev/null; then
    test $DEBUG -gt 0 && echo "Installing dependency $package."
    apt -y install "$package"
  fi
done

# extract files from .iso
test -d isofiles && rm -r isofiles
xorriso -osirrox on -indev "$grml_iso" -extract / isofiles

# extract root files system from file from .iso
if [ -d sqfs ]; then
  if mountpoint -q sqfs; then echo "Unmounting sqfs"; umount sqfs; fi
  rm -r sqfs
fi
unsquashfs -d sqfs isofiles/live/grml*/grml*.squashfs
mount -B sqfs sqfs                                         # bind mount to appease arch-chroot

# Enable software speech
case "$synth_type" in
soft)
  echo "Synth type is ${synth_type}."
  # create script that is automatically launched on grml startup
  mkdir isofiles/scripts
  echo '#!/bin/bash' > isofiles/scripts/grml.sh
  chmod +x isofiles/scripts/grml.sh
  if [ ! -f sqfs/etc/default/espeakup ]; then
    test $DEBUG -gt 0 && echo "Enabling software speech for GRML small."
    echo "apt-get update; apt-get -y install espeakup alsa-utils" >> isofiles/scripts/grml.sh
  fi
  cat << 'EOF' | sed -re 's/^    //' >> isofiles/scripts/grml.sh
systemctl enable --now espeakup
systemd-run -u deferred --no-block -p After=grml-boot.target bash -c 'amixer set Master 100% unmute; amixer set Speaker 100% unmute'
EOF
  ;;
*)
  echo "Synth type is ${synth_type}."
  ;;
esac

# add speakupmodule dependency to initramfs, generate new initramfs, then overwrite old initramfs with new
arch-chroot sqfs /bin/bash -c "echo speakup_${synth_type} >> /etc/initramfs-tools/modules; update-initramfs -u -k all"
cp sqfs/boot/initrd.img* isofiles/boot/grml*/initrd.img
umount sqfs
test $DEBUG -lt 3 && rm -r sqfs

# Enable ssh
test -n "$ssh_password" && sed -i "s/boot=live/boot=live ssh=${ssh_password}/" isofiles/boot/isolinux/default.cfg

# extract isohdpfx.bin to use in new iso; based on https://wiki.debian.org/RepackBootableISO
head -c 432 "$grml_iso" > isohdpfx.bin

# create new .iso; based on "mkisofs_cmdline" in isofiles\conf\buildinfo.json
source=$(basename ${grml_iso})
test "${source:0:5}" == "grml-" && target=$(echo "$source" | sed s/^grml-/grml-${synth_type}-/)
test -z "$target" && target="grml-${synth_type}.iso"
test -r "$target" && rm "$target"
xorriso -as mkisofs -V GRMLCFG -publisher 'grml-live | grml.org' -l -r -J -no-emul-boot -boot-load-size 4 \
  -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat \
  -boot-info-table -eltorito-alt-boot -e boot/efi.img -no-emul-boot -isohybrid-mbr isohdpfx.bin \
  -eltorito-alt-boot -e boot/efi.img -no-emul-boot -isohybrid-gpt-basdat -no-pad -o "$target" isofiles
test ! -r "$target" && { echo "Failed to create ${target}."; exit 1; }
echo "Created $target."

# cleanup
test $DEBUG -lt 2 && rm isohdpfx.bin
test $DEBUG -lt 2 && rm -r isofiles
exit 0
# EOF
