#!/bin/bash

# Default virtual mounts for linux systems
cfg_mounts+=( 'proc:proc:/proc:' )
cfg_mounts+=( 'run:tmpfs:/run:' )
cfg_mounts+=( 'sys:sysfs:/sys:' )

# devfs and its children
cfg_mounts+=( 'dev:devtmpfs:/dev:' )
cfg_mounts+=( 'pts:devpts:/dev/pts:noexec,nosuid,gid=5,mode=0620' )
cfg_mounts+=( 'mqueue:mqueue:/dev/mqueue:noexec,nosuid,nodev' )
cfg_mounts+=( 'shm:tmpfs:/dev/shm:defaults,mode=0777' )

# Some temporary directories
cfg_tmpdirs+=( '/run/lock' '/run/lock/lvm' '/run/lvm' '/run/user' )

# Functions
rc.rescue() { exec "${cfg_rc_rescue_shell:-"$SHELL"}"; }

rc.motd() {
	[[ -f "/etc/rc.motd" ]] && {
		while read; do
			printf "%s\n" "$REPLY"
		done < "/etc/rc.motd"
	}

	return 0
}

rc.tmpdirs() {
	mkdir -p -m0755 "${cfg_tmpdirs[@]}"
}

rc.mount_misc() {
	for m in "${cfg_mounts[@]}"; do
		echo "$m" | while IFS=':' read fs fs_type mountpoint mount_options; do
			[[ "$mount_options" ]] || { mount_options='defaults'; }

			mountpoint -q "$mountpoint" || {
				[[ -d "$mountpoint" ]] || { mkdir -p "$mountpoint"; }
				mount "$fs" -n -t "$fs_type" -o "$mount_options" "$mountpoint"
			}
		done
	done
}

rc.parse_cmdline() {
	[[ -f "/proc/cmdline" ]] && {
		boot_cmdline=( $(</proc/cmdline) )
	}

	for i in "${boot_cmdline[@]}"; do
		case "$i" in
			init.single) rc.rescue;;
		esac
	done
}

rc.services_start() {
	local service_name start_mode

	for i in "${cfg_services[@]}"; do
		unset service_name

		[[ "$i" =~ ^@ ]] && {
			service_name="${i##*@}"
			start_mode='bg'
		}

		[[ "$i" =~ ^% ]] && {
			service_name="${i##*%}"
			start_mode='watch'
		}

		service_name=${service_name:-$i}
		start_mode="${start_mode:-start}"
		
		case "$start_mode" in
			bg) service "$service_name" start &;;
			start) service "$service_name" start;;
			*) echo "Mode $start_mode not supported";;
		esac
	done
}

rc.services_stop() {
	echo "Stopping services..."
	local service_name

	for i in "${cfg_services[@]}"; do
		service_name="${i##*@}"; service_name="${service_name##*%}"
		service "$service_name" stop &>/dev/null &
	done
	wait
}

rc.stop_everything() {
	echo "Politely asking all processes to shut down..."
	killall5 -15; sleep 3

	echo "Killing the remaning ones..."
	killall5 -9
}

rc.unmount_everything() {
	echo "Unmounting filesystems..."
	umount -a
}

rc.remount_root() {
	echo "Remounting / read-only..."
	mount / -o remount,ro
}

rc.boot() {
	rc.mount_misc
	rc.tmpdirs
	rc.hostname
	rc.timezone
	rc.modules
	rc.services_start
	wait
	rc.motd
}

# This is handled by busybox
# rc.halt() {
# 	case "$action" in
# 		poweroff|shutdown) echo 'o' > /proc/sysrq-trigger;;
# 		halt) :;;
# 		reboot|*) echo 'b' > /proc/sysrq-trigger;;
# 	esac
# }

rc.shutdown() {
	rc.services_stop
	rc.stop_everything
	rc.unmount_everything
	rc.remount_root

	echo "Halt complete."
	
	#rc.halt
}

rc.hostname() {
	[[ -f '/etc/hostname' ]] && { hostname "$(</etc/hostname)"; }
	[[ "$cfg_hostname" ]] && { hostname "$cfg_hostname"; }
}

rc.modules() {
	for i in "${cfg_modules[@]}"; do
		modprobe "$i"
	done
}

rc.timezone() {
	[[ "$cfg_timezone" ]] && {
		ln -fs "/usr/share/zoneinfo/${cfg_timezone}" /etc/localtime
	}
}

rc.main() {
	source "/etc/rc.conf"

	action="${1:-boot}"

	case "$action" in
		boot)
			echo "Welcome to $(uname -rs)"
			rc.boot
		;;

		poweroff|reboot|shutdown|halt)
			rc.shutdown
		;;
	esac
}

# Main part
rc.main "$@"
