#!/usr/sbin/openrc-run

set -e

description="Load drivers via vdevd modprobe coldplug phase"

depend()
{
	after mountkernfs.sh
	before vdev mountdevsubfs.sh
	provide vdev-modprobe
	keyword -containers
}

_json="${VDEV_GLOBALS_JSON:-/etc/vdev/vdevd.globals.json}"

if [ -r "${_json}" ] && command -v jq >/dev/null 2>&1; then
	VDEV_JSON_DATA="$(sed -E 's|//.*||g' "${_json}" |
		sed 's|/\*.*\*/||g' |
		grep -v '^$' |
		jq -r .)"
	export VDEV_JSON_DATA
else
	VDEV_CONFIG_DIR="/etc/vdev"
	VDEV_MODPROBE="vdevd.0.conf"
	VDEV_MODPROBE_STAMP="/run/vdev/vdevd-0-coldplug.ready"
fi

get_json_get_key() {
	printf '%s' "${VDEV_JSON_DATA}" | jq -r --arg k "$1" '
		.globals[$k] // empty
	' 2>/dev/null
}

get_json_get_config() {
	printf '%s' "${VDEV_JSON_DATA}" | jq -r --arg s "$1" '
		.states[$s].config // empty
	' 2>/dev/null
}

get_json_get_stamp() {
	printf '%s' "${VDEV_JSON_DATA}" | jq -r --arg s "$1" '
		.states[$s].stamp // empty
	' 2>/dev/null
}

if [ -n "${VDEV_JSON_DATA}" ]; then
	_config_dir="$(get_json_get_key "config-dir")"
	VDEV_CONFIG_DIR="${_config_dir:-/etc/vdev}"

	_modprobe="$(get_json_get_config "modprobe")"
	VDEV_MODPROBE="${_modprobe:-vdevd.0.conf}"

	_stamp_dir="$(get_json_get_key "states-stamp-dir")"
	VDEV_STAMP_DIR="${_stamp_dir:-/run/vdev}"

	_stamp_modprobe="$(get_json_get_stamp "modprobe")"
	VDEV_MODPROBE_STAMP="${VDEV_STAMP_DIR}/${_stamp_modprobe:-vdevd-0-coldplug.ready}"

	_json_modprobe_bg="$(printf '%s' "${VDEV_JSON_DATA}" |
		jq -r '(.globals["modprobe-phase-background"] // false)' 2>/dev/null)"
fi

: "${VDEV_BIN:=/sbin/vdevd}"
[ -x "${VDEV_BIN}" ] || exit 0

: "${VDEV_MOUNTPOINT:=/dev}"

case "${VDEV_MODPROBE_BACKGROUND:+x}" in
	x) ;;
	*) VDEV_MODPROBE_BACKGROUND="${_json_modprobe_bg:-false}" ;;
esac

load_boot_vga_kms()
{
	local boot_file pci_dir alias_string

	for boot_file in /sys/bus/pci/devices/*/boot_vga; do
		[ -f "${boot_file}" ] || continue
		[ "$(cat "${boot_file}")" = "1" ] || continue
		pci_dir=$(dirname "${boot_file}")
		[ -f "${pci_dir}/modalias" ] || continue
		alias_string=$(cat "${pci_dir}/modalias")
		case "${alias_string}" in
			*v00008086*|*v000010DE*|*v00001002*)
				modprobe -q "${alias_string}" 2>/dev/null || true
				;;
			*)
				[ -n "${alias_string}" ] && modprobe -q nouveau 2>/dev/null || true
				;;
		esac
		break
	done
}

start()
{
	rm -f "${VDEV_MODPROBE_STAMP}" 2>/dev/null || true

	load_boot_vga_kms

	export VDEV_JSON_STATE=modprobe
	modprobe -q usbcore
	modprobe -q xhci_hcd

	ebegin "Running vdevd modprobe coldplug"
	"${VDEV_BIN}" -c "${VDEV_CONFIG_DIR}/${VDEV_MODPROBE}" "${VDEV_MOUNTPOINT}"
	eend $?
}
