#!/bin/sh
# Check the installed systemd service as set up by the package.
set -eu

tests_dir="$(cd "$(dirname "$0")" && pwd)"
unit=shairport-sync

fail() {
	echo "FAIL: $*" >&2
	journalctl -u "$unit" --no-pager >&2 || true
	exit 1
}

get_property() { # get_property PROPERTY
	dbus-send --system --print-reply=literal --dest=org.gnome.ShairportSync \
		/org/gnome/ShairportSync org.freedesktop.DBus.Properties.Get \
		string:org.gnome.ShairportSync "string:$1" | sed 's/^ *variant *//'
}

wait_for_active() {
	# The unit may still be starting, or waiting to be restarted after a
	# failed first start on a freshly installed system (for example when a
	# library's SONAME symlink only appears once the ldconfig trigger runs
	# after our postinst), so allow it some time to settle.
	i=0
	until systemctl is-active --quiet "$unit"; do
		i=$((i + 1))
		[ "$i" -lt 150 ] || fail "unit is not active: $(systemctl is-active "$unit" || true)"
		sleep 0.2
	done
}

wait_for_rtsp() { # wait_for_rtsp PORT
	i=0
	until "$tests_dir/rtsp-request" "$1" OPTIONS '*' >/dev/null 2>&1; do
		i=$((i + 1))
		[ "$i" -lt 100 ] || fail "timed out waiting for RTSP on port $1"
		sleep 0.2
	done
}

echo "checking the service user and runtime directory..."
getent passwd shairport-sync | grep -q ':/run/shairport-sync:' || fail "unexpected shairport-sync user entry"
[ -d /run/shairport-sync ] || fail "/run/shairport-sync does not exist"
[ "$(stat -c %U /run/shairport-sync)" = shairport-sync ] || fail "/run/shairport-sync has the wrong owner"

echo "checking the unit state..."
systemctl is-enabled "$unit" || fail "unit is not enabled"
wait_for_active

# With nqptp installed and running the service should offer AirPlay 2 on
# port 7000; otherwise classic AirPlay on port 5000.
if systemctl is-active --quiet nqptp 2>/dev/null; then
	expected_protocol="AirPlay 2"
	port=7000
else
	expected_protocol="AirPlay"
	port=5000
fi

echo "waiting for RTSP on port $port..."
wait_for_rtsp "$port"
"$tests_dir/rtsp-request" "$port" OPTIONS '*' || fail "RTSP OPTIONS failed"

echo "checking the system bus interface..."
protocol="$(get_property Protocol)"
echo "Protocol: $protocol"
[ "$protocol" = "$expected_protocol" ] || fail "expected protocol '$expected_protocol'"
version_string="$(get_property VersionString)"
[ "$version_string" = "$(shairport-sync -V)" ] || fail "VersionString does not match shairport-sync -V"

echo "restarting the service..."
systemctl restart "$unit"
wait_for_active
wait_for_rtsp "$port"

# Only look at the log of the current invocation; older boots may hold
# unrelated failures.
invocation="$(systemctl show -p InvocationID --value "$unit")"
! journalctl "_SYSTEMD_INVOCATION_ID=$invocation" --no-pager | grep -q 'fatal error' || fail "fatal error logged"
echo "OK"
