#!/usr/bin/bash -e
#
# Author: Casey DeLorme
#
# Description: A fully automated installation script wired for testing with
# packer, but fully functional for a standard installation.
#
# Make sure you have a network connection, install git, clone this repository,
# and finally run this script to automate the entire installation.
#
#	pacman -Sy git
#	git clone https://git.caseydelorme.com/cdelorme/arch-desktop.git
#	cd arch-desktop
#	./setup/install.sh

# check that efivars is mounted or notify the user that it could create a problem
[ ! -d /sys/firmware/efi/efivars ] && echo "efivars not mounted; this install may leave you with a derelict system..." && sleep 30s

# verify required variables
while [[ ! "$enable_hibernation" =~ ^[yn]$ ]]; do read -p "would you like to enable hibernation (yn)? " -n1 enable_hibernation && echo ""; done
while [ -z "$root_password" ]; do read -p "please enter a root password: " -s root_password && echo ""; done
while [ -z "$username" ]; do read -p "please enter your username: " username; done
while [ -z "$password" ]; do read -p "please enter your password: " -s password && echo ""; done
export hostname=${hostname:-arch}

# export environment variables for arch.sh automation
export enable_hibernation
export root_password
export username
export password

# optionally print all commands
[ -n "$DEBUG" ] && set -x && export DEBUG

# test network connection
ping -c 3 archlinux.org

# synchronize time (print for debug)
timedatectl set-ntp true
timedatectl status

# if more than one disk exists ask which to use:
if [ -z "$disk" ]; then
	export disk=$(lsblk -l | grep disk | awk '{if (!$7) print $1;}')
	if [ $(echo "$disk" | wc -l) -gt 1 ]; then
		echo -e "multiple disks found:\n$disk"
		read -p "please enter the name of the disk you want to use: " disk
	fi
fi

# make sure the disk exists or terminate
if [ ! -b "/dev/${disk}" ]; then
	echo "unable to locate disk: /dev/${disk}"
	exit 1
fi

# assume sane default for swap, or intelligently size for hibernation
export swap_size=2048
if [ "$enable_hibernation" = "y" ]; then
	export ram_size=$(numfmt --to-unit=Mi --from-unit=K $(cat /proc/meminfo | grep MemTotal | awk '{print $2}'))
	if [ $ram_size -le $(numfmt --to-unit=Mi --from=iec 4G) ]; then
		export swap_size=$(echo $(($ram_size * 3 / 2)))
	else
		swap_size=$(printf %.0f $(echo "sqrt($ram_size) + $ram_size" | bc))
	fi
fi

# partition the hard drive
parted "/dev/${disk}" -s 'mklabel gpt'
parted "/dev/${disk}" -s 'mkpart primary fat32 1MiB 1024MiB'
parted "/dev/${disk}" -s 'set 1 esp on'
parted "/dev/${disk}" -s "mkpart primary linux-swap 1024MiB $((swap_size + 1024))MiB"
parted "/dev/${disk}" -s "mkpart primary btrfs $((swap_size + 1024))MiB 100%"

# acquire partitions as an array
export partitions=( $(lsblk -l -xNAME "/dev/${disk}" | grep part | awk '{print $1}') )

# format the partitions
mkfs.fat -F32 -nEFI "/dev/${partitions[0]}"
mkswap -Lswap "/dev/${partitions[1]}"
mkfs.btrfs -fLarch "/dev/${partitions[2]}"

# enable and mount partitions with appropriate settings
swapon "/dev/${partitions[1]}"
export resume_uuid="$(lsblk -no UUID "/dev/${partitions[1]}")"
mount -t btrfs -o "noatime,compress=lzo,autodefrag,ssd,space_cache=v2" "/dev/${partitions[2]}" /mnt
mkdir /mnt/boot
mount "/dev/${partitions[0]}" /mnt/boot

# install base and base-devel package sets, and generate the fstab
pacstrap /mnt base
genfstab -Up /mnt > /mnt/etc/fstab

# this assumes that arch.sh and install/ exist and will copy them to continue
# @note: would prefer to copy to `/tmp` but `/mnt/tmp` from iso is a separate tmpfs
mkdir -p /mnt/srv/arch-desktop
cp -r ./ /mnt/srv/arch-desktop

# proceed to automate arch-chroot installation and push output to a log file that gets copied to the new disk
arch-chroot /mnt /srv/arch-desktop/arch.sh | tee arch-install.log
cp arch-install.log /mnt/arch-install.log

# if auto-reboot is enabled then unmount and automatically reboot
if [ -n "$AUTOREBOOT" ]; then
	sync
	umount -R /mnt
	echo "installation complete, rebooting in 5 seconds..."
	(sleep 5 && systemctl reboot) &
else
	echo "installation complete, run 'systemctl reboot' when ready..."
fi
