#!/usr/bin/env bash

# Anything instantiated per screen must take its screen from `modelData`.
#
# Variants supplies each delegate a `modelData` holding the screen. A component
# that instead declares `required property var screen` is constructed, never
# receives a screen, and its window silently never maps -- with nothing logged,
# no error, and no visible failure beyond the surface simply not being there.
#
# shell.qml has warned about this in a comment since the Bar hit it. The comment
# did not stop the window switcher hitting it again, which is the argument for a
# test: the failure is invisible, so review does not catch it either.

set -uo pipefail

repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
shell_file="$repo_dir/config/dot/quickshell/shell.qml"
modules="$repo_dir/config/dot/quickshell/modules"

fail() {
    printf 'per-screen surface contract: %s\n' "$1" >&2
    exit 1
}

[[ -r "$shell_file" ]] || fail "cannot read shell.qml"

# The component named inside each `Variants { model: Quickshell.screens ... }`.
delegates="$(awk '
    /Variants \{/ { inside = 1; next }
    inside && /model: Quickshell.screens/ { armed = 1; next }
    armed && /^[[:space:]]*[A-Z][A-Za-z]* *\{/ {
        match($0, /[A-Z][A-Za-z]*/)
        print substr($0, RSTART, RLENGTH)
        armed = 0; inside = 0
    }
' "$shell_file" | sort -u)"

[[ -n "$delegates" ]] || fail 'found no per-screen delegates -- this contract is not reading shell.qml correctly'

checked=0
while read -r name; do
    [[ -n "$name" ]] || continue

    file="$(find "$modules" -name "$name.qml" -print -quit 2>/dev/null)"
    [[ -n "$file" ]] || fail "shell.qml instantiates $name per screen, but $name.qml was not found"

    if grep -qE '^\s*required property var screen\b' "$file"; then
        fail "$name declares 'required property var screen', but Variants supplies modelData -- the window is built and never maps, silently. Use 'property var modelData' and bind screen to it, as Bar and Dock do."
    fi

    grep -qE '^\s*property var modelData' "$file" \
        || fail "$name is instantiated per screen but never declares 'property var modelData', so it cannot know which screen it is on"

    grep -qE 'screen: (root\.)?modelData' "$file" \
        || fail "$name declares modelData but never binds a screen to it"

    checked=$((checked + 1))
done <<<"$delegates"

printf 'per-screen surface contract: PASS (%d per-screen surfaces)\n' "$checked"
