#!/usr/bin/env bash

set -euo pipefail

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

cleanup() {
    qs ipc call settings close >/dev/null 2>&1 || true
}
trap cleanup EXIT

qs ipc show | rg -q '^target settings$' || fail 'settings IPC target is missing'
qs ipc call settings open >/dev/null

for _ in $(seq 1 40); do
    if hyprctl -j clients | jq -e '[.[] | select(.title == "Settings")] | length == 1' >/dev/null; then
        break
    fi
    sleep 0.1
done
hyprctl -j clients | jq -e '[.[] | select(.title == "Settings")] | length == 1' >/dev/null \
    || fail 'exactly one Settings window did not map'
hyprctl -j clients | jq -e '.[] | select(.title == "Settings" and .floating == false)' >/dev/null \
    || fail 'Settings window is not tiled'

qs ipc call settings page displays >/dev/null
[[ "$(qs ipc call settings status | jq -r .page)" == "displays" ]] || fail 'Displays page did not route'

qs ipc call settings page desktop >/dev/null
[[ "$(qs ipc call settings status | jq -r .page)" == "desktop" ]] || fail 'Desktop page did not route'

address="$(hyprctl -j clients | jq -r '.[] | select(.title == "Settings") | .address')"
hyprctl dispatch "hl.dsp.window.close({ window = \"address:$address\" })" >/dev/null
for _ in $(seq 1 40); do
    [[ "$(qs ipc call settings status | jq -r .open)" == "false" ]] && break
    sleep 0.1
done
[[ "$(qs ipc call settings status | jq -r .open)" == "false" ]] || fail 'compositor close did not synchronize shell state'

qs ipc call settings open >/dev/null
for _ in $(seq 1 40); do
    hyprctl -j clients | jq -e '.[] | select(.title == "Settings")' >/dev/null && break
    sleep 0.1
done

qs ipc call settings close >/dev/null
for _ in $(seq 1 40); do
    if ! hyprctl -j clients | jq -e '.[] | select(.title == "Settings")' >/dev/null; then
        trap - EXIT
        printf 'settings window contract: PASS\n'
        exit 0
    fi
    sleep 0.1
done

fail 'Settings window did not close'
