#!/bin/bash

set -e

ROOT=
MODEL=/usr/share/lip-finalize/files
ACTIONS="clean-network trixies-sources kernel-backport vdanjean-sources"

INTERACTIVE=true
NOACT=false
RESTART=true

PROGNAME="$(basename "$0")"

usage() {
	cat <<EOF
$PROGNAME [options..]
Options:
	-h|--help	this help
	-a|--automatic	do not ask for confirmation
	-n|--dry-run	do not modify anything, just check and show
EOF
}

log() {
	local PREFIX="$1"
	shift
	local l
	for l in "$@"; do
		echo 1>&2 "$PREFIX: $l"
	done
}

info() {
	log I "$@"
}

debug() {
	log D "$@"
}

warn() {
	log W "$@"
}

error() {
	log E "$@"
	exit 1
}

question() {
	local Q="$1"
	local ANS
	if ! $INTERACTIVE; then
		return
	fi
	printf "%s [Y/n]\n" "$Q"
	read ANS
	case "$ANS" in
		[nN]*) return 1;;
		*) return 0;;
	esac
}

run() {
	local PREFIX
	if $NOACT; then
		PREFIX="I: Should have run"
	else
		PREFIX="D: Running"
	fi
	echo 1>&2 "$PREFIX: " "$@"
	if ! $NOACT; then
		"$@"
	fi
}

clean-network() {
	local -a LIST
	LIST=( $(cat "$ROOT"/etc/network/interfaces | grep '^ *iface' \
		| awk '{print $2}' | grep -v '^lo$' || true) )
	if test "${#LIST[@]}" = 0 ; then
		debug "$ROOT/etc/network/interfaces with only lo"
	else
		info "${#LIST[@]} interface(s) (other that 'lo') are defined in $ROOT/etc/network/interface"
		if question "Do you want to remove them? (so that they can be handled by NetworkManager?)"; then
			info "Writing $ROOT/etc/network/interfaces"
			run cp -a "$MODEL"/interfaces "$ROOT/etc/network/interfaces"
			if $RESTART; then
				run systemctl restart NetworkManager || true
			fi
		fi
	fi
}

clean-sources-list() {
	local NB
	NB=$(cat "$ROOT"/etc/apt/sources.list 2>/dev/null | grep -vE '^[[:space:]]*(#.*)?$' | wc -l )
	if [ "$NB" = 0 ]; then
		debug "$ROOT/etc/apt/sources.list does not contain enabled sources"
	else
		info "$ROOT/etc/apt/sources.list contains sources"
		if question "Removing existing entries in $ROOT/etc/apt/sources.list?"; then
			run sed -e '/^ *[^ #].*/s/^/#LIP: /' -i "$ROOT/etc/apt/sources.list"
		fi
	fi
}

install-file() {
	local DEST="$1"
	local SRC="$2"
	if test -f "$1" ; then
		if cmp -s "$DEST" "$MODEL/$SRC" 2>/dev/null ; then
			debug "$DEST already up-to-date"
			return
		fi
		info "New version for $DEST available"
	else
		info "$DEST not installed yet"
	fi
	if question "Do you want to install $DEST?"; then
		run mkdir -p "$(dirname "$DEST")"
		run cp -a "$MODEL/$SRC" "$DEST"
	fi
}

install-trixies-sources() {
	install-file "$ROOT/etc/apt/sources.list.d/trixie.sources" "trixie.sources"
}

install-polytech-ens-sources() {
	install-file "$ROOT/etc/apt/sources.list.d/polytech-ens.sources" "polytech-ens.sources"
	install-file "$ROOT/etc/apt/keyrings/Enseignants_Polytech.gpg" "Enseignants_Polytech.gpg"
}


TEMP=$(getopt --shell sh \
	-o hna --long help,dry-run,automatic,model:,no-restart \
	-n "$PROGNAME" -- "$@")

eval set -- "$TEMP"

while true ; do
	case "$1" in
	-h|--help) usage ; exit 0 ;;
	-a|--automatic) INTERACTIVE=false ;;
	-n|--dry-run) NOACT=true ;;
	--no-restart) RESTART=false ;;
	--model) MODEL="$2"; shift ;;
	--) shift ; break ;;
	*) echo "Unknown option/argument '$1'" ; exit 1 ;;
	esac
	shift;
done

if [ "$(id -u)" != 0 ]; then
	if [ "$NOACT" != true ]; then
		warn "Not running as root, forcing dry-run mode"
		NOACT=true
	fi
fi       

cleanup() {
	run etckeeper commit "committing changes in /etc after running lip-finalyze" || warn "Cannot run etckeeper to record changes"
}

check-for-etckeeper() {
	if command -v etckeeper >/dev/null ; then
		debug "etckeeper is installed"
		return
	fi
	warn "etckeeper is not installed. You should reconsider it."
	if $INTERACTIVE; then
		if question "Do you want to install etckeeper package?"; then
			run apt install etckeeper
		fi
	else
		warn "Skipping etckeeper installation in automatic mode" \
			"You can install it with 'apt install etckeeper'"
	fi
}

check-for-etckeeper

run etckeeper commit "committing changes in /etc before running lip-finalyze" \
	|| warn "Cannot run etckeeper to record changes"
trap cleanup EXIT

clean-network
clean-sources-list
install-trixies-sources
install-polytech-ens-sources
