#!/bin/bash

# do not exit if a step fails
set +e

# Defaults
#PIDDIR=/var/run/persistence-elive
#persistence-elivePID=$PIDDIR/persistence-elive.pid
#DESC="Configure persistence-elive"
SCRIPTNAME=/etc/init.d/persistence-elive


# oly if we are bash (not sh)
SOURCE="$0"
source /usr/lib/elive-tools/functions
EL_REPORTS="1"

# Reads config file (will override defaults above)
[ -r /etc/default/persistence-elive.sh ] && . /etc/default/persistence-elive.sh

. /lib/lsb/init-functions

_CMDLINE="$(cat /proc/cmdline)"

# determine the mount version
if grep -qsE "(^7\.|wheezy)" /etc/debian_version || grep -Fqs "union=aufs" /proc/cmdline ; then
    LIVE_MOUNT_MAIN_d="/lib/live/mount"
    LIVE_UNION_SUBDIR_v=""
else
    LIVE_MOUNT_MAIN_d="/run/live"
    LIVE_UNION_SUBDIR_v="/rw"
fi

exit_ok(){
    # mark done for systemd
    echo "$(basename $0)" >> /tmp/.live-processes-finished

    exit 0
}

mount_nopersistence_saved_configurations(){
    # XXX important: this function has a same one in drivers-install so both they should be updated similar
    mountpoint_medium="$LIVE_MOUNT_MAIN_d/medium"
    # XXX: this file is only used when USB (img) mode, otherwise we fallback to the EFI partition for this
    persistent_image_confs="$mountpoint_medium/live/elive-live-saved-configurations.img"

    mountpoint_changes="/mnt/persistent_image_confs"
    mountpoint_changes_commit="$mountpoint_changes/persistent"

    mkdir -p "$mountpoint_changes"

    # USB mode (.img, not hybrid)
    if LC_ALL=C grep -qs "^/dev/.*$mountpoint_medium vfat " /proc/mounts \
        && [[ -e "$persistent_image_confs" ]] ; then
                #el_debug "Elive running in USB mode (img)"
        mkdir -p "$mountpoint_changes"

        # remount usb partition in RW
        mount -o remount -o rw "$mountpoint_medium"
        # mount persistence image
        mount -o rw "$persistent_image_confs" "$mountpoint_changes"
        #log_progress_msg "savings mounted in IMG mode on $mountpoint_changes"

    # hybrid image mode (iso9660 cdrom/dvd bootable)
    elif LC_ALL=C grep -qs "^/dev/.*$mountpoint_medium iso9660 " /proc/mounts ; then
        #el_debug "Elive running in Hybrid mode (iso)"
        mkdir -p "$mountpoint_changes"

        mountpoint_partition="$( LC_ALL=C grep "^/dev/.*$mountpoint_medium iso9660 " /proc/mounts | awk '{print $1}' | tail -1 )"
        mountpoint_partition="${mountpoint_partition%%[0-9]*}"
        if blkid -o export "${mountpoint_partition}1" | grep -qsi "TYPE=vfat" ; then
            mountpoint_partition="${mountpoint_partition}1"
        elif blkid -o export "${mountpoint_partition}2" | grep -qsi "TYPE=vfat" ; then
            mountpoint_partition="${mountpoint_partition}2"
        elif blkid -o export "${mountpoint_partition}3" | grep -qsi "TYPE=vfat" ; then
            mountpoint_partition="${mountpoint_partition}3"
        elif blkid -o export "${mountpoint_partition}4" | grep -qsi "TYPE=vfat" ; then
            mountpoint_partition="${mountpoint_partition}4"
        elif blkid -o export "${mountpoint_partition}" | grep -qsi "TYPE=vfat" ; then
            mountpoint_partition="${mountpoint_partition}"
        fi

        if [[ -b "$mountpoint_partition" ]] ; then
            # this can fail if we are using a cdrom media instead of a USB, but it doesn't matter because we will check if we were able to mount it later
            if mount -o rw "$mountpoint_partition" "$mountpoint_changes" 2>/dev/null ; then
                log_progress_msg "savings mounted in Hybrid image mode on $mountpoint_changes"
                # delete windows useless trash
                rm -rf "$mountpoint_changes/System Volume Information" 2>/dev/null || true
            else
                log_progress_msg "unable to save configurations: PLEASE RECORD YOUR USB using the tools suggested on the Elive website. You can also try using Persistence mode."
            fi
        fi
    fi
}


do_start(){

    # note: soft-persistence mode (small image with special confs) is now moved to drivers-install which is needed to run first
    if ! echo "${_CMDLINE}" | grep -qsE "(boot=live|persistence)" ; then
        exit 0
    fi

    # make sure that the working console reads and outputs things correctly (otherwise tab not works on dialog's unless we do a "login" or "getty")
    #exec 0</dev/console 1>/dev/console 2>&1


    # disabling unneeded daemons that bloats the filesystem disk usage, and we don't want to! no matter what
    if echo "${_CMDLINE}" | grep -qs "persistence" ; then
        systemctl --quiet stop     systemd-journald.service systemd-journald.socket systemd-journald-audit.socket systemd-journald-dev-log.socket || true
        # note: os-prober requires journald-dev-log

        # delete the daemon at stop or it will block (slower) the shutdown
        systemctl --quiet stop syslog.socket rsyslog.service 2>/dev/null || true
        systemctl --quiet disable rsyslog 2>/dev/null || true

        service rsyslog stop 2>/dev/null || true
        rm -f /etc/rc*.d/*rsyslog || true

        find /var/log/ -type f -delete || true
        rm -rf /var/log/journal/* || true
    fi

    #service fail2ban stop




    #
    # Restore things:
    #

    # exit if is our first-time persistence boot (restoring things are not needed)
    if ! [[ -s "/etc/default/persistence-elive.sh" ]] ; then
        exit 0
    fi

    if echo "${_CMDLINE}" | grep -Fq debug ; then
        set -x
    fi

    source "/etc/default/persistence-elive.sh"
    if [[ "${counter_times_persistence_booted}" -eq 0 ]] ; then
        exit 0
    fi


    log_daemon_msg "Configuring Persistence"



    #
    # detect persistence partition
    #

    # determine the mount version
    if grep -qsE "(^7\.|wheezy)" /etc/debian_version ; then
        LIVE_MOUNT_MAIN_d="/lib/live/mount"
    else
        LIVE_MOUNT_MAIN_d="/run/live"
    fi

    # get the partiton where the live system is mounted
    medium_part="$( cat /proc/mounts | grep "^/dev/.*${LIVE_MOUNT_MAIN_d}/medium" | awk '{print $1}' | grep -Fv "/dev/mapper/" | tail -1 )"
    if [[ ! -b "$medium_part" ]] ; then
        # this is like a strange buggy useless remount that happens here, replacing the previous one
        if ls $LIVE_MOUNT_MAIN_d/persistence/*/live/filesystem.*  1>/dev/null 2>&1 ; then
            medium_part="$( ls $LIVE_MOUNT_MAIN_d/persistence/*/live/filesystem.* | sed -e 's|/live/filesystem\..*$||g' | sort -u | head -1 )"
            medium_part="$( cat /proc/mounts | grep -F "${medium_part}" | awk '{print $1}' | tail -1 )"
        fi
        if [[ ! -b "$medium_part" ]] ; then
            medium_part="$( cat /proc/mounts | grep "^/dev/.*${LIVE_MOUNT_MAIN_d}/persistence/sd.3" | awk '{print $1}' | grep -Fv "/dev/mapper/" | tail -1 )"
            if [[ ! -b "$medium_part" ]] ; then
                medium_part="$( cat /proc/mounts | grep "^/dev/.*${LIVE_MOUNT_MAIN_d}/persistence/sd.2" | awk '{print $1}' | grep -Fv "/dev/mapper/" | tail -1 )"
                if [[ ! -b "$medium_part" ]] ; then
                    medium_part="$( cat /proc/mounts | grep "^/dev/.*${LIVE_MOUNT_MAIN_d}/persistence/sd.1" | awk '{print $1}' | grep -Fv "/dev/mapper/" | tail -1 )"
                    if [[ ! -b "$medium_part" ]] ; then
                        medium_part="$( cat /proc/mounts | grep "^/dev/.*${LIVE_MOUNT_MAIN_d}/persistence/sd.4" | awk '{print $1}' | grep -Fv "/dev/mapper/" | tail -1 )"
                        if [[ ! -b "$medium_part" ]] ; then
                            medium_part="$( cat /proc/mounts | grep "^/dev/.*${LIVE_MOUNT_MAIN_d}/persistence/sd.5" | awk '{print $1}' | grep -Fv "/dev/mapper/" | tail -1 )"
                            if [[ ! -b "$medium_part" ]] ; then
                                # nvme ?
                                medium_part="$( cat /proc/mounts | grep "^/dev/.*${LIVE_MOUNT_MAIN_d}/persistence/nvme" | awk '{print $1}' | grep -Fv "/dev/mapper/" | tail -1 )"
                                if [[ ! -b "$medium_part" ]] ; then
                                    medium_part="$( cat /proc/mounts | grep "^/dev/.*${LIVE_MOUNT_MAIN_d}/persistence/mmcblk" | awk '{print $1}' | grep -Fv "/dev/mapper/" | tail -1 )"
                                fi
                            fi
                        fi
                    fi
                fi
            fi
        fi
        # try to detect systems like /dev/mapper/ventoy that doesn't exist on /dev/mapper/ later
        if [[ ! -b "$medium_part" ]] ; then
            medium_part="$( cat /proc/mounts | grep "^/dev/.*${LIVE_MOUNT_MAIN_d}/medium" | awk '{print $1}' | tail -1 )"
            if [[ "$medium_part" = "/dev/mapper/"* ]] ; then
                medium_part="${medium_part#/dev/mapper/}"
                if [[ -n "$medium_part" ]] ; then
                    medium_part="$( NOREPORTS=1 EL_DEBUG=0 timeout 120 partitions-list --show-all 2>/dev/null | grep -i "$medium_part" | awk -v FS="::" '{print $1}' | tail -1 )"
                fi
            fi
        fi
    fi

    if [[ ! -b "$medium_part" ]] ; then
        el_error "unable to get of partition of live 'medium': $( cat /proc/mounts | grep -F persistence ) ;;; $( NOREPORTS=1 EL_DEBUG=0 timeout 120 partitions-list --show-all --show-all-raw )"
        unset medium_part
    fi

    if [[ "$medium_part" = "/dev/nvme"* ]] || [[ "$medium_part" = "/dev/mmcblk"* ]] ; then
        medium_dev="${medium_part%%p[0-9]*}"
    else
        medium_dev="${medium_part%%[0-9]*}"
    fi
    # medium_part_fs="$( NOREPORTS=1 EL_DEBUG=0 timeout 120 partitions-list --show-only="$medium_part" | awk -v FS="::" '{print $3}' )"

    # by knowing the disk of the live system we can know from where comes our persistence partition
    persistence_partition="$( NOREPORTS=1 EL_DEBUG=0 timeout 120 partitions-list --show-all --show-all-raw 2>/dev/null | grep -E "^/.*/${medium_dev##*/}.*::(persistence)::" | awk -v FS="::" '{print $1}' | tail -1 )"
    if [[ -n "$persistence_partition" ]] ; then
        persistence_mountpoint="$( mounts-manager --get-mountpoint "$persistence_partition" 2>/dev/null )"

        if [[ -z "$persistence_mountpoint" ]] ; then
            persistence_partition="$( cat /proc/mounts | grep -E "^/dev/.*${LIVE_MOUNT_MAIN_d}/persistence/${persistence_partition##*/}" | awk '{print $1}' )"
            persistence_mountpoint="$( mounts-manager --get-mountpoint "$persistence_partition" 2>/dev/null )"
        fi
    fi

    #if [[ -z "$persistence_mountpoint" ]] ; then
        #persistence_partition="$( cat /proc/mounts | grep -E "/persistence/${persistence_partition##*/}\s+" | awk '{print $1}' )"
        #persistence_mountpoint="$( NOREPORTS=1 mounts-manager --get-mountpoint "$persistence_partition" 2>/dev/null )"
    #fi

    # checks and fix:
    if ! [[ -b "${persistence_partition}" ]] || ! [[ -d "${persistence_mountpoint}" ]] ; then
        # debug:

        el_error "persistence partition '${persistence_partition}' or persistence mountpoint '${persistence_mountpoint}' not obtained correctly, falling back to a different method...: debug:\n
        $(
            echo -e "Medium is: $medium_dev - medium part is $medium_part \n${LIVE_MOUNT_MAIN_d} \nPartitions list is:\n" ;
            NOREPORTS=1 EL_DEBUG=0 timeout 120 partitions-list --show-all --show-all-raw 2>&1  ;
            echo -e "/proc/mounts is:\n" ;
            cat /proc/mounts | grep "${LIVE_MOUNT_MAIN_d}" ;
        )"
        persistence_partition="$( cat /proc/mounts | grep "^/dev/.*${LIVE_MOUNT_MAIN_d}/persistence/" | grep -vE "\s+vfat\s+" | awk '{print $1}' | tail -1 )"
        persistence_mountpoint="$( cat /proc/mounts | grep "^/dev/.*${LIVE_MOUNT_MAIN_d}/persistence/" | grep -vE "\s+vfat\s+" | awk '{print $2}' | tail -1 )"
    fi


    # add the subdir needed for overlayfs:
    if [[ -d "$persistence_mountpoint" ]] && [[ -d "${persistence_mountpoint}${LIVE_UNION_SUBDIR_v}" ]] ; then
        persistence_mountpoint="${persistence_mountpoint}${LIVE_UNION_SUBDIR_v}"
    fi

    # remount with better options
    if grep -qsE "^${persistence_partition}\s+.*\s+(reiserfs)\s+" /proc/mounts ; then
        # seems like aufs doesn't knows / accepts commit= value
        mount -o remount -o nodiratime -o notail "${persistence_partition}"
    else
        mount -o remount -o nodiratime "${persistence_partition}"
    fi

    log_progress_msg "detected in ${persistence_partition}"


    #
    # remove temporal data like cache's or apt if we need free space
    #
    # clean some useles files if we need free space
    if [[ -b "$persistence_partition" ]] ; then
        # in bytes
        persistence_space_free="$( LC_ALL=C df -m | grep -E "^${persistence_partition}\s+" | awk '{print $4}' | tail -1 )"

        if echo "$persistence_space_free" | grep -qs "^[[:digit:]]" ; then
            # mark a state, useful for elive-upgrader
            echo "$persistence_space_free" > /tmp/.persistence-space-free-at-boot
        else
            el_warning "unable to determine free space for persistence partition"
            exit_ok
        fi

        # if we have less than 1GB free
        if [[ -n "$persistence_mountpoint" ]] && [[ -d "$persistence_mountpoint" ]] ; then

            if [[ -n "$persistence_space_free" ]] ; then
                if [[ "${persistence_space_free}" -lt "1500" ]] ; then
                    #log_progress_msg "Removing temporary data to improve persistence free space"

                    rm -rf "${persistence_mountpoint}"/home/*/.cache
                    rm -rf "${persistence_mountpoint}"/home/*/.local/share/Trash
                    # /var/lib/apt/lists/ (apt-get update, 53M)
                    # /var/cache/apt-xapian-index  (some index stuff like apt-get update, 72 MB)
                    # /var/cache/apt/archives/*deb (deb downloaded files)
                    # /var/cache/apt/*.bin (some caches, 43 MB)
                    rm -rf "${persistence_mountpoint}"/var/lib/apt/lists/*
                    rm -rf "${persistence_mountpoint}"/var/cache/apt-xapian-index
                    # note needed because we also apt-get clean:
                    #rm -rf "${persistence_mountpoint}"/var/cache/apt/archives/*deb
                    rm -rf "${persistence_mountpoint}"/var/cache/apt/*.bin
                    rm -rf "${persistence_mountpoint}"/var/log/*
                fi

                if [[ "${persistence_space_free}" -lt "800" ]] ; then
                    rm -rf "${persistence_mountpoint}"/var/cache/apt
                    mkdir -p "${persistence_mountpoint}"/var/cache/apt/archives/partial
                fi

                # restore original states
                find "$persistence_mountpoint/var/lib/apt/lists/" -type c -delete 2>/dev/null || true
                find "$persistence_mountpoint/var/cache/apt/" -type c -delete 2>/dev/null || true
                find "$persistence_mountpoint/var/cache/apt-xapian-index/" -type c -delete 2>/dev/null || true

            else
                el_error "persistence_space_free unset"
            fi
        fi
    fi

    # recover apt original states which doesn't use memory
    if [[ -d "$persistence_mountpoint" ]] ; then
        # always delete downloaded packages, we need this to restore the saved cached debs, like for install nvidia drivers on-demand and not download them, and also it cleans up space
        # recover cached packages, we need always the ones provided by elive and this doesn't takes space

        # remove user-installed packages
        TERM=linux apt-get clean

        # restore files back to original live mode:
        # update: overlayfs mode (not aufs)
        #rm -f "$persistence_mountpoint/var/cache/apt/archives/"*.deb 2>/dev/null || true
        #rm -f "$persistence_mountpoint/var/cache/apt/archives/".wh.*.deb 2>/dev/null || true
        find "$persistence_mountpoint/var/cache/apt/archives/" -type c -iname '*deb' -delete 2>/dev/null || true
        #find "$persistence_mountpoint/var/cache/apt/" -type c -iname '*'bin -delete 2>/dev/null || true

        #rm -f "$persistence_mountpoint/var/cache/apt/".wh.*.bin 2>/dev/null || true
        #find "$persistence_mountpoint/var/lib/apt/lists/" -type c -delete 2>/dev/null || true
        #find "$persistence_mountpoint/var/cache/apt-xapian-index" -type c -delete 2>/dev/null || true

        #rm -f "$persistence_mountpoint/var/lib/apt/lists/"*Packages* 2>/dev/null || true
        #rm -f "$persistence_mountpoint/var/lib/apt/lists/"*Source* 2>/dev/null || true
        #rm -f "$persistence_mountpoint/var/lib/apt/lists/"*Translation* 2>/dev/null || true
        #rm -f "$persistence_mountpoint/var/lib/apt/lists/"*Release* 2>/dev/null || true
        #rm -f "$persistence_mountpoint/var/lib/apt/lists/".wh.*Packages* 2>/dev/null || true
        #rm -f "$persistence_mountpoint/var/lib/apt/lists/".wh.*Source* 2>/dev/null || true
        #rm -f "$persistence_mountpoint/var/lib/apt/lists/".wh.*Translation* 2>/dev/null || true
        #rm -f "$persistence_mountpoint/var/lib/apt/lists/".wh.*Release* 2>/dev/null || true
        # update: this is meant to be maintained among our boots which is good, there's no reason to have it broken here
        #find "$persistence_mountpoint/var/lib/apt/lists/" -type c  -delete
    fi


    # re-use E configurations only for machine-ID's
    machine_id="$( el_get_machine_id )"
    if [[ -n "$machine_id" ]] ; then
        machine_id="#machine-id:${machine_id}"
        if command -v lshw >/dev/null ; then
            machine_id_friendly="$( lshw -class system | grep -E "^\s+(description|product):" | head -2 | sed -e 's|^.*: ||g' | tr '\n' ' ' ; echo )"
            log_progress_msg "machine ID is ${machine_id} (${machine_id_friendly})"
        else
            log_progress_msg "machine ID is ${machine_id}"
        fi
    else
        el_error "unable to get machine-id from el_get_machine_id: $( el_get_machine_id 2>&1 )"
        # echo -e "unable to get machine-id from el_get_machine_id: $( set -x ; el_get_machine_id 2>&1 )" >> /tmp/live-logs.txt
        machine_id="#machine-id:unknown"
    fi

    # restore system configurations for hardware-based profiles
    for config in \
        /var/lib/alsa/asound.state \
        $NULL
    do
        if [[ -n "$machine_id" ]] ; then
            if [[ -e "${config}${machine_id}" ]] ; then
                rm -rf "${config}" 2>/dev/null || true
                cp -a "${config}${machine_id}" "${config}"
            else
                # no machine id found, always let dynamic environments to be created
                rm -rf "${config}" 2>/dev/null || true
            fi
        else
            # no machine id found, always let dynamic environments to be created
            rm -rf "${config}" 2>/dev/null || true
        fi
    done

    # restore user's configurations
    for userdir in /home/*
    do
        [[ ! -d "${userdir}" ]] && continue
        [[ "${userdir}" = "/home/*" ]] && continue
        if ! grep -Fqs ":${userdir}:" /etc/passwd ; then
            continue
        fi

        # always cleanup these:
        rm -rf "${userdir}/.Xauthority"  2>/dev/null

        # forced ones (must be deleted, strict hardware conf)
        for config in \
            .e \
            .e16 \
            .conkyrc \
            .config/elive/elive-tools/%%usr%%bin%%elive-multiscreens_conf.sh \
            .config/elive/elive-tools/%%usr%%bin%%e_wrapper_conf.sh \
            .config/pulse \
            .asoundrc \
            .Xdefaults \
            .gconf/apps/gnome-volume-control \
            $NULL
        do

            if [[ -n "$machine_id" ]] ; then
                if [[ -e "${userdir}/${config}${machine_id}" ]] ; then
                    rm -rf "${userdir:?}/${config:?}" 2>/dev/null || true
                    # note: a file file owned by users stills owned by user when copied by root
                    cp -a "${userdir}/${config}${machine_id}" "${userdir}/${config}"
                    log_progress_msg "restored ${config}"
                else
                    # no conf found for this machine ID, always let dynamic environments be created
                    rm -rf "${userdir:?}/${config:?}" 2>/dev/null || true
                    su -c "cd ${userdir} ; EL_DEBUG=0 elive-skel upgrade '${config}' 1>/dev/null 2>&1" eliveuser
                    log_progress_msg "created new ${config}"
                fi
            else
                # no machine ID found, always let dynamic environments be created
                rm -rf "${userdir:?}/${config:?}" 2>/dev/null || true
                su -c "cd ${userdir} ; EL_DEBUG=0 elive-skel upgrade '${config}' 1>/dev/null 2>&1" eliveuser
                log_progress_msg "NO MACHINE-ID FOUND, created new ${config}"
            fi
        done
        # optional ones (dont delete, but use a backup if we have)
        for config in \
            .config/vokoscreen/vokoscreen.conf \
            $NULL
        do

            if [[ -n "$machine_id" ]] ; then
                if [[ -e "${userdir}/${config}${machine_id}" ]] ; then
                    rm -rf "${userdir:?}/${config:?}" 2>/dev/null || true
                    # note: a file owned by users remains owned by user when copied by root
                    cp -a "${userdir}/${config}${machine_id}" "${userdir}/${config}"
                fi
            fi
        done
    done
            #.config/user-dirs.dirs \
            #.config/user-dirs.locale \

    # this dir should not exist
    rm -fr /home/*/.pulse 1>/dev/null 2>&1 || true


    # keep a track of the original version of the OS before persistence:
    if [[ -s "/etc/default/persistence-elive.sh" ]] ; then
        if [[ -s "/etc/elive-version-persistence" ]] ; then
            if [[ "$( grep -F "elive-version:" /etc/elive-version-persistence )" != "$( grep -F "elive-version:" /etc/elive-version )" ]] ; then
                #el_warning "ISO has been updated on the USB (ventoy?) at the same time there was a persistence used, we should probably remove many OS files the user may have updated / installed like /usr or /var in order to keep a clean environment"
                # system needs to be restored:
                if [[ -d "${persistence_mountpoint%%rw}rw-backup" ]] ; then
                    # stop plymouth to see messages
                    #plymouth --ping 1>/dev/null 2>&1  && plymouth --hide-splash && chvt 1

                    log_progress_msg "OS version is newer than when Persistence was created, restoring state..."

                    rsync -a --delete \
                        --exclude="/etc" \
                        --exclude="/home" \
                        --exclude="/nix" \
                        --exclude="/opt" \
                        --exclude="/root" \
                        --exclude="/snap" \
                        --exclude="/srv" \
                        --exclude="/usr/local" \
                        --exclude="/var/lib/flatpak" \
                        --exclude="/var/lib/mysql" \
                        --exclude="/var/www" \
                        "${persistence_mountpoint%%rw}rw-backup/" "${persistence_mountpoint%%/}/"

                    # always create new user ?
                    # Update: no, normal users will have everything in eliveuser
                    #rm -rf "${persistence_mountpoint}/home/eliveuser"

                    sync
                    log_progress_msg "Rebooting computer in 5..."
                    sleep 1
                    log_progress_msg "Rebooting computer in 4..."
                    sleep 1
                    log_progress_msg "Rebooting computer in 3..."
                    sleep 1
                    log_progress_msg "Rebooting computer in 2..."
                    sleep 1
                    log_progress_msg "Rebooting computer in 1..."

                    reboot

                fi
            fi
        else
            grep -F "elive-version:" /etc/elive-version > /etc/elive-version-persistence
        fi
    fi


    #
    # Fixes for compatibility among different machines
    #
    #for file in /etc/adjtime /etc/blkid.tab
    #do
        #rm -rf "${persistence_mountpoint}/${file}" 2>/dev/null || true
    #done

    # do not remember clock settings
    # update: i dont see a reason to not remember these settings, so i will leave the code commented
    #rm -rf "${persistence_mountpoint}"/etc/adjtime
    #rm -rf "${persistence_mountpoint}"/etc/localtime
    #rm -rf "${persistence_mountpoint}"/etc/timezone
    #rm -rf "${persistence_mountpoint}"/etc/elive-tools/languagedetection

    # do not remember disks/partitions
    rm -rf "${persistence_mountpoint}"/etc/blkid.tab

    # do not remember language configurations
    #rm -rf "${persistence_mountpoint}"/etc/console-setup

    # hardware based & drivers cleanups
    rm -rf "${persistence_mountpoint}"/etc/urfkill
    # note: nvidia/flgrx takes already care of these, so not remove them:
    #rm -rf "${persistence_mountpoint}"/etc/X11
    # should be not needed but just in case?
    #rm -rf "${persistence_mountpoint}"/home/*/.cache/evas*
    # TODO: verify that we don't have after to uninstall nvidia drivers:
    #           and include them in the unistall scripts of nvidia/fglrx
    #./etc/X11/xorg.conf.d/20-nvidia.conf
    #./etc/modprobe.d/nvidia-blacklists-nouveau.conf
    #./etc/modprobe.d/nvidia.conf
    #./etc/modprobe.d/nvidia-kernel-common.conf
    #./etc/init.d/nvidia-kernel
    #   TODO: just do a "buscar nvidia" in the persistence overlay!

    #rm -rf "${persistence_mountpoint}"/etc/
    #rm -rf "${persistence_mountpoint}"/etc/
    #rm -rf "${persistence_mountpoint}"/etc/
    #rm -rf "${persistence_mountpoint}"/etc/


    # uninstall drivers if we don't need them
    # Update: moved to the correct drivers-install step
    # nvidia
    #if nvidia-privative-drivers-install -d ; then
        #if ! nvidia-privative-drivers-install -t ; then
            ## we have nvidia hardware, but our driver not works, uninstall
            ## a new installation will be asked later (of a different driver to use)
            #log_daemon_msg "Nvidia: uninstalling driver: not the correct version for this machine"
            #nvidia-privative-drivers-install -a -f -u
        #fi

    #else
        ## we don't have the hardware at all, uninstall driver
        #log_daemon_msg "Nvidia: uninstalling driver: this machine doesn't has it"
        #nvidia-privative-drivers-install -a -f -u
    #fi

    ## fglrx
    #if fglrx-privative-drivers-install -d ; then
        #if ! fglrx-privative-drivers-install -t ; then
            ## we have fglrx hardware, but our driver not works, uninstall
            ## a new installation will be asked later (of a different driver to use)
            #log_daemon_msg "ATI fglrx: uninstalling driver: not the correct version for this machine"
            #fglrx-privative-drivers-install -a -f -u
        #fi

    #else
        ## we don't have the hardware at all, uninstall driver
        #log_daemon_msg "ATI fglrx: uninstalling driver: this machine doesn't has it"
        #fglrx-privative-drivers-install -a -f -u
    #fi




    # turn off debugging if we have finished
    if echo "${_CMDLINE}" | grep -Fq debug ; then
        set +x
    fi

    #log_progress_msg "Persistence for Elive"
    true
    #log_end_msg 0

    # make sure to add the mark in systemd
    exit_ok
}

do_stop(){
    log_daemon_msg "Saving Persistence"
    log_progress_msg "saving configurations..."

    if ! echo "${_CMDLINE}" | grep -Fqs "boot=live" ; then
        exit
    fi

    # this is needed in order to make the system boot "waiting for a connection" work correctly, otherwise it will not connect during drivers-install
    # allow network to be used for any user by default, this solves a small issue where after install there was no network
    sed -i -e '/^permissions=/d' "/etc/NetworkManager/system-connections/"*  2>/dev/null || true
    # allow all interfaces (wifi device names can change)
    sed -i -e '/^interface-name=/d' "/etc/NetworkManager/system-connections/"*  2>/dev/null || true


    # save network configurations in no-persistence mode
    if ! [[ -s "/etc/default/persistence-elive.sh" ]] && ! [[ -e "/dev/mapper/ventoy" ]] ; then

        #log_progress_msg "soft mode"
        mount_nopersistence_saved_configurations

        # do we have our persistent confs mounted?
        if LC_ALL=C grep -qs " $mountpoint_changes .*rw," /proc/mounts ; then

            mkdir -p "$mountpoint_changes_commit"

            # save network configurations so they can be reused
            while read -ru 3 file
            do
                if [[ -s "$file" ]] ; then
                    #echo "$file" | cpio -padu --quiet "$mountpoint_changes_commit/" || rm -f "$mountpoint_changes_commit/${file#/}"
                    echo "$file" | cpio -padu --quiet "$mountpoint_changes_commit/" 2>/dev/null
                fi

            done 3<<< "$( find "/etc/NetworkManager/system-connections/" -type f 2>/dev/null )"


            # save language and keyboard preselected by default too
            #for file in /etc/default/locale /etc/default/keyboard
            #do
                #if [[ -s "$file" ]] ; then
                    #mkdir -p "${mountpoint_changes_commit}$( dirname "$file" )"
                    #cp "$file" "${mountpoint_changes_commit}${file}.saved"  || rm -f "$file" "${mountpoint_changes_commit}${file}.saved"
                    ##echo "$file" | cpio -padu --quiet "$mountpoint_changes_commit/" 2>/dev/null || rm -f "$mountpoint_changes_commit/${file#/}"
                #fi
            #done

            # save confs on elive-tools like geolocation fetching
            while read -ru 3 file
            do
                if [[ -s "$file" ]] ; then
                    #echo "$file" | cpio -padu --quiet "$mountpoint_changes_commit/" || rm -f "$mountpoint_changes_commit/${file#/}"
                    echo "$file" | cpio -padu --quiet "$mountpoint_changes_commit/" 2>/dev/null
                fi

            done 3<<< "$( find "/etc/elive-tools/" -type f )"
            # note: the previous copy already includes the geolocated location: "/etc/elive-tools/geolocation/livemode-location-fetched.txt"

            # remount in ro, just in case
            sync
            umount "$mountpoint_changes" || umount -f "$mountpoint_changes"
            rmdir "$mountpoint_changes"
            sync
            log_progress_msg "saved configurations to your USB"
            #mount -o remount -o ro "$mountpoint_medium"
            #sync
        fi
    fi


    #start-stop-daemon --stop --quiet --pidfile $persistence-elivePID
    # Wait a little and remove stale PID file
    #if [ -f $persistence-elivePID ] && ! ps h $(cat $persistence-elivePID) > /dev/null
    #then
        ## Stale PID file (persistence-elive was succesfully stopped),
        ## remove it (should be removed by persistence-elive itself IMHO.)
    #rm -f $persistence-elivePID
    #fi

    #
    # detect persistence partition
    #
    #medium_part="$( cat /proc/mounts | grep -E "/(mount|live)/medium" | awk '{print $1}' )"
    #if [[ -z "$medium_part" ]] ; then
        ## this is like a strange buggy useless remount that happens here, replacing the previous one
        #if ls $LIVE_MOUNT_MAIN_d/persistence/*/live/filesystem.*  1>/dev/null 2>&1 ; then
            #medium_part="$( ls $LIVE_MOUNT_MAIN_d/persistence/*/live/filesystem.* | sed -e 's|/live/filesystem\..*$||g' | sort -u | head -1 )"
            #medium_part="$( cat /proc/mounts | grep "${medium_part}" | awk '{print $1}' | tail -1 )"
        #fi
        #if [[ -z "$medium_part" ]] ; then
            #medium_part="$( cat /proc/mounts | grep "/mount/persistence/sd.2" | awk '{print $1}' | tail -1 )"
            #if [[ -z "$medium_part" ]] ; then
                #medium_part="$( cat /proc/mounts | grep "/mount/persistence/sd.1" | awk '{print $1}' | tail -1 )"
            #fi
        #fi
    #fi
    #medium_disk="${medium_part%%[0-9]*}"
    #persistence_partition="$( NOREPORTS=1 EL_DEBUG=0 timeout 120 partitions-list --show-all --show-all-raw | grep -E "^${medium_disk}.*::(persistence)::" | awk -v FS="::" '{print $1}' | tail -1 )"
    #persistence_mountpoint="$( NOREPORTS=1 mounts-manager --get-mountpoint "$persistence_partition" 2>/dev/null )"
    #if [[ -z "$persistence_mountpoint" ]] ; then
        #persistence_partition="$( cat /proc/mounts | grep -E "/persistence/${persistence_partition##*/}\s+" | awk '{print $1}' )"
        #persistence_mountpoint="$( NOREPORTS=1 mounts-manager --get-mountpoint "$persistence_partition" 2>/dev/null )"
    #fi


    #
    # Persistence mode
    #
    # simplest check to see if we are running or not from persistence, if we are not, we should not have this file:
    if ! [[ -s "/etc/default/persistence-elive.sh" ]] ; then
        # log_progress_msg "not persistence mode"
        return 0
    fi


    # XXX unfortunately seems like there's no way to obtain these mountpoints partitions because no matter what, the shutdown process umounts them (even if i try to set the in shutdown priority order), the only way -could- be running the stop from elive-pm instead of system as an option, but for now we don't need them and the normal shutdown correctly works with the other things
    #persistence_partition="$( cat /proc/mounts | grep "^/dev/.*${LIVE_MOUNT_MAIN_d}/persistence/" | grep -vE "\s+vfat\s+" | awk '{print $1}' | tail -1 )"
    #persistence_mountpoint="$( cat /proc/mounts | grep "^/dev/.*${LIVE_MOUNT_MAIN_d}/persistence/" | grep -vE "\s+vfat\s+" | awk '{print $2}' | tail -1 )"
    ## add the subdir needed for overlayfs:
    #if [[ -d "$persistence_mountpoint" ]] && [[ -d "${persistence_mountpoint}${LIVE_UNION_SUBDIR_v}" ]] ; then
        #persistence_mountpoint="${persistence_mountpoint}${LIVE_UNION_SUBDIR_v}"
    #fi



    # save hardware-based profiles
    machine_id="$( el_get_machine_id )"
    if [[ -n "$machine_id" ]] ; then
        machine_id="#machine-id:${machine_id}"
        log_progress_msg "machine id is ${machine_id}"
    else
        el_error "unable to get machine-id from el_get_machine_id: $( el_get_machine_id 2>&1 )"
        machine_id="#machine-id:unknown"
    fi

    # save system configurations for hardware-based profiles
    for config in \
        /var/lib/alsa/asound.state \
        $NULL
    do
        if [[ -n "$machine_id" ]] ; then
            if [[ -e "${config}" ]] ; then
                rm -rf "${config}${machine_id}" 2>/dev/null || true
                mv -f "${config}" "${config}${machine_id}"
            fi
        fi
    done

    # save user's configurations
    # note: this file exists since the first boot with persistence (already created partition), so we don't need to save the confs at shutdown since we already saved them in the creator tool
    for userdir in /home/*
    do
        [[ ! -d "${userdir}" ]] && continue
        [[ "${userdir}" = "/home/*" ]] && continue
        if ! grep -Fqs ":${userdir}:" /etc/passwd ; then
            continue
        fi

        # XXX: do not use a match that can be inside another match! (or just use the parent for all), ex.: .config/ vs .config/elive/
        # note: no need to create target directories since they exist (because the original file exists at the same place)
        # forced ones (originals must be deleted)
        # descriptions: .e needs things like GL configuration, .e16 has dedicated sized gadgets like the pagers, .conkyrc includes hardware based settings like network, multiscreens is hardware based, e_wrapper I don't remember, asoundrc requires hardware setting for alsa mode, Xdefaults includes dpi settings, volume control is also hardware based
        for config in \
            .e \
            .e16 \
            .conkyrc \
            .config/elive/elive-tools/%%usr%%bin%%elive-multiscreens_conf.sh \
            .config/elive/elive-tools/%%usr%%bin%%e_wrapper_conf.sh \
            .config/pulse \
            .asoundrc \
            .Xdefaults \
            .gconf/apps/gnome-volume-control \
            $NULL
        do

            # save confs per-machine based
            if [[ -n "$machine_id" ]] ; then
                # we really need to only save confs for IDs here, not deleting needs here
                if [[ -e "${userdir}/${config}" ]] ; then
                    rm -rf "${userdir:?}/${config:?}${machine_id:?}" 2>/dev/null || true
                    mv -f "${userdir}/${config}" "${userdir}/${config}${machine_id}"
                fi
            fi
        done
        # optional ones (just a copy)
        for config in \
            .config/vokoscreen/vokoscreen.conf \
            $NULL
        do

            if [[ -n "$machine_id" ]] ; then
                # we really need to only save confs for id's here, not deleting needs here
                if [[ -e "${userdir}/${config}" ]] ; then
                    rm -rf "${userdir:?}/${config:?}${machine_id:?}" 2>/dev/null || true
                    cp -a "${userdir}/${config}" "${userdir}/${config}${machine_id}"
                fi
            fi
        done
    done
    # do not save these per-hardware, because after the user has been created a first time we don't want to mess up renaming folders or creating new ones, just respecting the same ones, no matter which desktop
        #.config/user-dirs.dirs \
        #.config/user-dirs.locale \



    log_daemon_msg "Persistence Saved"
    log_progress_msg "done"

    sync ; LC_ALL=C sleep 1.0


    # umount it TODO: doesn't work because we cannot get the partition value in shutdown process
    #if [[ -b "$persistence_partition" ]] ; then
        #mounts-manager --umount "$persistence_partition"
        #cryptsetup luksClose "${persistence_partition##*/}_crypt" 2>/dev/null
        #cryptsetup luksClose "${persistence_partition##*/}" 2>/dev/null
    #fi

    log_progress_msg "Configurations Saved..."

    log_end_msg 0
}

case "$1" in
    "")
        echo "Error: persistence-elive should be called with the 'start' argument." >&2
        ;;
    start)
        do_start
        ;;
    stop)
        do_stop
        ;;
    restart|reload|force-reload)
        "$0" stop
        "$0" start
        ;;
    *)
        echo "Usage: persistence-elive [start|stop]" >&2
        exit 3
        ;;
esac

# vim: set filetype=sh :
