#!/bin/bash
if [ "$EUID" -ne 0 ]
	then echo "Please run as root"
	exit 0
fi

device=""
spart=""
cpart=""
bpart=""
epart=""
drivelist=""
disklist=""
ACTION=""

lang=$(echo "$LANG" | awk -F\_ '{print $1}')
case "$lang" in
    de*)
        export title1="Laufwerke"
        export title2="TUXEDO chroot helper"
        export title3="Reparatur Option wählen"
        export text1="Sorry, keine Platte ausgewählt, beende."
        export text2="Gewählte Disk:"
        export text3="Aufgeschlossen"
        export text4="Betrete installiertes System"
        export text5="Verlassen Sie das Chroot mittels 'exit' oder Ctrl+d"
        export text6="Nicht verschlüsselt"
        export text7="Wählen Sie die Festplatte, welche untersucht werden soll."
        export text8="Kein tomte gefunden, automatische Reparatur mittels Tomte nicht möglich. Beende."
        export text9="Mehrere Linux Installationen gefunden\n\nWählen Sie eine Partition für chroot"
        export text10="Sorry, keine Partition ausgewählt, beende."
        export text11="Möchten Sie den Versuch einer automatischen Reparatur starten?<br>Es wird versucht, das System auf die TUXEDO Standard Einstellungen zurückzusetzen.<br>Es werden im Vorfeld einige Abfragen erscheinen."
        export text12="Kein Passwort eingegebn."
        export text20="Kein System gefunden, eventuell eine Datenpartition. Nochmal versuchen?"
        export text21="Falsches Passwort. Erneut versuchen?"
        export text22="Gewählte Partition:"
        export textcr="LUKS Verschlüsselungspasswort eingeben"
        export textrep="<b>Bitte wählen Sie, die Art der Reparatur.</b><br><br>Beim Zurücksetzen auf Wekseinstellungen werden alle 32Bit Pakete sowie alle Fremdpakete entfernt.<br>Nachinstallierte Anwendungen können entfernt werden. Es werden keine Daten in Ihrem Home gelöscht.<br>Die Paketquellen werden auf Standardquellen geändert.<br>Wenn Sie hier auf <b>Abbrechen</b> klicken, wird das Script beendet, ohne etwas an ihrem installierten System zu machen."
        export menu1="Ausführen von Tuxedo-Tomte"
        export menu2="Zurücksetzen auf Werkseinstellungen"
        export menu3="Systeminfos auslesen und hochladen"
        export tomtetext="Es wird nun versucht, ein <b>tomte reconfigure all</b> in Ihrem installierten System auszuführen.<br>Sie können an dieser Stelle noch unterbrechen, indem Sie hier auf <b>Abbrechen</b> klicken.<br>Das Script wird dann beendet, ohne etwas an ihrem installierten System zu machen."

        ;;
    *)
        export title1="Devices"
        export title2="Automated Repair Trial with tuxedo-tomte"
        export title3="Choose repair option"
        export text1="Sorry, no disk choosen, exiting."
        export text2="Choosen disc:"
        export text3="Decrypted"
        export text4="Enter installed system"
        export text5="Exit the chroot using 'exit' or Ctrl+d"
        export text6="Not crypted"
        export text7="Select the hard disk to be examined."
        export text8="No tomte found, atumatic repair with tomte not possible. Exiting."
        export text9="Multiple linux installations found.\n\nChoose one partition for chroot"
        export text10="Sorry, no partition choosen, exiting."
        export text11="Would you like to attempt an automatic repair?<br>An attempt will be made to reset the system to the TUXEDO default settings.<br>A few queries will appear in advance."
        export text12="No password given."
        export text20="No system found, maybe a data partition. Try again?"
        export text21="Wrong password. Try again?"
        export text22="Choosen partition:"
        export textcr="input LUKS passphrase"
        export textrep="<b>Please select the type of repair.</b><br><br>With reset to default settings, all 32-bit packages as well as all third-party packages will be removed.<br>Subsequent installed applications can be removed. No data in your home directory will be deleted.<br>The package sources will be changed to default sources.<br>If you click <b>Cancel</b> at this point, the script will be terminated without making any changes to your installed system."
        export menu1="Run Tuxedo-Tomte"
        export menu2="Factory reset"
        export menu3="Read out and upload system informations."
        export tomtetext="An attempt is now being made to execute a <b>tomte reconfigure all</b> in your installed system. You can still interrupt this process by clicking <b>Cancel</b> at this point.<br>The script will then be terminated without making any changes to your installed system."
        ;;
esac
rm -f /tmp/disk*
rm -f /tmp/devic*
rm -f /tmp/cpa*
rm -f /tmp/sysp*

update_task() {
    apt-get update | zenity --progress --title="Update..." --text="$text19" --pulsate --no-cancel --auto-close 2>/dev/null
    now=$(apt-cache policy tuxedo-repair | sed -n '2p;3q' | awk '{print $2}')
    repo=$(apt-cache policy tuxedo-repair | sed -n '3p;4q' | awk '{print $2}')
    if [ "$repo" != "$now" ]; then
        if apt-get -y install tuxedo-repair | zenity --progress --title="Update..." --text="$text19" --pulsate --no-cancel --auto-close 2>/dev/null; then
            kdialog --sorry "$text16" 2>/dev/null
            do_cancel
        fi
    fi
}


is_tomte() {
    is_tomte=""
    if [ $(ls -d /mnt/"$syspart"/etc/tomte) ] || [ $(ls -d /mnt/"$syspart"/@/etc/tomte) ] || [ $(ls -d /mnt/etc/tomte) ] || [ $(ls -d /mnt/@/etc/tomte) ] || [ $(ls -d /mnt/"$cpart"/etc/tomte) ] || [ $(ls -d /mnt/"$cpart"/@/etc/tomte) ] || [ $(ls -d /mnt/"$syspart"/var/log/tomte) ] || [ $(ls -d /mnt/"$syspart"/@/var/log/tomte) ]
    then
        is_tomte="tomte"
        touch /opt/repair_script/tomte
    fi
}

is_txos() {
    is_txos=""
    if [ $(grep TUXEDOOS /mnt/"$syspart"/var/log/tuxedo-install.log 2>/dev/null | grep "read confg" | awk '{print $1}') ] || [ $(ls /mnt/"$syspart"/etc/tuxedo-os-version 2>/dev/null) ] || [ $(grep -m1 tuxedo /mnt/"$syspart"/etc/os-release 2>/dev/null) ] || [ $(grep TUXEDOOS /mnt/"$syspart"/@/var/log/tuxedo-install.log 2>/dev/null | grep "read confg" | awk '{print $1}') ] || [ $(ls /mnt/"$syspart"/@/etc/tuxedo-os-version 2>/dev/null) ] || [ $(grep -m1 tuxedo /mnt/"$syspart"/@/etc/os-release 2>/dev/null) ]
    then
        is_txos="txos"
    fi
}

is_system() {
    is_system=""
    if [ $(ls -f /mnt/"$syspart"/etc/fstab 2>/dev/null) ] || [ $(ls -f /mnt/"$syspart"/@/etc/fstab 2>/dev/null) ]; then
        is_system="system"
    fi
}

find_crypt() {
    is_crypt=$(lsblk -fs | grep "$part" | grep -i luks | awk '{print $1}')
    if [ "$is_crypt" ]; then
        is_luks1=$(cryptsetup luksDump /dev/"$part" | grep Version | awk '{print $2}' | grep 1)
        is_luks2=$(cryptsetup luksDump /dev/"$part" | grep Version | awk '{print $2}' | grep 2)
    fi
}

find_disk(){
    rm -f /tmp/disk* 2> /dev/null
    rm -f /tmp/device* 2> /dev/null
    lsblk | awk '/disk/{print $1}' | sort >/tmp/disklist2
    for m in $(lsblk -lf -o Name,TYPE,FSTYPE | grep -E "ext|btrfs|xfs|LUKS" | awk '{print $1}' | egrep "sd|hd|vd" | cut -c1-3 | sort | uniq); do sed -i "/\<$m\>/d" /tmp/disklist2; done
    for n in $(lsblk -lf -o Name,TYPE,FSTYPE | grep -E "ext|btrfs|xfs|LUKS" | awk '{print $1}' | grep nvme | cut -c1-7 | sort | uniq); do sed -i "/\<$n\>/d" /tmp/disklist2; done
    for e in $(lsblk -lf -o Name,TYPE,SUBSYSTEMS | grep usb | awk '/disk/{print $1}'| sort | uniq); do sed -i "/\<$e\>/d" /tmp/disklist2; done
    blacklist=$(cat /tmp/disklist2)
    for x in $(lsblk -dnl -o NAME,RM | grep -E -v " 1|loop" | awk '{print $1}'); do lsblk -lfo NAME,FSTYPE | grep $x > /tmp/disk_$x.txt; done
    for liste in /tmp/disk_*; do cat "$liste" >> /tmp/disklist.txt; done
    if [ "$blacklist" ]; then
        for i in $(lsblk -dn -o NAME,TYPE,SUBSYSTEMS | grep -E -iv "loop|rom|usb|$blacklist" | awk '{print $1}'); do
        z=$(lsblk -dn -o NAME,Size | grep $i | awk '{print $2}')
        echo -e  $i'\t'\'$i'\t'$z'\t'$(cat /sys/block/$i/device/model | sed 's/*_//')\' | sed "s/\ '/\'/g"
        done 1> /tmp/device1 2> /dev/null
    else
        for i in $(lsblk -dn -o NAME,TYPE,SUBSYSTEMS | grep -E -iv "loop|rom|usb" | awk '{print $1}'); do
            z=$(lsblk -dn -o NAME,Size | grep $i | awk '{print $2}')
            echo -e  $i'\t'\'$i'\t'$z'\t'$(cat /sys/block/$i/device/model | sed 's/*_//')\' | sed "s/\ '/\'/g"
        done 1> /tmp/device1 2> /dev/null
    fi
    cat /tmp/device1 | sort 1> /tmp/device 2> /dev/null
    if [ "$(cat /tmp/device | wc -l)" -ge 2 ]; then
        disk=$(dialog_disk.pl)
    else
        disk=$(cat /tmp/device | awk '{print $1}')
    fi
    if [ -z "$disk" ]; then
        kdialog --sorry "<p><h3>$text1</h3></p>" 2> /dev/null
        do_cancel
    fi
    echo $text2 $disk
}

find_nvidia() {
    is_nv=$(lspci | grep -i nvidia | grep -Ei "3d|display|vga" | awk '{print $2}')
}

get_pkglist() {
    #wget --no-directories -r -l1 --directory-prefix=/opt/repair_script -A "TUXEDO-OS*.manifest" https://os.tuxedocomputers.com/
    if [ ! -f /opt/repair_script/paketliste-p6 ]; then
	wget --directory-prefix=/opt/repair_script https://deb.tuxedocomputers.com/paketliste-p6
    fi
    if [ ! -f /opt/repair_script/paketliste-p5 ]; then
	wget --directory-prefix=/opt/repair_script https://deb.tuxedocomputers.com/paketliste-p5
    fi
    #wget --no-directories -r -l1 -O /opt/repair_script/systeminfos.sh https://mytuxedo.de/index.php/s/DcAeZk4TbBTTjRq/download
    if [ "$is_nv" ]; then
	touch /opt/repair_script/nvidia
    else
	rm -f /opt/repair_script/nvidia
    fi
}

partlist() {
    blkid -c /dev/null | grep -iE "ext|btrf|xfs|luks" | grep -E -iv "ntfs|gap|ventoy|reserved|fat" | awk '{print $1}' | grep $disk | awk -F\: '{print $1}' | awk -F\/ '{print $3}' | sort > /tmp/partlist1
    for x in $(cat /tmp/partlist1); do
    mkdir -p /mnt/$x && mount /dev/$x /mnt/$x 2>/dev/null
    done
    is_boot=$(ls -d /mnt/*/grub 2>/dev/null | awk -F\/ '{print $3}' 2>/dev/null || ls -d /mnt/*/@/grub 2>/dev/null | awk -F\/ '{print $3}' 2>/dev/null)
    if [ "$is_boot" ]; then
    for p in $(cat /tmp/partlist1 | grep -v $is_boot); do
        x=$(lsblk -lf -o NAME,FSTYPE,SIZE | grep $p | sed s/crypto_// | awk '{print $1}')
        z=$(lsblk -lf -o NAME,FSTYPE,SIZE | grep $p | sed s/crypto_// | awk '{print $2}')
        y=$(lsblk -lf -o NAME,FSTYPE,SIZE | grep $p | sed s/crypto_// | awk '{print $3}')
        echo -e  $p' '\'$p'\t     '$z'\t'$y\'
    done 1> /tmp/partlist 2> /dev/null
    umount -R /mnt/* 2>/dev/null
    else
    for p in $(cat /tmp/partlist1); do
        x=$(lsblk -lf -o NAME,FSTYPE,SIZE | grep $p | sed s/crypto_// | awk '{print $1}')
        z=$(lsblk -lf -o NAME,FSTYPE,SIZE | grep $p | sed s/crypto_// | awk '{print $2}')
        y=$(lsblk -lf -o NAME,FSTYPE,SIZE | grep $p | sed s/crypto_// | awk '{print $3}')
        echo -e  $p' '\'$p'\t     '$z'\t'$y\'
    done 1> /tmp/partlist 2> /dev/null
    umount -R /mnt/* 2>/dev/null
    fi
    if [ "$(cat /tmp/partlist | wc -l)" -ge 2 ]; then
        part=$(dialog_part.pl)
    if [ -z "$part" ]; then
        kdialog --sorry "<p><h3>$text10</h3></p>" 2> /dev/null
        do_cancel
    fi
    else
        part=$(cat /tmp/partlist | awk '{print $1}')
    fi
    echo "$text22" "$part"
}

find_part() {
        syspart="$part"
        mkdir /mnt/"$syspart" 2>/dev/null
        mount /dev/"$syspart" /mnt/"$syspart"
        is_system 2>/dev/null
        if [ $(ls -ld /mnt/"$syspart"/@ 2>/dev/null | awk '{print $2}') ]; then
            svol=1
        else
            svol=0
        fi
        if [ -z "$is_system" ]; then
            umount -R /mnt/* 2>/dev/null
            kdialog --yesno "$text20" 2>/dev/null
            if [ "$?" = 0 ]; then
                find_disk
                partlist
                find_part
            else
                umount -R /mnt/* 2>/dev/null
                umount -R /mnt 2>/dev/null
                exit 0
            fi
        fi
        is_tomte 2>/dev/null
        is_txos 2>/dev/null
        if [ ! "$is_tomte" ] && [ ! "$is_txos" ]; then
            kdialog --error "$text8" 2>/dev/null
            umount -R /mnt/* 2> /dev/null
            umount -R /mnt 2> /dev/null
            exit 0
        fi
        umount -R /mnt/* 2>/dev/null
        umount -R /mnt 2> /dev/null
}

find_crpart2() {
        cpart="$part"
        ERC=1
        until [ $ERC -ne 1 ]
            do
            CPASS="$(kdialog --password "<p><font size=4>&emsp;$textcr</font></p>" 2> /dev/null)"
            ret=$?
            if [ "$ret" = 0 ] && [ "$CPASS" ]; then
                printf '%s\n' "$CPASS" | cryptsetup -q luksOpen /dev/"$cpart" cryptdev_"$cpart"
                ret1=$?
            else
                ret1=255
            fi
            if [ "$ret" = 0 ] && [ "$ret1" -ge 1 ] && [ ! "$CPASS" ]; then
                clear
                sleep 1
                ERC=1
            else
                if [ "$ret" = 0 ] && [ "$ret1" -ge 1 ]; then
                    kdialog --sorry "$text21" 2>/dev/null
                    ERC=1
                else
                    set +H
                    ERC=0
                    break;
                fi
            fi
        done
        case $ret in
            0)
                echo ""
                ;;
            1)
                do_cancel
                ;;
            255)
                do_cancel
                ;;
        esac
        for z in $( vgscan | awk -F\" '{print $2}'); do vgchange -ay $z >/dev/null; done 2>/dev/null
        spart=$(blkid -c /dev/null | grep mapper | grep -Eiv "live|ventoy" | grep -E "ext|btrfs|xfs" | awk '{print $1}' | awk -F\: '{print $1}')
        syspart=$cpart
        mkdir -p /mnt/$syspart
        mount $spart /mnt/$syspart
        is_system 2>/dev/null
        if [ $(ls -ld /mnt/"$syspart"/@ 2>/dev/null | awk '{print $2}') ]; then
            svol=1
            cdev=$(awk '/luks/{print $1}' /mnt/"$syspart"/@/etc/crypttab)
        else
            svol=0
            cdev=$(awk '/luks/{print $1}' /mnt/"$syspart"/etc/crypttab)
        fi
        if [ -z "$is_system" ]; then
            kdialog --sorry "$text20" 2>/dev/null
            umount -R /mnt/* 2>/dev/null
            umount -R /mnt 2>/dev/null
            exit 0
        fi
        is_tomte 2>/dev/null
        is_txos 2>/dev/null
        if [ ! "$is_tomte" ] && [ ! "$is_txos" ]; then
            kdialog --error "$text8" 2>/dev/null
            umount -R /mnt/* 2> /dev/null
            umount -R /mnt 2> /dev/null
            for z in $( vgscan | awk -F\" '{print $2}'); do vgchange -a n $z >/dev/null; done
            for c in $( dmsetup info -c | awk '/LUKS/{print $1}'); do cryptsetup luksClose $c >/dev/null; done
            exit 0
        fi
        umount -R /mnt/* 2>/dev/null
        umount -R /mnt 2>/dev/null
        for z in $( vgscan | awk -F\" '{print $2}'); do vgchange -a n $z >/dev/null; done >/dev/null
        for c in $( dmsetup info -c | awk '/LUKS/{print $1}'); do cryptsetup luksClose $c >/dev/null; done >/dev/null
        printf '%s\n' "$CPASS" | cryptsetup luksOpen -q /dev/"$cpart" $cdev
        for z in $( vgscan | awk -F\" '{print $2}'); do vgchange -ay $z >/dev/null; done >/dev/null
        syspart=$(blkid | grep mapper | grep -E "ext|btrf|xfs" | grep -Eiv "live|ventoy" | awk '{print $1}' | awk -F\: '{print $1}')
}

find_crpart1() {
        cpart="$part"
        syspart=luks\-$(lsblk -fl | grep "$part" | awk '/LUKS/{print $4}')
        # get password
        ERC=1
        until [ $ERC -ne 1 ]
            do
            CPASS="$(kdialog --password "<p><font size=4>&emsp;$textcr</font></p>" 2> /dev/null)"
            ret=$?
            if [ "$ret" = 0 ] && [ "$(CPASS)" ]; then
                printf '%s\n' "$CPASS" | cryptsetup luksOpen -q /dev/"$cpart" "$syspart" 2>/dev/null
                ret1=$?
            else
                ret1=255
            fi
            if [ "$ret" = 0 ] && [ "$ret1" -ge 1 ] && [ ! "$(CPASS)" ]; then
                sleep 1
                ERC=1
            else
                if [ "$ret" = 0 ] && [ "$ret1" -ge 1 ]; then
                    kdialog --sorry "$text21" 2>/dev/null
                    ERC=1
                else
                    set +H
                    ERC=0
                    break;
                fi
            fi
        done
        case $ret in
            0)
                ;;
            1)
                #dialog --msgbox "Cancel Pressed" 8 30
                echo "Cancel pressed."
                exit 1
                ;;
            255)
                exit 1
                ;;
        esac
        mkdir /mnt/"$syspart"
        mount /dev/mapper/"$syspart" /mnt/"$syspart"
        is_system 2>/dev/null
        if [ -z "$is_system" ]; then
            kdialog --sorry "$text20" 2>/dev/null
            umount -R /mnt/* 2>/dev/null
            umount -R /mnt 2>/dev/null
            exit 0
        fi
        is_tomte 2>/dev/null
        is_txos 2>/dev/null
        if [ $(ls -ld /mnt/@ 2>/dev/null | awk '{print $2}') ]; then
            svol=1
            umount -R /mnt 2> /dev/null
            umount -R /mnt/* 2> /dev/null
        else
            svol=0
            umount -R /mnt 2> /dev/null
            umount -R /mnt/* 2> /dev/null
        fi
        if [ ! "$is_tomte" ] && [ ! "$is_txos" ]; then
            kdialog --error "$text8" 2>/dev/null
            exit 0
        fi
}

do_action() {
    if [ ! -e /opt/repair_script/tomte ]; then
        ACTION=apt
        ACTION=$(kdialog --menu "<p><font size=4>$textrep</font></p>" apt "$menu2" --title "$title3"2>/dev/null)
    else
	ACTION=systeminfos
        ACTION=$(kdialog --menu "<p><font size=4>$textrep</font></p>" tomte "$menu1" apt "$menu2" --title "$title3" 2>/dev/null)
    fi
    if [ "$?" != 0 ]; then
        do_cancel
    fi
    echo "$ACTION"
}

do_work() {
    if [ "$is_luks2" ]; then
        if [ "$svol" = 1 ]; then
            mount -o subvol=@ "$syspart" /mnt
        else
            mount "$syspart" /mnt
        fi
    fi
    if [ "$is_luks1" ]; then
        if [ "$svol" = 1 ]; then
            mount -o subvol=@ /dev/mapper/"$syspart" /mnt
        else
            mount /dev/mapper/"$syspart" /mnt
        fi
    fi
    if [ ! "$is_crypt" ]; then
        if [ "$svol" = 1 ]; then
            mount -o subvol=@ /dev/"$syspart" /mnt
        else
            mount /dev/"$syspart" /mnt
        fi
    fi
    for i in /dev /dev/pts /proc /sys /sys/firmware/efi/efivars /run; do  mount -B $i /mnt$i; done
    hostname chroot
    mount -B /opt/repair_script /mnt/mnt/
    if [ "$sysinfo" ]; then
            chroot /mnt /bin/sh -c "mount -a || true && ./mnt/systeminfos.sh"
    else
        if [ "$is_txos" ]; then
            if [ "$(echo $ACTION)" = "tomte" ]; then
                echo "tomte run"
                chroot /mnt /bin/sh -c "mount -a || true && ./mnt/tomte_run.sh"
            else
                echo "apt run"
                chroot /mnt /bin/sh -c "mount -a || true && ./mnt/apt_run.sh"
            fi
        fi
    fi
    hostname "$(cat /etc/hostname)"
    cp -af /repair-live.log /mnt/var/log/
    umount -R /mnt 2> /dev/null
    umount -R /mnt/* 2> /dev/null
}

do_cancel() {
    umount -R /mnt/* 2>/dev/null
    umount -R /mnt 2>/dev/null
    for z in $( vgscan | awk -F\" '{print $2}'); do vgchange -a n $z >/dev/null; done
    for c in $( dmsetup info -c | awk '/LUKS/{print $1}'); do cryptsetup luksClose $c >/dev/null; done
    touch /tmp/cancel
    exit 0
}

sysinfo() {
    kdialog --yesno "$menu3" 2>/dev/null
    case $? in
            0)
                sysinfo=1
                touch /tmp/sysinfo
                ;;
            *)
                sysinfo=""
                ;;
    esac
}

update_task
find_disk
partlist
find_crypt
if [ "$is_luks2" ]; then
	find_crpart2
fi
if [ $is_luks1 ]; then
	find_crpart1
fi
if [ ! $is_crypt ]; then
	find_part
fi
find_nvidia
get_pkglist
#sysinfo
if [ "$is_txos" ]; then
    do_action
fi
if [ ! "$is_txos" ] && [ "$is_tomte" ]; then
    kdialog --warningyesno "<font size=4>$tomtetext</font>" 2>/dev/null
    if [ $? != 0 ]; then
        do_cancel
    fi
fi

do_work
umount -R /mnt/* 2>/dev/null
umount -R /mnt 2>/dev/null
for z in $( vgscan | awk -F\" '{print $2}'); do vgchange -a n $z >/dev/null; done
for c in $( dmsetup info -c | awk '/LUKS/{print $1}'); do cryptsetup luksClose $c >/dev/null; done

exit 0
