#!/bin/sh

# shellcheck shell=ash

PROGRAM=rkos-setup

if [ -t 1 ]; then
	COLCYAN="\e[36m"
	COLWHITE="\e[97m"
	COLRESET="\e[0m"
else
	COLCYAN=""
	COLWHITE=""
	COLRESET=""
fi

print_heading1() {
	printf "${COLCYAN}%s${COLRESET}\n" "$1"
}

print_heading2() {
	printf "${COLWHITE}%s${COLRESET}\n" "$1"
}

is_kvm_clock() {
	grep -q "kvm-clock"  "$ROOT"sys/devices/system/clocksource/clocksource0/current_clocksource 2>/dev/null
}

is_virtual_console() {
	case "$(readlink "$ROOT"/proc/self/fd/0)" in
		/dev/tty[0-9]*) return 0;;
	esac
	return 1
}

usage() {
	cat <<-__EOF__
		usage: $PROGRAM [-ahq] [-c FILE | -f FILE]

		Setup RKOS Linux

		options:
		 -a  Create Alpine Linux overlay file
		 -c  Create answer file (do not install anything)
		 -e  Empty root password
		 -f  Answer file to use for installation
		 -h  Show this help
		 -q  Quick mode. Ask fewer questions.
	__EOF__
	exit $1
}

while getopts "aec:hq" opt ; do
	case $opt in
		a) ARCHIVE=yes;;
		c) CREATEANSWERFILE="$OPTARG";;
		e) empty_root_password=1;;
		h) usage 0;;
		q) empty_root_password=1; quick=1; APKREPOSOPTS="-1"; HOSTNAMEOPTS="alpine";;
		'?') usage "1" >&2;;
	esac
done
shift $(expr $OPTIND - 1)

case "$USEANSWERFILE" in
	http*://*|ftp://*)
		# dynamically download answer file from URL (supports HTTP(S) and FTP)
		# ensure the network is up, otherwise setup a temporary interface config
		if ! rc-service networking --quiet status; then
			setup-interfaces -ar
		fi

		temp="$(mktemp)"
		wget -qO "$temp" "$USEANSWERFILE" || die "Failed to download '$USEANSWERFILE'"
		USEANSWERFILE="$temp"
		;;
	*)
		[ -n "$USEANSWERFILE" ] && USEANSWERFILE=$(realpath "$USEANSWERFILE")
		;;
esac
if [ -n "$USEANSWERFILE" ] && [ -e "$USEANSWERFILE" ]; then
	. "$USEANSWERFILE"
fi

if [ -n "$CREATEANSWERFILE" ]; then
	touch "$CREATEANSWERFILE" || echo "Cannot touch file $CREATEANSWERFILE"
	cat > "$CREATEANSWERFILE" <<-__EOF__
		# Example answer file for rkos-setup script
		# If you don't want to use a certain option, then comment it out

		# Use US layout with US variant
		# KEYMAPOPTS="us us"
		KEYMAPOPTS=none

		# Set hostname to 'router'
		HOSTNAMEOPTS=router

		# Search domain of example.com, Quad9 public nameserver
		# DNSOPTS="-d example.com 9.9.9.9"

		# Set timezone to UTC
		#TIMEZONEOPTS="UTC"
		TIMEZONEOPTS=none

		# Create admin user
		USEROPTS="-a -u -g audio,input,video,netdev juser"
		#USERSSHKEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOIiHcbg/7ytfLFHUNLRgEAubFz/13SwXBOM/05GNZe4 juser@example.com"
		#USERSSHKEY="https://example.com/juser.keys"

		# Do not install Openssh
		SSHDOPTS=none
		#ROOTSSHKEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOIiHcbg/7ytfLFHUNLRgEAubFz/13SwXBOM/05GNZe4 juser@example.com"
		#ROOTSSHKEY="https://example.com/juser.keys"

		# Use openntpd
		# NTPOPTS="openntpd"
		NTPOPTS=none
	__EOF__
	echo "Answer file $CREATEANSWERFILE has been created.  Please add or remove options as desired in that file"
	exit 0
fi

printf "\n\n"
print_heading1 " RKOS LINUX SETUP"
print_heading1 "------------------"

if [ "$ARCHIVE" ] ; then
	echo "Creating an Alpine overlay"
	init_tmpdir ROOT
else
	PKGADD="apk add"
fi

# set keymap
if is_virtual_console || [ -n "$KEYMAPOPTS" ]; then
	echo
	print_heading2 " Keymap"
	print_heading2 "--------"
	setup-keymap ${KEYMAPOPTS}
fi

# set hostname
echo
print_heading2 " Hostname"
print_heading2 "----------"
setup-hostname ${HOSTNAMEOPTS} && if [ -z "$SSH_CONNECTION" ]; then
	if rc-service --quiet networking status; then
		# manually restart networking, forcing this script to wait until networking starts
		rc-service --quiet networking stop
		rc-service --quiet hostname restart
		rc-service --quiet networking start
	else
		rc-service --quiet hostname restart
	fi
fi
setup-devd -C mdev # just to bootstrap

# set root password
if [ -z "$empty_root_password" ]; then
	echo
	print_heading2 " Root Password"
	print_heading2 "---------------"
	while ! $MOCK passwd ; do
		echo "Please retry."
	done
fi

# pick timezone
if [ -z "$quick" ]; then
	echo
	print_heading2 " Timezone"
	print_heading2 "----------"
	setup-timezone ${TIMEZONEOPTS}
fi

echo
rc-update --quiet add networking boot
rc-update --quiet add seedrng boot || rc-update --quiet add urandom boot
svc_list="cron crond"
if [ -e /dev/input/event0 ]; then
	# Only enable acpid for systems with input events entries
	# https://gitlab.alpinelinux.org/alpine/aports/-/issues/12290
	svc_list="$svc_list acpid"
fi
for svc in $svc_list; do
	if rc-service --exists $svc; then
		rc-update --quiet add $svc
	fi
done

# start up the services
$MOCK openrc ${SSH_CONNECTION:+-n} boot
$MOCK openrc ${SSH_CONNECTION:+-n} default

# update /etc/hosts - after we have got dhcp address
# Get default fully qualified domain name from *first* domain
# given on *last* search or domain statement.
_dn=$(sed -n \
-e '/^domain[[:space:]][[:space:]]*/{s///;s/\([^[:space:]]*\).*$/\1/;h;}' \
-e '/^search[[:space:]][[:space:]]*/{s///;s/\([^[:space:]]*\).*$/\1/;h;}' \
-e '${g;p;}' "$ROOT"/etc/resolv.conf 2>/dev/null)

_hn=$(hostname)
_hn=${_hn%%.*}

sed -i -e "s/^127\.0\.0\.1.*/127.0.0.1\t${_hn}.${_dn:-$(get_fqdn my.domain)} ${_hn} localhost.localdomain localhost/" \
	"$ROOT"/etc/hosts 2>/dev/null

if ! is_kvm_clock && [ "$quick" != 1 ]; then
	echo
	print_heading2 " Network Time Protocol"
	print_heading2 "-----------------------"
	setup-ntp ${NTPOPTS:+chrony}
fi

# lets stop here if in "quick mode"
if [ "$quick" = 1 ]; then
	exit 0
fi

echo
print_heading2 " User"
print_heading2 "------"
setup-user ${USERSSHKEY+-k "$USERSSHKEY"} ${USEROPTS:--a -g 'audio input video netdev'}
for i in "$ROOT"home/*; do
	if [ -d "$i" ]; then
		lbu add $i
	fi
done

setup-sshd ${ROOTSSHKEY+-k "$ROOTSSHKEY"} ${SSHDOPTS:openssh}
root_keys="$ROOT"/root/.ssh/authorized_keys
if [ -f "$root_keys" ]; then
	lbu add "$root_keys"
fi
