#!/bin/sh

# Vars {{{
[ -z "${DEBUG}" ] && readonly DEBUG=0
## Export DEBUG for sub-script
export DEBUG

## Colors
readonly PURPLE='\033[1;35m'
readonly RED='\033[0;31m'
readonly RESET='\033[0m'
readonly COLOR_DEBUG="${PURPLE}"

## Define the hard drive to use
if [ -b '/dev/sda' ]; then
	hdd="/dev/sda"
else
	printf '%b\n' "Please check the hard drive to use"
	exit 0
fi
# }}}

## Dependencies {{{
apt update
apt install -y aptitude btrfs-progs bzip2 cryptsetup debconf-i18n dialog dmsetup htop ipcalc isc-dhcp-client isc-dhcp-common locales lvm2 openssh-server pciutils tmux vim-nox wget zsh
## }}}

debug_message() {                                               # {{{

	local_message="${1}"

	## Print message if DEBUG is enable (=0)
	[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6b\e[m\n' "DEBUG − ${PROGNAME}: ${local_message}"

	return 0
}
# }}}

## If the script should create extra volume (eg. backup, virt, Proxmox,…)
manage_extra_lv=0
## Is LUKS {{{

if blkid | grep -q -- "${hdd}.*crypto_LUKS"; then
	debug_message "is_luks − \
Luks seems available on ${hdd} device."
	manage_luks=0
	## You need to set a new passphrase after the installation or at least change this one
	luks_passphrase="generic key"
	luks_key_file="/tmp/luks.keyfile.temp"
	luks_pv_name=$(basename "${hdd}"2_crypt)
else
	manage_luks=1
	debug_message "is_luks − \
No Luks system on ${hdd} device."
fi
## }}}
## Open LUKS system {{{
if [ "${manage_luks}" -eq 0 ]; then
	### Put passphrase in a keyfile for multiple usage
	rm -f -- "${luks_key_file}" && printf '%b' "${luks_passphrase}" > "${luks_key_file}"
	### If the volume is not already opened
	if [ ! -h /dev/mapper/"${luks_pv_name}" ]; then
		debug_message "open_luks − \
Try to open Luks on ${luks_pv_name} − ${hdd}2"
		### Open LUKS system
		cryptsetup luksOpen "${hdd}"2 "${luks_pv_name}" --key-file "${luks_key_file}" || exit 2
	fi
fi
## }}}
## Enable LVM {{{
### Ensure to enable LVM devices
pvscan --quiet > /dev/null
vgscan --quiet > /dev/null
vgchange --activate y --quiet > /dev/null

## Try to guess the VG name by using the last VG detected
vgname=$(vgdisplay --short | tail -n 1 | sed 's/.*"\(.*\)" .*/\1/')
## }}}
## Is BTRFS {{{
root_fs_type=$(lsblk -f /dev/mapper/"${vgname}"-root | awk '/root/ { print $2 }')
if [ "${root_fs_type}" = "btrfs" ]; then
	manage_btrfs=0
	debug_message "is_btrfs − \
The root seems to be in btrfs."
else
	manage_btrfs=1
	debug_message "is_btrfs − \
No btrfs detected."
fi
## }}}

## Mount the system {{{
### Root
mkdir -p -- /target
mountpoint -q /target            || mount -- /dev/mapper/"${vgname}"-root /target

	### boot - grub
	mountpoint -q /target/boot       || mount -- ${hdd}1 /target/boot
##
if [ "${manage_btrfs}" -eq 0 ]; then
	printf '%b\n' "The root system is in ${GREEN}BTRFS${RESET}, no extra mount is required."
else
	#### home LV
	mountpoint -q /target/home       || mount -- /dev/mapper/"${vgname}"-home /target/home
	#### opt LV
	mountpoint -q /target/opt        || mount -- /dev/mapper/"${vgname}"-opt /target/opt
	#### srv LV
	mountpoint -q /target/srv        || mount -- /dev/mapper/"${vgname}"-srv /target/srv
	#### tmp LV
	mountpoint -q /target/tmp        || mount -- /dev/mapper/"${vgname}"-tmp /target/tmp
	#### usr LV
	mountpoint -q /target/usr        || mount -- /dev/mapper/"${vgname}"-usr /target/usr
	#### var LV
	mountpoint -q /target/var        || mount -- /dev/mapper/"${vgname}"-var /target/var

	if [ "${manage_extra_lv}" -eq 0 ]; then
		### Extra bkp LV
		mountpoint -q /target/srv/backup || mount -- /dev/mapper/"${vgname}"-bkp /target/srv/backup
		### Extra vz LV
		mountpoint -q /target/var/lib/vz || mount -- /dev/mapper/"${vgname}"-vz /target/var/lib/vz
	fi
fi

### Swap
swapon -- /dev/mapper/"${vgname}"-swap
## }}}
## Ensure to (re)mount devices for chroot {{{
mkdir -p --   /target/dev
mountpoint -q /target/dev        || mount -t devtmpfs -- none      /target/dev
mkdir -p --   /target/dev/pts
mountpoint -q /target/dev/pts    || mount -t devpts   -- /dev/pts  /target/dev/pts
mkdir -p --   /target/proc
mountpoint -q /target/proc       || mount -t proc     -- none      /target/proc
mkdir -p --   /target/sys
mountpoint -q /target/sys        || mount -t sysfs    -- none      /target/sys
### FIXME : /run/lvm needs to be manually set in debootstrap|chroot for Buster {{{
### See :
### https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=918590
### https://bbs.archlinux.org/viewtopic.php?pid=1820949#p1820949
mkdir -p --   /target/run/lvm
mountpoint -q /target/run/lvm    || mount --bind      -- /run/lvm  /target/run/lvm
mkdir -p --   /target/run/udev
mountpoint -q /target/run/udev   || mount --bind      -- /run/udev /target/run/udev
### }}}
## }}}

## Network {{{
### Get all informations from current network configuration in rescue mode
net_device=$(ip r | grep "^default" | head -1 | cut -d" " -f5)
#### TODO: Switch to ip a to get ip address
net_address=$(ip r | grep -vE "(^default|metric)" | grep "${net_device}.*src" | head -1 | awk -F" " '{print $NF}')
read -r net_mac_address </sys/class/net/"${net_device}"/address
net_netmask=$(ipcalc "${net_address}" | awk '/Netmask:/{print $2;}')
net_netmask_cidr=$(ipcalc "${net_address}" | awk '/Netmask:/{print $4;}')
net_broadcast=$(ip a s dev "${net_device}" | awk '/inet.*brd/{print $4}')
net_network=$(ip r | grep -vE "(^default|metric)" | grep "src ${net_address}" | head -1 | cut -d"/" -f1)
net_gateway=$(ip r | grep "^default" | head -1 | cut -d" " -f3)

### Create a network unit for systemd-networkd
printf '%b' "[Match]
MACAddress=${net_mac_address}

[Network]
Description=network interface with default route without dhcp
DHCP=no
Address=${net_address}/${net_netmask_cidr}
Gateway=${net_gateway}
IPv6AcceptRA=no
DNS=80.67.169.12
" > /tmp/50-default.network

## }}}

printf '%b\n' "${GREEN}The system is available on /target you can now try to chroot.${RESET}"

exit 0
