#!/bin/bash -e

function warning_blob() {
    cat <<MR_BLOBBY
This script converts an Endless OS system from using OSTree to using apt for
package management, and makes other changes that are generally desired for
development systems, such as making the journal persistent.

This is not a supported configuration. This script is intended only for
developing Endless OS itself. eos-dev-unlock is a safer, reversible alternative
for testing OS changes. You almost certainly SHOULD NOT continue.

WARNING: These changes are IRREVERSIBLE.
                           ============

MR_BLOBBY
}

if [[ $1 == "-h" ]] || [[ $1 == "--help" ]]; then
    echo "Usage:"
    echo "   $0"
    echo ""
    warning_blob
    exit 0
fi

warning_blob
read -p "Are you sure you want to proceed? [y/N] "
response="${REPLY,,}" # to lower
if [[ ! "$response" =~ ^(yes|y)$ ]]; then
    exit 1
fi

# Check that script was run with superuser privileges.
if [[ $EUID != 0 ]]; then
    echo "$0 requires superuser privileges."
    exit 1
fi

if [ ! -L /ostree ]; then
  echo "Not running on an ostree system"
  exit 1
fi

# Set the metrics system to use the dev environment
echo "Configuring Metrics System for Dev"
source eos-select-metrics-env 'dev'

# Disable upgrade timer
systemctl disable --now eos-autoupdater.timer
systemctl stop eos-autoupdater.service

# Unsure if these are necessary after stopping the timer, but better to be
# sure.
systemctl stop eos-updater.service

# 4th element in mountinfo is the "root" within a mounted filesystem, 5th is
# where it's mounted. Hence dig out where our root is coming from, so we're
# always using the _current_ root filesystem instead of the last updated
# version
OSTREE_DEPLOY_CURRENT=$(cat /proc/self/mountinfo | \
  egrep '([^ ]* ){4}/ ' | cut -d ' ' -f 4)

if [ -d /ostree/deploy/master ]; then
  echo "Detected master OSTree deploy"
  OSTREE_DEPLOY=/ostree/deploy/master
elif [ -d /ostree/deploy/dev ]; then
  echo "Detected dev OSTree deploy"
  OSTREE_DEPLOY=/ostree/deploy/dev
elif [ -d /ostree/deploy/eos ]; then
  echo "Detected eos OSTree deploy"
  OSTREE_DEPLOY=/ostree/deploy/eos
else
  echo "Failed to find OSTree deploy - exiting"
  exit 1
fi

# As now the real homedir will be /home and not /sysroot/home, update passwd accordingly
echo "Updating HOME directory"
sed -i "s#/sysroot/home#/home#g" /etc/passwd* /etc/adduser.conf /etc/default/useradd

# Directories in the deployment root to merge to /sysroot
ROOT_DIRS=(bin etc lib sbin usr opt var)
if [ -d ${OSTREE_DEPLOY_CURRENT}/lib64 ]; then
  ROOT_DIRS+=(lib64)
fi

echo "Hardlinking files from $OSTREE_DEPLOY_CURRENT, this may take a while"

# Copy the system directories to the real filesystems /
for dir in ${ROOT_DIRS[@]}; do
  cp -paxl ${OSTREE_DEPLOY_CURRENT}/${dir} /sysroot
done

# Overlay the /var as deployed on the systems /var
echo "Overlaying deployed /var FROM ${OSTREE_DEPLOY}"
cp -paxl ${OSTREE_DEPLOY}/var /sysroot

# To properly share objects with ostree, /var/lib/flatpak is a symlink
# to /sysroot/flatpak. Since /sysroot will become /, point the symlink
# to /flatpak instead.
if [ "$(readlink -f /sysroot/var/lib/flatpak)" = /sysroot/flatpak ]; then
  ln -sfT /flatpak /sysroot/var/lib/flatpak
fi

# Break any unwanted hard links. We assume that only empty files with
# multiple links are unwanted and were created by ostree. Otherwise,
# assume that the hard links are desired and were created by a package.
# We look for files with greater than 2 links since we just hardlinked
# everything to the ostree deployment, so by definition all files will
# have at least 2 links.
for dir in ${ROOT_DIRS[@]}; do
  find /sysroot/${dir} -xdev -type f -size 0 -links +2 \
       -exec eos-break-links '{}' '+'
done

# homedirs are /sysroot/home/<user> for some odd reason so point /sysroot/home 
# to the real /home.
# Note that making /syroot a symlink to / fails as dracut will 
# pick that up when re-generating the initramfs and blow up
mkdir -p /sysroot/sysroot
ln -s /home /sysroot/sysroot/

# Merge the passwd and group files from /lib back into the corresponding
# files in /etc so that debian maintainer scripts can update them as
# they expect.
eos-convert-passwd --root=/sysroot

# Make the systemd journal persistent
mkdir -p /var/log/journal
systemd-tmpfiles --create --prefix /var/log/journal

# Enable systemd coredumps storage
eos-enable-coredumps /sysroot/etc

# Put the kernels/initramfs in the expected place by Debian
for orig in ${OSTREE_DEPLOY_CURRENT}/usr/lib/modules/*; do
  ver="${orig##*/}"
  cp -pax "$orig/vmlinuz" "/boot/vmlinuz-$ver"
  cp -pax "$orig/initramfs.img" "/boot/initrd.img-$ver"
done

# Put the efi_binaries directory back where it came from
if [ -d "${OSTREE_DEPLOY_CURRENT}"/usr/lib/efi_binaries ]; then
  cp -pax "${OSTREE_DEPLOY_CURRENT}"/usr/lib/efi_binaries /boot/efi
fi

if [ -L /boot/uEnv.txt ] ; then 
  # Running on ARM
  ln -r -s /boot/vmlinuz* /boot/vmlinuz
  ln -r -s /boot/initrd* /boot/initrd.img

  sed -i \
    -e 's:^kernel_image=.*:kernel_image=/vmlinuz:' \
    -e 's:^ramdisk_image=.*:ramdisk_image=/initrd.img:' \
    -e 's/ostree=[^ ]*//g' \
    /boot/uEnv.txt
else
  O=$(grep options /boot/loader/entries/*.conf | head -n1 | cut -d ' ' -f 2-)
  echo GRUB_CMDLINE_LINUX_DEFAULT=\"${O} \" | sed 's/ostree=[^ ]*//g' \
    >> /etc/default/grub
  update-grub -f
fi

echo "All done, please reboot"
