#!/usr/bin/env bash

# What Panama does while a game runs must be undone afterwards -- to what was
# there before, not to a default.
#
# That distinction is the whole feature. If ending a game forced Do Not Disturb
# off, it would silently undo a Do Not Disturb someone set by hand; if it forced
# the power profile to "balanced", it would undo a deliberate choice. Both are
# worse than doing nothing at all, because both look like the desktop
# misbehaving rather than a setting being wrong.
#
# Read-only: it reads gaming state and never engages Game Mode.

set -uo pipefail

repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
helper="$repo_dir/config/dot/quickshell/scripts/panama-gaming"
service="$repo_dir/config/dot/quickshell/services/Gaming.qml"
page="$repo_dir/config/dot/quickshell/modules/settings/GamingPage.qml"
shell_file="$repo_dir/config/dot/quickshell/shell.qml"

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

for path in "$helper" "$service" "$page" "$shell_file"; do
    [[ -r "$path" ]] || fail "missing $path"
done
[[ -x "$helper" ]] || fail 'panama-gaming is not executable'

# ── The hook restores, it does not impose ───────────────────────────────────
hook_body="$(sed -n '/^def hook/,/^def /p' "$helper")"
[[ -n "$hook_body" ]] || fail 'the hook is missing'
grep -q 'state_path' <<<"$hook_body" \
    || fail 'the hook records nothing about the state before a game, so it cannot restore it'
grep -qE 'before\.get\("profile"\)' <<<"$hook_body" \
    || fail 'the power profile is not restored to what it was'
# Do Not Disturb is no longer the hook's business at all. It belongs to the
# Gaming focus mode, which records what Do Not Disturb was before it took over
# and puts that back -- the same protection, in one place instead of two. The
# assertion is therefore stricter than it was: the hook must not touch it.
grep -qE 'setDnd|dndState' <<<"$hook_body" \
    && fail 'the hook writes Do Not Disturb again, so it and the focus mode both own it'
grep -q 'gameStarted' <<<"$hook_body" \
    || fail 'the hook does not report the game to the shell, so no mode can react to it'
grep -qE 'set.*"balanced"' <<<"$hook_body" \
    && fail 'the hook restores a hardcoded profile rather than the previous one'

# ── The shell can be told, not only toggled ─────────────────────────────────
# A toggle is the wrong primitive here: if notifications were already silenced,
# toggling at game start would unsilence them.
grep -q 'function setDnd(enabled: bool)' "$shell_file" \
    || fail 'there is no explicit way to set Do Not Disturb, only a toggle'
grep -q 'function dndState()' "$shell_file" \
    || fail 'there is no way to read Do Not Disturb, so the hook cannot know what to restore'
# setDnd and dndState remain the right primitives and are still asserted above --
# a toggle would flip an already-silent machine back on. What changed is who
# calls them: not this hook, which now reports the game and lets the Gaming
# focus mode decide. Asserted in the other direction a few lines up.

# ── The hook does not depend on the shell being up ──────────────────────────
# A game can start after a shell restart; a hook that asked the shell for its
# settings would silently do nothing.
grep -q 'settings.json' <<<"$hook_body" \
    || fail 'the hook reads its settings from somewhere other than the settings file'

# ── Honest reporting ────────────────────────────────────────────────────────
grep -q 'governorAlreadyThere' "$service" \
    || fail 'the service cannot tell when Game Mode would change nothing'
page_code="$(grep -vE '^\s*//' "$page")"
grep -q 'already runs that governor' <<<"$page_code" \
    || fail 'the page does not say when Game Mode has no effect on this machine'
# Proton is listed, never chosen: Steam owns that per game.
grep -qiE 'setProton|selectProton|chooseProton' <<<"$page_code" \
    && fail 'the page claims to choose the Proton build, which Steam owns per game'

# ── Polling stops when nobody is looking ────────────────────────────────────
grep -q 'running: root.watching' "$service" \
    || fail 'the poll timer runs regardless of whether the page is open'
grep -q 'Gaming.watching = false' "$page" \
    || fail 'the page never stops the poll timer, so it would poll forever after being closed'

command -v jq >/dev/null 2>&1 || { printf 'gaming contract: SKIP (no jq)\n'; exit 0; }

state="$("$helper" snapshot 2>/dev/null)" || fail 'snapshot failed'
jq -e '(.gpus | type == "array") and (.gameMode | type == "object") and (.library | type == "object")' \
    <<<"$state" >/dev/null || fail 'the snapshot is incomplete'
jq -e '.gameMode | has("active") and has("daemonRunning") and has("hooksInstalled")' <<<"$state" >/dev/null \
    || fail 'Game Mode state is incomplete'
# An integrated GPU reporting no video memory must not be described as discrete.
jq -e '[.gpus[] | select(.discrete) | .vramTotalBytes > 0] | all' <<<"$state" >/dev/null \
    || fail 'a card with no video memory is reported as the discrete one'

[[ -n "$("$helper" set-overlay-preset nonsense 2>/dev/null | jq -r '.error // ""')" ]] \
    || fail 'an unknown overlay preset was accepted'
[[ -n "$("$helper" hook nonsense 2>/dev/null | jq -r '.error // ""')" ]] \
    || fail 'an unknown hook phase was accepted'

printf 'gaming contract: PASS (%s GPU(s), %s games, hooks %s)\n' \
    "$(jq '.gpus | length' <<<"$state")" \
    "$(jq -r '.library.games' <<<"$state")" \
    "$(jq -r 'if .gameMode.hooksInstalled then "installed" else "not installed" end' <<<"$state")"
