#!/bin/sh
# Entrypoint for the client container.
#
# Its job is to fail loudly and specifically when the container has not been
# given the access it needs. Without these checks the client starts, finds no
# devices, and leaves you guessing whether the problem is the config, the
# network or the container setup.
set -e

MODE="${1:-both}"

warn() { echo "[entrypoint] $*" >&2; }

case "$MODE" in
share | both)
	if [ ! -d /dev/bus/usb ]; then
		warn "ERROR: /dev/bus/usb is not present in the container."
		warn ""
		warn "Sharing devices needs the host's USB tree. Add to your compose file:"
		warn "    volumes:"
		warn "      - /dev/bus/usb:/dev/bus/usb"
		warn "      - /sys/bus/usb:/sys/bus/usb"
		warn "    privileged: true"
		warn ""
		warn "On macOS and Windows this cannot work at all: Docker runs in a"
		warn "Linux VM that has no access to the host's USB hardware."
		exit 1
	fi

	if [ ! -d /sys/bus/usb/devices ]; then
		warn "ERROR: /sys/bus/usb is not mounted."
		warn "Devices are enumerated through sysfs; mount it read-only at least:"
		warn "    - /sys/bus/usb:/sys/bus/usb"
		exit 1
	fi

	# Rebinding drivers after a share writes to this sysfs attribute, which
	# needs the mount to be writable.
	if [ ! -w /sys/bus/usb/devices ] 2>/dev/null; then
		warn "NOTE: /sys/bus/usb is read-only. Devices can be shared, but kernel"
		warn "drivers cannot be rebound afterwards — a device may stay unusable"
		warn "on the host until it is replugged. Mount it writable to avoid that."
	fi
	;;
esac

case "$MODE" in
use | both)
	if [ ! -d /sys/devices/platform/vhci_hcd.0 ]; then
		warn "NOTE: vhci_hcd is not available, so no remote device can be attached."
		warn "Load it on the HOST (not in the container):  sudo modprobe vhci-hcd"
		warn "Sharing local devices still works."
	fi
	;;
esac

exec usb-client "$@"
