#!/usr/bin/env bash

# A surface that respects the bar's reserved space must not also subtract it by
# hand.
#
# wlr-layer-shell has three behaviors and only the middle one is subtle:
#
#   exclusiveZone > 0   reserve this much space; other surfaces are pushed out
#   exclusiveZone = 0   reserve nothing, but RESPECT what others reserved
#   exclusiveZone < 0   reserve nothing and ignore what others reserved
#
# Every popover here uses 0, so the compositor has already placed it below the
# bar before its own margin applies. Adding Theme.barHeight to that margin
# counts the bar twice. That is not a crash and not a warning -- the panel
# simply opens lower than intended, which is how the control center spent its
# life hanging 38px under a bar it was written to sit 2px below, and five other
# surfaces sat at 48px instead of 12px.
#
# The rule is mechanical, so a test can hold it: with exclusiveZone 0, a margin
# is the GAP, never the gap plus what someone else reserved.
#
# Static and read-only.

set -uo pipefail

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

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

[[ -d "$modules" ]] || fail 'the modules directory is missing'

# The premise: the bar is what reserves space at the top. If that ever changes,
# the rule below stops being the right rule and this should be revisited rather
# than kept passing.
bar="$modules/bar/Bar.qml"
[[ -r "$bar" ]] || fail 'Bar.qml is missing'
grep -q 'exclusiveZone: Theme.barHeight' "$bar" \
    || fail 'the bar no longer reserves its own height, so what popovers should offset by has changed'

violations=""
checked=0

while read -r file; do
    [[ -n "$file" ]] || continue
    grep -q 'PanelWindow' "$file" || continue

    # Only surfaces that respect other zones. A surface with a negative zone is
    # positioned from the screen edge and SHOULD carry the bar height itself.
    zone="$(grep -oE 'exclusiveZone:[[:space:]]*-?[0-9]+' "$file" | head -1 | grep -oE '\-?[0-9]+$')"
    [[ "$zone" == "0" ]] || continue
    checked=$((checked + 1))

    # Margins only. Theme.barHeight is legitimate elsewhere -- sizing a row to
    # match the bar, for instance -- so this looks at the placement lines.
    offenders="$(grep -nE '^[[:space:]]*(margins\.(top|bottom)|top|bottom):.*Theme\.barHeight' "$file" || true)"
    if [[ -n "$offenders" ]]; then
        while IFS= read -r line; do
            violations+="    ${file#$repo_dir/}:${line}"$'\n'
        done <<<"$offenders"
    fi
done < <(find "$modules" -name '*.qml' | sort)

(( checked > 0 )) || fail 'no surfaces with exclusiveZone 0 were found, so this checked nothing'

if [[ -n "$violations" ]]; then
    printf 'layer margin contract: these surfaces respect the bar'"'"'s reserved space AND add it to their margin, so they open one bar-height too low:\n%s' "$violations" >&2
    exit 1
fi

printf 'layer margin contract: PASS (%d surfaces respect the bar without double-counting it)\n' "$checked"
