# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: Copyright 2024 SUSE LLC
# SPDX-FileCopyrightText: Copyright 2024 Richard Brown

mig_dir=/var/lib/tik/mig
snap_dir=homebk
home_size=0
tik_stick_size=0
if [ ! -d ${mig_dir} ]; then
    prun /usr/bin/mkdir -p ${mig_dir}
fi

if [ ! -z "$(ls -A ${mig_dir})" ]; then
    log "[mig] existing backup found"
    d_opt --question --no-wrap --cancel-label="No, Delete Backup" --title="Existing user backup detected" --text="These users can be restored to the new installation\n\nWould you like to use this backup?"
    oldbackupyn=$?
    log "[mig] [oldbackupyn][${oldbackupyn}]"
    if [ "${oldbackupyn}" == 0 ]; then
        skipbackup=1
        migrate=1
        log "[mig] backup skipped, migration will use existing backup"
    else
        prun-opt /usr/sbin/btrfs property set -f -ts ${mig_dir}/${snap_dir} ro false
        for subsubvol in $(prun-opt /usr/sbin/btrfs subvolume list -o ${mig_dir}/${snap_dir} --sort=path | rev | cut -f1 -d' ' | rev | sed "s/^@//"); do
            prun /usr/sbin/btrfs subvolume delete ${subsubvol}
        done
        prun-opt /usr/sbin/btrfs subvolume delete ${mig_dir}/${snap_dir}
        prun-opt /usr/bin/rm ${mig_dir}/*.out
        prun-opt /usr/bin/rm ${mig_dir}/system-connections/*
        prun-opt /usr/bin/rmdir ${mig_dir}/system-connections
        prun-opt /usr/bin/rm ${mig_dir}/users/*
        prun-opt /usr/bin/rmdir ${mig_dir}/users
        prun-opt /usr/bin/rm ${mig_dir}/icons/*
        prun-opt /usr/bin/rmdir ${mig_dir}/icons
        prun-opt /usr/bin/rm ${mig_dir}/localtime
        prun-opt /usr/bin/rm ${mig_dir}/subgid
        prun-opt /usr/bin/rm ${mig_dir}/subuid
        prun-opt /usr/bin/rm ${mig_dir}/bluetooth/*
        prun-opt /usr/bin/rmdir ${mig_dir}/bluetooth
        prun-opt /usr/bin/rm ${mig_dir}/openvpn/*
        prun-opt /usr/bin/rmdir ${mig_dir}/openvpn
        prun-opt /usr/bin/rm -R ${mig_dir}/fprint/*
        prun-opt /usr/bin/rmdir ${mig_dir}/fprint
        prun-opt /usr/bin/rmdir ${mig_dir}/mnt
    fi
fi

get_disk

if [ -z "${skipbackup}" ]; then
    # Mount the existing system
    tik_target_mount "tik_old_root" "optional"
    case "$?" in
        0) ;;
        *)
            log "[mig] no migratable system found, skipping migration"
            migrate=0
            return 0
            ;;
    esac

    # Determine whether migration is feasible by checking /home size
    if [ -d "${TIK_ROOT_MNT}/home" ]; then
        # If /home is btrfs, run quota rescan and check qgroup usage.
        # Quotas may not be enabled, so qgroup show can fail. Fall back to du in that case.
        prun-opt /usr/sbin/btrfs quota show "${TIK_ROOT_MNT}/home" >/dev/null 2>&1
        if [ "${retval}" -eq 0 ]; then
            tik_progress_step "Scanning existing /home (btrfs quotas)" 10
            prun-opt /usr/sbin/btrfs quota rescan -w "${TIK_ROOT_MNT}/home" >/dev/null 2>&1
            if [ "${retval}" -eq 0 ]; then
                home_size="$(prun-opt /usr/sbin/btrfs qgroup show --raw -f "${TIK_ROOT_MNT}/home" | awk 'NR==2{print $2}')"
            fi
        else
            home_size=""
        fi

        if [ -z "${home_size}" ] || [ "${home_size}" = "0" ]; then
            log "[mig] btrfs quotas not enabled (or qgroup size unavailable), falling back to du -sb for /home size"
            tik_progress_step "Scanning existing /home size" 15
            home_size="$(prun /usr/bin/du -sb "${TIK_ROOT_MNT}/home" 2>/dev/null | awk '{print $1}')"
        fi

        tik_progress_step "Checking available space" 25
        tik_stick_size=$(prun /usr/sbin/btrfs fi usage --raw ${mig_dir} | grep estimated | awk '{print $3}')
        if [ -n "${home_size}" ] && [ -n "${tik_stick_size}" ]; then
            if [ "${home_size}" -gt "${tik_stick_size}" ]; then
                # Not enough space to offer migration
                migrate=0
            fi
            if [ "${home_size}" -le 16384 ]; then
                # /home subvolume is empty
                migrate=0
            fi
        else
            log "[mig] could not determine /home size or stick size reliably, migration disabled"
            migrate=0
        fi

        # partition found, /home found, no known reason to not migrate, so ask the user
        if [ -z "${migrate}" ]; then
            d_opt --question --no-wrap --title="Backup users from the existing install?" --text="These users will be restored to the new installation."
            migrateyn=$?
            if [ "${migrateyn}" == 0 ]; then
                migrate=1
            else
                migrate=0
            fi
        fi
    else
        log "[mig] no /home found on mounted system, migration disabled"
        migrate=0
    fi

    if [ "${migrate}" == 1 ]; then
        # We're migrating, lets go!
        # Check for existing snapshot from interrupted backup and delete if it exists boo#1224824
        tik_progress_step "Preparing /home snapshot" 35
        if [ -d "${TIK_ROOT_MNT}/home/${snap_dir}" ]; then
            prun /usr/sbin/btrfs subvolume delete "${TIK_ROOT_MNT}/home/${snap_dir}"
        fi
        prun /usr/sbin/btrfs subvolume snapshot -r "${TIK_ROOT_MNT}/home" "${TIK_ROOT_MNT}/home/${snap_dir}"

        tik_progress_step "Backing up /home" 45
        (prun /usr/sbin/btrfs send "${TIK_ROOT_MNT}/home/${snap_dir}" | pv -f -F "# %b copied in %t %r" | prun /usr/sbin/btrfs receive ${mig_dir}) 2>&1 >/dev/null

        tik_progress_step "Cleaning up snapshot" 55
        prun /usr/sbin/btrfs subvolume delete "${TIK_ROOT_MNT}/home/${snap_dir}"

        # Probe for subvolumes nested beneath /home and back them up also
        if (prun-opt /usr/sbin/btrfs subvolume list -o "${TIK_ROOT_MNT}/home" | grep -q "ID "); then
            prun /usr/sbin/btrfs property set -f -ts ${mig_dir}/${snap_dir} ro false
            for subsubvol in $(prun-opt /usr/sbin/btrfs subvolume list -o "${TIK_ROOT_MNT}/home" --sort=path | rev | cut -f1 -d' ' | rev | sed 's/^@\/home//'); do
                subsubvolname=$(basename $subsubvol)
                subsubdirname=$(dirname $subsubvol)
                prun /usr/sbin/btrfs subvolume snapshot -r "${TIK_ROOT_MNT}/home/${subsubvol}" "${TIK_ROOT_MNT}/home/${subsubvolname}"

                tik_progress_step "Backing up containers" 65
                (prun /usr/sbin/btrfs send "${TIK_ROOT_MNT}/home/${subsubvolname}" | pv -f -F "# %b copied in %t %r" | prun /usr/sbin/btrfs receive ${mig_dir}/${snap_dir}/${subsubdirname}) 2>&1 >/dev/null

                prun /usr/sbin/btrfs subvolume delete "${TIK_ROOT_MNT}/home/${subsubvolname}"
            done
            prun /usr/sbin/btrfs property set -f -ts ${mig_dir}/${snap_dir} ro true
        fi

        tik_progress_step "Exporting user/account data" 80
        prun /usr/bin/awk -F'[/:]' '($3 >= 1000 && $3 != 65534)' "${TIK_ROOT_MNT}/etc/passwd" | prun /usr/bin/awk -F':' '{ $7="/bin/bash"; print };' OFS=':' | prun tee ${mig_dir}/passwd.out
        prun /usr/bin/awk -F'[/:]' '($3 >= 1000 && $3 != 65534 && $3 != 65533)' "${TIK_ROOT_MNT}/etc/group" | prun tee ${mig_dir}/group.out
        prun /usr/bin/awk -F'[/:]' '{if ($3 >= 1000 && $3 != 65534) print $1}' "${TIK_ROOT_MNT}/etc/passwd" | prun /usr/bin/grep -f - "${TIK_ROOT_MNT}/etc/shadow" | prun tee ${mig_dir}/shadow.out
        prun /usr/bin/cp -a "${TIK_ROOT_MNT}/etc/subuid" ${mig_dir}/subuid
        prun /usr/bin/cp -a "${TIK_ROOT_MNT}/etc/subgid" ${mig_dir}/subgid
        # It's not guaranteed that the system will have existing network configs, custom localtime or AccountsService
        prun-opt /usr/bin/cp -a "${TIK_ROOT_MNT}/etc/NetworkManager/system-connections" ${mig_dir}/system-connections
        prun-opt /usr/bin/cp -a "${TIK_ROOT_MNT}/etc/localtime" ${mig_dir}/localtime
        prun-opt /usr/bin/cp -a "${TIK_ROOT_MNT}/var/lib/AccountsService/users" ${mig_dir}/users
        prun-opt /usr/bin/chmod 744 ${mig_dir}/users
        prun-opt /usr/bin/cp -a "${TIK_ROOT_MNT}/var/lib/AccountsService/icons" ${mig_dir}/icons
        prun-opt /usr/bin/cp -a "${TIK_ROOT_MNT}/var/lib/bluetooth" ${mig_dir}/bluetooth
        prun-opt /usr/bin/cp -a "${TIK_ROOT_MNT}/var/lib/fprint" ${mig_dir}/fprint
        prun-opt /usr/bin/cp -a "${TIK_ROOT_MNT}/etc/openvpn" ${mig_dir}/openvpn

        tik_progress_step "Migration backup prepared" 100
    fi
fi
