#!/usr/bin/env bash

# The touchpad gestures, and the window swallowing beside them.
#
# Both are behaviour that only exists on hardware this machine may not have, so
# neither can be checked by running it. What can be pinned is the shape:
#
#   * Three gestures, mirroring GNOME. Sideways moves workspaces, up opens the
#     overview, down closes it.
#   * Up and down do not both toggle. That is the obvious way to write it and it
#     is wrong: swiping up from an open overview would close it, and swiping
#     down would reopen it, which is the opposite of what the fingers mean.
#   * Swallowing is off by default and driven by a preference. Turning it on for
#     everybody would make terminals appear to vanish on a machine nobody asked.
#   * The swallow regex names only terminals this desktop ships. Anything the
#     pattern matches can swallow, so a broad pattern is windows disappearing in
#     cases nobody intended.

set -uo pipefail

repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
input="$repo_dir/config/dot/hypr/input.lua"
looks="$repo_dir/config/dot/hypr/looks.lua"
schema="$repo_dir/config/dot/quickshell/config/PreferenceSchema.qml"

findings=()
note() { findings+=("$1"); }

# ── Gestures ─────────────────────────────────────────────────────────────────

gestures="$(grep -c 'hl\.gesture({' "$input" || true)"
(( gestures == 3 )) || note "input.lua registers $gestures gestures, not the 3 that mirror GNOME"

grep -qE 'fingers = 3, direction = "horizontal",[[:space:]]*action = "workspace"' "$input" \
    || note 'three fingers sideways does not switch workspaces'
grep -qE 'fingers = 3, direction = "up",[[:space:]]*action = overview\("open"\)' "$input" \
    || note 'three fingers up does not open the overview'
grep -qE 'fingers = 3, direction = "down",[[:space:]]*action = overview\("close"\)' "$input" \
    || note 'three fingers down does not close the overview'

# The specific mistake worth a test of its own.
if grep -qE 'direction = "(up|down)",[[:space:]]*action = overview\("toggle"\)' "$input"; then
    note 'a vertical gesture toggles the overview, so swiping the same way twice undoes itself'
fi

# The tuning that Hyprland does accept at runtime has to be reachable, or the
# gestures are unadjustable without editing this file -- which is the thing
# Settings exists to avoid.
for key in swipeDistance swipeInvert; do
    grep -q "key: \"$key\"" "$schema" \
        || note "$key is not a preference, so the gestures cannot be tuned from Settings"
done

# ── Swallowing ───────────────────────────────────────────────────────────────

grep -qE 'enable_swallow = prefs\.get\("windowSwallow", false\)' "$looks" \
    || note 'window swallowing is not preference-driven and off by default'

regex_line="$(grep -E '^\s*swallow_regex' "$looks" || true)"
[[ -n "$regex_line" ]] || note 'swallowing is enabled with no regex, so nothing can ever swallow'

# Anchored at both ends: an unanchored pattern matches any class containing the
# name, which is a much larger set than the one intended.
grep -qE 'swallow_regex\s*=\s*"\^\(.*\)\$"' "$looks" \
    || note 'the swallow regex is not anchored, so it matches more window classes than it names'

for terminal in kitty ghostty; do
    grep -q "$terminal" <<<"$regex_line" \
        || note "the swallow regex does not cover $terminal, which this desktop ships"
done

# Whatever the regex names has to be something the machine will actually have.
declared="$(cat "$repo_dir"/setup/packages/* 2>/dev/null | sed 's/#.*//' | tr -d ' ' | grep -v '^$')"
for terminal in kitty ghostty; do
    grep -qix "$terminal" <<<"$declared" \
        || note "the swallow regex names $terminal, which no package list installs"
done

# ── Report ───────────────────────────────────────────────────────────────────

if (( ${#findings[@]} > 0 )); then
    mapfile -t findings < <(printf '%s\n' "${findings[@]}" | sort -u)
    printf 'gestures contract: %d finding(s)\n' "${#findings[@]}" >&2
    printf '  - %s\n' "${findings[@]}" >&2
    exit 1
fi

printf 'gestures contract: PASS\n'
