#!/bin/bash
# barium helper scripts
# author: rosalinux.ru: betcher

if [ -f $(dirname $0)/lib ] ;  then
    . $(dirname $0)/lib
else 
    . $(which lib) || exit 1
fi
CURPWD=$(pwd)

TMPD=""
MTMP=""

HLP (){
    echo "
Usage:
    $(basename $0) kernel-6.6-generic       - install alternate kernel from repo
    $(basename $0) ./kernel-6.6-generic.rpm - install from local rpm

Keys:
    -l | --ls | --list   - list of installed alternate kernels
    -r | --rm | --remove - remove kernel in interactive mode 
    -R | --rmall         - remove all kernels
    -h | --help          - this help
"
    exit 1    
}

setkernel () {
    if ! barium ls --raw '$bname_source' |grep -q mkuird-dev.xzm ; then
        echo "module mkuird-dev.xzm not installed, run:"
        echo "barium getmod mkuird-dev.xzm && reboot"
        echo "and try again"
        exit ${wgetLINENO}
    fi
    
    if ! [ $1 ] ; then
        exitmsg "Please specify kernel rpm file or kernel name to get kernel from repository" ${LINENO}
    elif [ -f "$1" ] && [ $(file "$1" |cut -f2 -d ' ') == 'RPM' ]  ; then
        RPM="$(realpath $1)"
    elif dnf download -y $1 ; then
        RPM=$(realpath $(ls -t ./ |grep "$1" |head -n1))
    else
        exitmsg "Unknown $1" ${LINENO}
    fi
    
    [ -f "$RPM" ] || exitmsg "Can't get rpm" ${LINENO}
    
    echo "==> Unpacking rpm"
    TMPD=$(mktemp -d)
    trap 'rm -rf $TMPD' EXIT
    rpm -Uhv --nodeps $RPM -r $TMPD
    KERNEL=$(find $TMPD -type f -name 'vmlinuz*' | head -n1)
    PREFIX=$(echo $(basename $KERNEL) |sed 's/vmlinuz//')
    
    echo "==> Find and get kernel"
    if [ ! "$KERNEL" ] || [ ! -f "$KERNEL" ] ; then
        exitmsg "can't find kernel" ${LINENO}
    fi
    
    mv "$KERNEL" ./ || exitmsg "Can't move kernel to current dir" ${LINENO}
    KERNEL="./$(basename $KERNEL)"
    
    echo "Clear directory for module"
    find ${TMPD}/ -mindepth 2 |grep -v '/lib' | xargs rm -rf
    
    echo "==> Create module"
    barium mkmod $TMPD -o ./kmod${PREFIX}.xzm || exitmsg "Can't create module" ${LINENO}
    
    echo "==> create UIRD"
    pushd /var/lib/mkuird/uird
    CMDLINE=$(cat ../chroot_patches/uird.cmdline)
    KMODDIR=${TMPD}/lib/modules
    [ -d ${TMPD}/usr/lib/modules ] && KMODDIR=${TMPD}/usr/lib/modules
    KNAME=$(basename $(ls $KMODDIR |head -n1))
    
    if ! ./mkuird Rosa $CMDLINE -k "$KNAME" -m "$KMODDIR" -n uird.Rosa${PREFIX}.cpio.xz ; then
        popd
        exitmsg "Can't create UIRD" ${LINENO}
    fi
    
    if ! mv ./uird.Rosa${PREFIX}.cpio.xz ${CURPWD}/ ; then
       popd
       exitmsg "Can't get uird from builder" ${LINENO}
    fi
    popd
    
    echo "==> setting up bootloader"
    mountboot
    [ -f  ${MTMP}/boot/grub2/rosa/grub.cfg ] || exit
    
    if [ -f ${MTMP}/alterkernels ] ; then
        . ${MTMP}/alterkernels
        echo "ALTER KERNELS NOW: $alterkernels"
    fi
    alterkernels="$PREFIX $alterkernels"
    
    echo -e "\nKernel vmlinuz${PREFIX} ready to install\n================================="
    ls $KERNEL
    ls ./uird.Rosa${PREFIX}.cpio.xz
    ls ./kmod${PREFIX}.xzm
    echo -e "\nENTER to continue, ctrl-c to abort."
    read qqq
    
    echo "==> Installing kernel"
    cp -fn $KERNEL ${SYSMNT}/layer-base/0/ || exitmsg "can't install kernel"  ${LINENO}
    
    echo "==> Install kernel modules"
    barium instmod ./kmod${PREFIX}.xzm || exitmsg "Can't install module ./kernel${PREFIX}.xzm" ${LINENO}
    
    echo "==> Install uird"
    cp -fn ./uird.Rosa${PREFIX}.cpio.xz ${SYSMNT}/layer-base/0/ || exitmsg "Can't install UIRD" ${LINENO}
    
    echo "==> Configure bootloader"
    echo "alterkernels=\"$alterkernels\"" > ${MTMP}/alterkernels || exitmsg "Can't write to ${MTMP}/alterkernels" ${LINENO}
    echo "Сongratulations! You may try to reboot using new kernel."
}

mountboot () {
    [ "$MTMP" ] && [ -f  ${MTMP}/boot/grub2/rosa/grub.cfg ] && return
    BOOTPART=$(blkid -s LABEL |grep BARIUM_EFI |cut -f1 -d ':')
    [ -b $BOOTPART ] || $(blkid -s LABEL |grep EFI |cut -f1 -d ':')
    MTMP=$(mktemp -d)
    mount "$BOOTPART" "$MTMP"
    if ! [ -f  ${MTMP}/boot/grub2/rosa/grub.cfg ] ; then
       echo "Can't find partition with grub configs"
       echo "Please specify (aka /dev/sda1):"
       read BOOTPART
       mount "$BOOTPART" "$MTMP"
    fi
    trap 'umount $MTMP ; umount -l $MTMP 2>/dev/null ; rm -rf $TMPD $MTMP' EXIT
}

remove (){
    enum_kernels=''
    n=1
    enum_kerenels=$(for a in $(list) ; do echo "$n. $a" ; n=$(( n+1 )); done)
    echo "$enum_kerenels"
    echo "Please enter a number of kernel to remove"
    read N
    [ "$N" ] || exit  ${LINENO}
    PREFIX=$(echo "$enum_kerenels" |grep "${N}.*vmlinuz" |sed 's/[[:digit:]]\+\.\ vmlinuz//')
    rm -f "${SYSMNT}layer-base/0/vmlinuz$PREFIX"
    rm -f "${SYSMNT}layer-base/0/uird.Rosa${PREFIX}.cpio.xz"
    rm -f "${SYSMNT}/layer-base/1/modules/kmod${PREFIX}.xzm"
    mountboot
    . ${MTMP}/alterkernels
    alterkernels=$(echo $alterkernels |sed 's/'$PREFIX'//g' |sed 's/ \+/ /g')
    echo "alterkernels=\"$alterkernels\"" > ${MTMP}/alterkernels || exitmsg "Can't write to ${MTMP}/alterkernels" ${LINENO}
    echo "Remaining alternate kernels:"
    for a in $alterkernels ; do
        echo "vmlinuz$a"
    done
}

list () {
    mountboot
    [ -f  ${MTMP}/alterkernels ] || exitmsg "No additional kernels, or bootloaders partition not mounted" ${LINENO} 1>&2
    . ${MTMP}/alterkernels
    for a in $alterkernels ; do
        echo "vmlinuz$a"
    done
}

rmall () {
    mountboot
    [ -f  ${MTMP}/alterkernels ] || exitmsg "No additional kernels, or bootloaders partition not mounted" ${LINENO}
    . ${MTMP}/alterkernels
    for a in $alterkernels ; do
        rm -f "${SYSMNT}layer-base/0/vmlinuz$a"
        rm -f "${SYSMNT}layer-base/0/uird.Rosa${a}.cpio.xz"
        rm -f "${SYSMNT}/layer-base/1/modules/kmod${a}.xzm"
    done
    rm -f  ${MTMP}/alterkernels
    echo "All alternate kernels removed"
}

while [ -n "$1" ] ; do
    case "$1" in
        "-r" | "--rm" | "--remove" ) remove ; exit;;
        "-l" | "--ls" | "--list" ) list ; exit ;;
        "-R" | "--rmall" ) rmall ; exit ;;
        "-h" | "--help" ) HLP ; exit ;;
        *) PAR="$1"
    esac
    shift
done

[ "$PAR" ] || HLP
setkernel $PAR
