#!/usr/bin/env bash

set -euo pipefail

fail() {
    printf 'Home Assistant helper contract: %s\n' "$1" >&2
    exit 1
}

project_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
helper="$project_root/config/dot/quickshell/scripts/panama-home-assistant"

[[ -x "$helper" ]] || fail 'helper is missing or not executable'

# The helper exits 2 for any catalog it could not complete -- including both
# cases below, which are not defects. Taking the status deliberately rather than
# letting `set -e` act on it is what makes those skips reachable at all: they
# were not. On a machine with no token, or with the server simply switched off,
# this line aborted the script before either could run, and the contract failed
# with no output whatsoever -- which reads as a crash rather than as a skip.
catalog=""
catalog_status=0
catalog="$("$helper" catalog 2>/dev/null)" || catalog_status=$?

[[ -n "$catalog" ]] || fail "the helper produced no output (exit $catalog_status)"
jq -e . >/dev/null 2>&1 <<<"$catalog" || fail 'the helper did not answer with JSON'

reason="$(jq -r '.error // "unknown"' <<<"$catalog")"

# This asserts a LIVE, authenticated Home Assistant. An absent credential is not
# a defect in Panama, so it skips rather than fails -- otherwise the suite is red
# on any machine that has not been given a token, and a red suite that is
# expected to be red stops being read.
if [[ "$(jq -r '.configured' <<<"$catalog")" != "true" ]]; then
    printf 'Home Assistant helper contract: SKIP (no token configured)\n'
    printf '  Set PANAMA_HOME_ASSISTANT_TOKEN in config/bash/env to exercise this.\n'
    printf '  Reason reported by the helper: %s\n' "$reason"
    exit 0
fi

# Configured, but nothing answered: off the network, the VPN down, or the server
# itself asleep. Also not a defect in Panama, and the same reasoning as the
# extras contract skipping when dnf or Flathub cannot be reached.
#
# Only "unreachable", which the helper raises exclusively for a timeout or a
# socket error. A bridge that ANSWERS and refuses -- authentication-required,
# request-failed, invalid-response -- is a configured-but-broken bridge, which
# is exactly the case worth catching, so those still fail.
if [[ "$reason" == "unreachable" ]]; then
    printf 'Home Assistant helper contract: SKIP (configured, but the bridge did not answer)\n'
    printf '  Nothing to assert about a server that is not there.\n'
    exit 0
fi

(( catalog_status == 0 )) || fail "the helper reported: $reason"

jq -e '
  .ok == true and .configured == true and .error == "" and
  (.entities | type == "array" and length > 0) and
  ([.entities[] | (keys | sort) == (["active", "available", "brightnessPct", "dimmable", "id", "sourceName", "state"] | sort)] | all) and
  ([.entities[] | (.id | startswith("light.")) and (.brightnessPct >= 0 and .brightnessPct <= 100)] | all) and
  (.legacyEntityIds | type == "array")
' <<<"$catalog" >/dev/null || fail 'live catalog shape is invalid'

printf 'Home Assistant helper contract: PASS (configured=true, %s lights; contents redacted)\n' \
    "$(jq '.entities | length' <<<"$catalog")"
