#!/bin/sh

set -eu

CALAMARES_DIR="/etc/calamares"
MODULE_DIR="/etc/calamares/modules"

ACTIVE_SETTINGS="$CALAMARES_DIR/settings.conf"
ZFS_SETTINGS="$CALAMARES_DIR/settings-zfs.conf"

ACTIVE_PARTITION_CONF="$MODULE_DIR/partition.conf"
ZFS_PARTITION_CONF="$MODULE_DIR/partition-zfs.conf"

GRUB_ZFS_CONF="$MODULE_DIR/zfs-grub.conf"
OPENZFS_CONF="$MODULE_DIR/zfs-openzfs.conf"
ACTIVE_ZFS_CONF="$MODULE_DIR/zfs.conf"

MODE="${1:-}"

SETTINGS_BACKUP=""
PARTITION_BACKUP=""

die()
{
    echo "Synex Calamares ZFS: $*" >&2
    exit 1
}

[ "$(id -u)" -eq 0 ] || die "must run as root"

[ -f "$ACTIVE_SETTINGS" ] \
    || die "missing default Calamares configuration: $ACTIVE_SETTINGS"

[ -f "$ZFS_SETTINGS" ] \
    || die "missing ZFS Calamares configuration: $ZFS_SETTINGS"

[ -f "$ACTIVE_PARTITION_CONF" ] \
    || die "missing default partition configuration: $ACTIVE_PARTITION_CONF"

[ -f "$ZFS_PARTITION_CONF" ] \
    || die "missing ZFS partition configuration: $ZFS_PARTITION_CONF"

[ -f "$GRUB_ZFS_CONF" ] \
    || die "missing ZFS GRUB configuration: $GRUB_ZFS_CONF"

[ -f "$OPENZFS_CONF" ] \
    || die "missing OpenZFS configuration: $OPENZFS_CONF"


cleanup()
{
    #
    # zfs.conf is always temporary.
    #
    rm -f "$ACTIVE_ZFS_CONF"

    #
    # Restore the standard partition.conf when Advanced ZFS mode
    # temporarily replaced it.
    #
    if [ -n "$PARTITION_BACKUP" ] && [ -f "$PARTITION_BACKUP" ]; then
        install \
            -o root \
            -g root \
            -m 0644 \
            "$PARTITION_BACKUP" \
            "$ACTIVE_PARTITION_CONF"

        rm -f "$PARTITION_BACKUP"
    fi

    #
    # Restore the standard settings.conf when Advanced ZFS mode
    # temporarily replaced it.
    #
    if [ -n "$SETTINGS_BACKUP" ] && [ -f "$SETTINGS_BACKUP" ]; then
        install \
            -o root \
            -g root \
            -m 0644 \
            "$SETTINGS_BACKUP" \
            "$ACTIVE_SETTINGS"

        rm -f "$SETTINGS_BACKUP"
    fi
}

trap cleanup EXIT HUP INT TERM


case "$MODE" in
    grub)
        #
        # Normal installation.
        #
        # settings.conf remains untouched.
        # partition.conf remains untouched.
        # Only create the temporary GRUB-compatible zfs.conf.
        #

        install \
            -o root \
            -g root \
            -m 0644 \
            "$GRUB_ZFS_CONF" \
            "$ACTIVE_ZFS_CONF"

        grep -q -- "compatibility=grub2" "$ACTIVE_ZFS_CONF" \
            || die "generated zfs.conf does not contain compatibility=grub2"

        echo "Synex Calamares:"
        echo "  mode: Normal Installation"
        echo "  settings: $ACTIVE_SETTINGS"
        echo "  partition profile: $ACTIVE_PARTITION_CONF"
        echo "  ZFS profile: $GRUB_ZFS_CONF"
        ;;

    openzfs)
        #
        # Advanced ZFS installation.
        #
        # Preserve the normal settings.conf and partition.conf,
        # then temporarily replace them with the Advanced ZFS profiles.
        #

        SETTINGS_BACKUP="$(mktemp /run/synex-calamares-settings.XXXXXX)"
        PARTITION_BACKUP="$(mktemp /run/synex-calamares-partition.XXXXXX)"

        cp -a \
            "$ACTIVE_SETTINGS" \
            "$SETTINGS_BACKUP"

        cp -a \
            "$ACTIVE_PARTITION_CONF" \
            "$PARTITION_BACKUP"

        install \
            -o root \
            -g root \
            -m 0644 \
            "$ZFS_SETTINGS" \
            "$ACTIVE_SETTINGS"

        install \
            -o root \
            -g root \
            -m 0644 \
            "$ZFS_PARTITION_CONF" \
            "$ACTIVE_PARTITION_CONF"

        install \
            -o root \
            -g root \
            -m 0644 \
            "$OPENZFS_CONF" \
            "$ACTIVE_ZFS_CONF"

        #
        # Validate OpenZFS compatibility profile.
        #

        grep -q -- "compatibility=openzfs-2.3-linux" "$ACTIVE_ZFS_CONF" \
            || die "generated zfs.conf does not contain compatibility=openzfs-2.3-linux"

        #
        # Validate Advanced ZFS partition profile.
        #

        grep -Eq \
            '^[[:space:]]*defaultFileSystemType:[[:space:]]*"zfs"[[:space:]]*$' \
            "$ACTIVE_PARTITION_CONF" \
            || die "Advanced ZFS partition profile does not set ZFS as default filesystem"

        grep -Eq \
            '^[[:space:]]*availableFileSystemTypes:[[:space:]]*\["zfs"\][[:space:]]*$' \
            "$ACTIVE_PARTITION_CONF" \
            || die "Advanced ZFS partition profile is not restricted to ZFS"

        grep -Eq \
            '^[[:space:]]*zfs:[[:space:]]*true[[:space:]]*$' \
            "$ACTIVE_PARTITION_CONF" \
            || die "Advanced ZFS partition profile does not enable ZFS"

        grep -Eq \
            '^[[:space:]]*allowZfsEncryption:[[:space:]]*true[[:space:]]*$' \
            "$ACTIVE_PARTITION_CONF" \
            || die "Advanced ZFS partition profile does not allow ZFS native encryption"

        #
        # Safety check: Advanced ZFS mode must not execute GRUB
        # installation jobs.
        #

        if grep -Eq '^[[:space:]]*-[[:space:]]+bootloader-config[[:space:]]*$' \
            "$ACTIVE_SETTINGS"; then
            die "Advanced ZFS settings unexpectedly contain bootloader-config"
        fi

        if grep -Eq '^[[:space:]]*-[[:space:]]+grubcfg[[:space:]]*$' \
            "$ACTIVE_SETTINGS"; then
            die "Advanced ZFS settings unexpectedly contain grubcfg"
        fi

        if grep -Eq '^[[:space:]]*-[[:space:]]+bootloader[[:space:]]*$' \
            "$ACTIVE_SETTINGS"; then
            die "Advanced ZFS settings unexpectedly contain bootloader"
        fi

        echo "Synex Calamares:"
        echo "  mode: Advanced ZFS Installation"
        echo "  settings: $ZFS_SETTINGS"
        echo "  partition profile: $ZFS_PARTITION_CONF"
        echo "  ZFS profile: $OPENZFS_CONF"
        ;;

    *)
        die "invalid mode: $MODE"
        ;;
esac


if calamares -d; then
    RC=0
else
    RC=$?
fi

exit "$RC"
