#!/bin/bash
set -euo pipefail #strict mode

# Arch Linux setup script for the XFCE desktop
# Frank ENDRES, (first at last dot fr) - 2024-02
# Licence: [CeCILL](https://cecill.info/licences/Licence_CeCILL_V2.1-en.txt)
# Version: 2025.05.29



#mirror selection:
mirror=${MIRROR:-'http://mirrors.gandi.net/archlinux/$repo/os/$arch'}

#languages selection - set LC_I18N (locale), FF_I18N (firefox), TB_I18N (thunderbird), LO_I18N (libreoffice), HS_I18N (hunspell) and TA_I18N (tesseract) environment variables according your needs:
lci18n=${LC_I18N:-"fr_FR de_DE es_ES it_IT pt_PT en_US"} #for locale-gen (ar_EG bn_BD hi_IN ja_JP ru_RU zh_CN)
#~ ffi18n=${FF_I18N:-"fr de es-es it pt-pt"}   #FireFox (ar bn hi-in ja ru zh-cn)
#~ tbi18n=${TB_I18N:-"fr de es-es it pt-pt"}   #ThunderBird (ar ja ru zh-cn)
#~ loi18n=${LO_I18N:-"fr de es it pt"} #LibreOffice (ar bn hi ja ru zh-cn)
#~ hsi18n=${HS_I18N:-"fr de en_us es-es it"}   #HunSpell (ru)
#~ tai18n=${TA_I18N:-"fra deu eng spa ita por"} #TesserAct ( ara ben hin jpn rus chi_sim)

#hostname, login & password selection:
hostname=${HOSTNAME:-linomad}
username=${USERNAME:-linomad}
password=${PASSWORD:-linomad}


#ensure script is run by root:
if [ $(id -u) != 0 ]; then
    echo "error: $(basename $0) must be run as root"
    exit 1
fi

#handle install folder:
chrootcmd=""
pacstrapcmd="pacman -Syu"
pacmancmd="pacman --noconfirm"
sysroot=${1:-""}
sysroot=${sysroot%/} #remove trailing slash - boot loader and fstab
if [ ! -z "$sysroot" ]; then
    mkdir -p $sysroot
    chrootcmd="chroot $sysroot"
    pacstrapcmd="pacstrap $sysroot"
    pacmancmd="pacman --noconfirm --root $sysroot"
fi

#ensure required tools are available:
missing=""
for command in curl; do
    if [ -z "$(which $command 2>/dev/null)" ]; then
        echo "error: missing command $command"
        missing="$command $missing"
    fi
done
if [ ! -z "$sysroot" ] && [ -z "$(which pacstrap 2>/dev/null)" ]; then
    echo "error: missing command pacstrap"
    missing="arch-install-scripts $missing"
fi
if [ -z "$(which pacman 2>/dev/null)" ]; then
    echo "error: missing command pacman"
    missing="pacman-package-manager $missing"
fi
if [ ! -z "$missing" ]; then
    echo "packages to install: $missing"
    exit 2
fi


#base packages:
packages=""
packages="$packages base iptables-nft linux linux-firmware mkinitcpio grub efibootmgr os-prober ntp sudo tlp" #intel-ucode amd-ucode
packages="$packages dosfstools exfatprogs fscrypt"
packages="$packages man-db vim less tree inotify-tools wget curl arch-install-scripts rsync strace lsof"
packages="$packages traceroute whois tcpdump net-tools inetutils which"
packages="$packages squashfs-tools xorriso" #required for live-system

#driver packages:
packages="$packages wireplumber pipewire-pulse pipewire-alsa pipewire-jack"
packages="$packages iwd broadcom-wl networkmanager networkmanager-openvpn"
packages="$packages vulkan-tools vulkan-nouveau vulkan-radeon vulkan-intel" #Vulkan drivers (nvidia-utils)
packages="$packages mesa-utils mesa libva-utils" #hardware video acceleration
packages="$packages libva-intel-driver intel-media-driver" #Intel hardware video acceleration (libvpl vpl-gpu-rt)
packages="$packages vdpauinfo libvdpau-va-gl libva-nvidia-driver" #hardware video acceleration translations layers (libva-vdpau-driver)
packages="$packages cups cups-pdf sane-airscan nss-mdns" #driverless printing and scanning

#desktop packages:
packages="$packages xorg-server xorg-drivers xorg-xhost xdg-utils xdg-user-dirs xdg-desktop-portal-gtk" #wayland
packages="$packages lightdm-gtk-greeter lightdm-gtk-greeter-settings light-locker"
packages="$packages xfce4-session xfwm4 xfwm4-themes xfce4-panel xfdesktop xfce4-notifyd xfce4-power-manager xfce4-settings xfce4-screensaver" #labwc (wayland)
packages="$packages xfce4-pulseaudio-plugin pavucontrol network-manager-applet blueman system-config-printer"
packages="$packages xfce4-weather-plugin xfce4-clipman-plugin xfce4-notes-plugin xfce4-whiskermenu-plugin xfce4-docklike-plugin xfce4-calculator-plugin touchegg"
packages="$packages xfce4-terminal thunar thunar-volman tumbler libgsf thunar-archive-plugin"
packages="$packages gvfs gvfs-gphoto2 gvfs-mtp gvfs-smb samba 7zip zip unrar file-roller gvfs-afc gvfs-goa gvfs-google"
packages="$packages xfce4-screenshooter xfce4-taskmanager xfce4-appfinder mousepad ristretto parole"
#packages="$packages xfce4-panel-profiles appmenu-gtk-module xfce4-places-plugin xfce4-windowck-plugin" #vala-panel-appmenu-xfce (AUR)
packages="$packages gst-libav gstreamer-vaapi gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-plugin-pipewire"
packages="$packages simple-scan galculator polkit-gnome papers netsurf seahorse" #firefox thunderbird epiphany geary secrets
packages="$packages ttf-dejavu ttf-liberation ttf-carlito ttf-roboto ttf-roboto-mono" #libreoffice-fresh
packages="$packages gparted mtools gpart"
packages="$packages fuse2 libxml2-legacy" #AppImage support

#i18n packages:
#~ for lang in $ffi18n; do packages="$packages firefox-i18n-$lang"; done
#~ for lang in $tbi18n; do packages="$packages thunderbird-i18n-$lang"; done
#~ for lang in $loi18n; do packages="$packages libreoffice-fresh-$lang"; done

#packages installation:
$pacstrapcmd $packages
if [ ! -z "$sysroot" ]; then
    for d in sys proc dev; do mount --bind /$d $sysroot/$d; done
fi


#i18n:
for lang in $lci18n; do sed "s/^#\($lang.UTF-8\)/\1/" -i $sysroot/etc/locale.gen; done
$chrootcmd locale-gen
vcmap=$(localectl status | grep VC | cut -c16-)
x11map=$(localectl status | grep "X11 Layout" | cut -c16- | cut -f1 -d' ')
if [ ! -z "$vcmap" ]; then
    echo -e "KEYMAP=$vcmap\nXKBLAYOUT=$x11map" > $sysroot/etc/vconsole.conf
    for lang in $lci18n; do #xx <-> xx_XX.UTF-8
        code=$(echo $lang | cut -c1-2)
        if [ "$code" == "$vcmap" ]; then
            echo "LANG=$lang.UTF-8" > $sysroot/etc/locale.conf
        fi
    done
fi
if [ ! -z "$x11map" ]; then
    cat > $sysroot/etc/X11/xorg.conf.d/00-keyboard.conf << EOF
Section "InputClass"
    Identifier "system-keyboard"
    MatchIsKeyboard "on"
    Option "XkbLayout" "$x11map"
EndSection
EOF
fi

#udev and modprobe configuration:
echo 'KERNEL=="sr0", SYMLINK+="cdrom dvd"' > $sysroot/etc/udev/rules.d/100-cd-dvd.rules
echo "blacklist pcspkr" > $sysroot/etc/modprobe.d/no-pc-speaker.conf

#hostname and DNS:
echo "$hostname" > $sysroot/etc/hostname
echo "nameserver 9.9.9.9" >> $sysroot/etc/resolv.conf

#NTP:
sed -e 's/^#NTP=.*$/NTP=0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org/' -e 's/#FallbackNTP=/FallbackNTP=/' -i $sysroot/etc/systemd/timesyncd.conf
$chrootcmd systemctl enable systemd-timesyncd

#lightdm session manager:
cat > $sysroot/etc/lightdm/lightdm-gtk-greeter.conf << EOF
[greeter]
theme-name = Adwaita
icon-theme-name = elementary
indicators = ~spacer;~spacer;~a11y;~session;~power
EOF
$chrootcmd systemctl enable lightdm

#desktop services:
$chrootcmd systemctl enable NetworkManager
$chrootcmd systemctl enable bluetooth
$chrootcmd systemctl enable touchegg

#driverless printing & scanning:
sed 's/resolve/mdns_minimal \[NOTFOUND=return\] resolve/' -i $sysroot/etc/nsswitch.conf
$chrootcmd systemctl enable avahi-daemon
$chrootcmd systemctl enable cups

#ls & grep colors + vi:
cat > $sysroot/etc/profile.d/ls-grep-colors.sh << EOF
alias ls='ls --color=auto'
alias grep='grep --color=auto'
EOF
chmod +x $sysroot/etc/profile.d/ls-grep-colors.sh
ln -sf vim $sysroot/usr/bin/vi


#logs, tmp files and firefox cache:
sed 's/#Storage=auto/Storage=volatile/' -i $sysroot/etc/systemd/journald.conf
echo -e "tmpfs\t/tmp\t\ttmpfs\tdefaults\t0 0" >> $sysroot/etc/fstab
#~ mkdir -p $sysroot/usr/lib/firefox/defaults/pref
#~ cat > $sysroot/usr/lib/firefox/defaults/pref/autoconfig.js << EOF
#~ pref("general.config.filename", "firefox.cfg");
#~ pref("general.config.obscure_value", 0);
#~ EOF
#~ echo -e "\ndefaultPref(\"browser.cache.disk.enable\", false);" > $sysroot/usr/lib/firefox/firefox.cfg #better for live-system on USB media


#users:
curl https://fox-echo.info/linomad/res/cfg/skel-xfce.tar.gz | tar -xzv -C $sysroot/etc/
#rm -f $sysroot/usr/share/backgrounds/xfce/xfce-shapes.svg #from xfdesktop package
#curl -o $sysroot/usr/share/backgrounds/xfce/xfce-shapes.svg https://fox-echo.info/linomad/res/cfg/arch-linux.svg #hack to set default background
$chrootcmd useradd -m -g users -G wheel,disk,input $username
echo -e "root:$password\n$username:$password" | $chrootcmd chpasswd
sed 's/# \(%wheel ALL=(ALL:ALL) ALL\)/\1/' -i $sysroot/etc/sudoers
sed -e 's/rwh$/frwh/' -i $sysroot/etc/login.defs #to allow users changing their name


#additional packages:
if [ ! -d linomad-packages ]; then
    #curl https://fox-echo.info/linomad/res/pkg/linomad-packages.tar.gz | tar -xzv -
    curl https://fox-echo.info/linomad/res/pkg/linomad-packages.tar.gz -o linomad-packages.tar.gz
    tar -zxvf linomad-packages.tar.gz
    rm -f linomad-packages.tar.gz
fi
$pacmancmd -U linomad-packages/live-system-*-any.pkg.tar.zst
$pacmancmd -U linomad-packages/thunar-encryption-plugin-*-x86_64.pkg.tar.zst
$pacmancmd -U linomad-packages/gsettings-datetime-*-any.pkg.tar.zst
$pacmancmd -U linomad-packages/gsettings-accounts-*-any.pkg.tar.zst
$pacmancmd -U linomad-packages/xfwm4-theme-generator-*-x86_64.pkg.tar.zst
$pacmancmd -U linomad-packages/adwaita-xfce-icon-theme-*-any.pkg.tar.zst
$chrootcmd gtk-update-icon-cache -f -t /usr/share/icons/hicolor
curl https://fox-echo.info/linomad/res/src/appimage.sh -o $sysroot/usr/local/bin/appimage.sh
chmod +x $sysroot/usr/local/bin/appimage.sh


#desktop files:
sed -e 's/Utility;//' -e 's/System;//' -i $sysroot/usr/share/applications/lightdm-gtk-greeter-settings.desktop #settings
sed 's/System;//' -i $sysroot/usr/share/applications/system-config-printer.desktop #settings
echo "NoDisplay=true" >> $sysroot/usr/share/applications/cups.desktop #use GTK app instead
echo "NoDisplay=true" >> $sysroot/usr/share/applications/vim.desktop #terminal app
echo "NoDisplay=true" >> $sysroot/usr/share/applications/qv4l2.desktop #no Qt
echo "NoDisplay=true" >> $sysroot/usr/share/applications/qvidcap.desktop #no Qt
$chrootcmd update-desktop-database /usr/share/applications/


#pacman:
$chrootcmd pacman-key --init
$chrootcmd pacman-key --populate
sed '/^Server = /d' -i $sysroot/etc/pacman.d/mirrorlist
echo -e "\nServer = $mirror" >> $sysroot/etc/pacman.d/mirrorlist
$chrootcmd pacman -Sy


#boot loader and fstab (if installation is done on a partition):
if mount | grep -q " on $sysroot type "; then
    syspart=$(mount | grep " on $sysroot type " | cut -f1 -d' ')
    uuid=$(lsblk -n -o UUID $syspart)
    fs=$(lsblk -n -o FSTYPE $syspart)
    echo -e "\n#$syspart\n$uuid / $fs defaults 1 1" >> $sysroot/etc/fstab
    disk="/dev/"$(ls -d /sys/block/*/$(basename $syspart) | cut -f4 -d'/')
    efipart=$(lsblk -o PATH,PARTTYPE -rn $disk | sed -n '/ c12a7328-f81f-11d2-ba4b-00a0c93ec93b$/p' | cut -f1 -d' ') #auto-detected
    if [ ! -z "$efipart" ]; then #GPT / UEFI
        uuid=$(lsblk -n -o UUID $efipart)
        fs=$(lsblk -n -o FSTYPE $efipart)
        echo -e "\n#$efipart\n$uuid /boot/efi $fs defaults 1 1" >> $sysroot/etc/fstab
        mount $efipart $sysroot/boot/efi; mount --bind /sys/firmware/efi/efivars $sysroot/sys/firmware/efi/efivars
        $chrootcmd grub-install --target x86_64-efi
        umount $sysroot/sys/firmware/efi/efivars; umount $sysroot/boot/efi
    else #MBR / BIOS (legacy) - probably in a virtual machine
        $chrootcmd grub-install --target i386-pc $disk
    fi
    $chrootcmd grub-mkconfig -o /boot/grub/grub.cfg
    if mount | grep -q " on $sysroot/home type "; then
        homepart=$(mount | grep " on $sysroot/home type " | cut -f1 -d' ')
        uuid=$(lsblk -n -o UUID $homepart)
        fs=$(lsblk -n -o FSTYPE $homepart)
        echo -e "\n#$homepart\n$uuid /home $fs defaults 1 1" >> $sysroot/etc/fstab
    fi
fi


#cleanup:
gpgps=$(ps -u root | grep gpg-agent | awk '{ printf $1 }')
if [ ! -z "$gpgps" ]; then kill $gpgps; sleep 5; fi
rm $sysroot/var/cache/pacman/pkg/* #pacman -Scc
for d in sys proc dev; do umount $sysroot/$d; done
