#!/bin/sh -e
### BEGIN INIT INFO
# Provides:          vdev-settle
# Required-Start:    $local_fs
# Required-Stop:
# Should-Start:      vdev $network
# Default-Start:     S
# Default-Stop:
# Short-Description: Wait for vdev two-phase startup to settle
# X-Start-Before:    display-manager
### END INIT INFO

PATH="/sbin:/bin:/usr/bin"
. /lib/lsb/init-functions

# Top priority: find out the JSON file
# If there is no environment variable, we search the system's default path
_json="${VDEV_GLOBALS_JSON:-/etc/vdev/vdevd.globals.json}"

VDEV_HELPERS_DIR="/lib/vdev"
VDEV_STATE_DIR="/run/vdev"
VDEV_STAMP_DIR="/run/vdev"
VDEV_MODPROBE_STAMP="/run/vdev/vdevd-0-coldplug.ready"
VDEV_EARLY_STAMP="/run/vdev/vdevd-1-coldplug.ready"

if [ -r "$_json" ] && command -v jq >/dev/null 2>&1; then
    # Clean up comments // and also /* */
	VDEV_JSON_DATA="$(sed -E 's|//.*||g' "$_json" |
        sed 's|/\*.*\*/||g' |
        grep -v '^$' |
        jq -r .)"
    export VDEV_JSON_DATA
fi

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

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

if [ -n "$VDEV_JSON_DATA" ]; then
    _helpers_dir="$(get_json_get_key "helpers-dir")"
    VDEV_HELPERS_DIR="${_helpers_dir:-/lib/vdev}"

    _state_dir="$(get_json_get_key "states-stamp-dir")"
    if [ -z "$_state_dir" ]; then
        _state_dir="$(get_json_get_key "stamp_dir")"
    fi
    VDEV_STATE_DIR="${_state_dir:-/run/vdev}"
    VDEV_STAMP_DIR="${_state_dir:-/run/vdev}"

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

    _stamp_early="$(get_json_get_stamp "early")"
    VDEV_EARLY_STAMP="${VDEV_STAMP_DIR}/${_stamp_early:-vdevd-1-coldplug.ready}"
fi

export VDEV_STATE_DIR VDEV_HELPERS_DIR

vdev_input_settle_worker() {
    if ! command -v vdevadm >/dev/null 2>&1; then
        echo "vdev-settle: vdevadm not found" >&2
        return 1
    fi
    vdevadm settle --input-worker \
        --stamp-early="$VDEV_EARLY_STAMP" \
        --settle-bin="${VDEV_HELPERS_DIR}/vdev_settle" \
        -t 15
}

case "$1" in
    start)
        log_daemon_msg "Waiting for vdev settle" "vdev-settle"

        if command -v vdevadm >/dev/null 2>&1; then
            # vdevd.0: wait for os-queue-tracking stamp (VDEV_OS_QUEUE_TRACKING_FLAG=1).
            vdevadm settle --stamp="$VDEV_MODPROBE_STAMP" -t 5 || true

            # vdevd.1: wait for os-queue-tracking stamp (VDEV_OS_QUEUE_TRACKING_FLAG=2).
            vdevadm settle --stamp="$VDEV_EARLY_STAMP" -t 5 || true
        fi

        # Detached worker: libinput monitor + sysfs uevent re-add; does not block init stop.
        (
            vdev_input_settle_worker
        ) >/dev/null 2>&1 &
        ;;
    stop)
        if command -v vdevadm >/dev/null 2>&1; then
            vdevadm control --stop-settle
        fi
        ;;
    restart|force-reload|status)
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|force-reload|status}" >&2
        exit 1
        ;;
esac

exit 0
