#!/usr/bin/env bash

# The lock screen follows the color scheme.
#
# It did not. hyprlock.conf shipped with Tokyo Night Moon hardcoded in six
# places, so choosing light mode left the one screen a user sees most often
# stubbornly dark. Every other surface -- kitty, GTK, the launcher, btop, tmux,
# neovim -- had been taught to follow the scheme; this was the last one.
#
# It is also the worst place to discover a theming bug, because you find out
# while locked out of the machine and cannot fix it from there. Hence a test.
#
# Generated into a fixture, never the live config: this contract must not
# retheme the lock screen of the desktop it is running on.

set -uo pipefail

repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
template="$repo_dir/config/dot/hypr/hyprlock.conf.template"
theme_apps="$repo_dir/config/dot/quickshell/scripts/panama-theme-apps"

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

[[ -r "$template" ]] || fail 'hyprlock.conf.template is missing, so nothing generates the lock screen'

# The committed template must carry no literal colors. One left behind is a
# color that silently stays dark in light mode -- exactly the original bug.
literal="$(grep -vE '^\s*#' "$template" | grep -oE 'rgba\([0-9]+, *[0-9]+, *[0-9]+' || true)"
[[ -z "$literal" ]] \
    || fail "the template still contains hardcoded colors, which will not follow the scheme: $literal"

fixture="$(mktemp -d /tmp/panama-lockscreen.XXXXXX)"
trap 'rm -rf "$fixture"' EXIT
mkdir -p "$fixture/hypr"
cp "$template" "$fixture/hypr/"

for scheme in dark light; do
    XDG_CONFIG_HOME="$fixture" "$theme_apps" "$scheme" >/dev/null 2>&1
    generated="$fixture/hypr/hyprlock.conf"

    [[ -r "$generated" ]] || fail "no hyprlock.conf was generated for $scheme"

    # An unsubstituted placeholder is not a parse error to hyprlock; it is an
    # invalid color it quietly ignores, falling back to its own default.
    leftover="$(grep -oE '@[A-Z_]+@' "$generated" || true)"
    [[ -z "$leftover" ]] \
        || fail "$scheme left placeholders unsubstituted: $leftover"

    # Every color hyprlock is given must be a complete decimal triple. It
    # takes rgba(r, g, b, a), NOT hex, and a hex value here is silently ignored.
    while read -r color; do
        [[ -n "$color" ]] || continue
        grep -qE '^rgba\([0-9]{1,3}, [0-9]{1,3}, [0-9]{1,3}$' <<<"$color" \
            || fail "$scheme produced a malformed color: $color"
    done < <(grep -vE '^\s*#' "$generated" | grep -oE 'rgba\([^)]*' | sed 's/,[^,]*$//')

    # The Pango markup values are hex, and hyprlock wants them doubled-hashed.
    while read -r pango; do
        [[ -n "$pango" ]] || continue
        grep -qE '^##[0-9a-f]{6}$' <<<"$pango" \
            || fail "$scheme produced malformed Pango markup color: $pango"
    done < <(grep -vE '^\s*#' "$generated" | grep -oE '##[0-9a-fA-F]{6}')

    # The whole background block, not a fixed number of lines after it: the
    # color sits near the end, after the blur and noise settings.
    background="$(awk '/^background \{/,/^\}/' "$generated" \
        | grep -vE '^\s*#' | grep -oE 'color = rgba\([0-9]+' | grep -oE '[0-9]+$' | head -1)"
    [[ -n "$background" ]] || fail "$scheme produced no background color"

    # The point of the whole exercise: a light lock screen must actually be
    # light. 128 splits the two cleanly for these palettes.
    if [[ "$scheme" == "light" ]]; then
        (( background > 128 )) \
            || fail "light mode produced a DARK lock screen background (red channel $background) -- the original bug"
    else
        (( background < 128 )) \
            || fail "dark mode produced a LIGHT lock screen background (red channel $background)"
    fi
done

# The two schemes must actually differ, or the substitution is a no-op that
# passes every check above.
XDG_CONFIG_HOME="$fixture" "$theme_apps" dark >/dev/null 2>&1
dark_hash="$(sha256sum "$fixture/hypr/hyprlock.conf" | cut -d' ' -f1)"
XDG_CONFIG_HOME="$fixture" "$theme_apps" light >/dev/null 2>&1
light_hash="$(sha256sum "$fixture/hypr/hyprlock.conf" | cut -d' ' -f1)"
[[ "$dark_hash" != "$light_hash" ]] \
    || fail 'the light and dark lock screens are byte-identical, so the scheme is not being applied'

printf 'lock screen theme contract: PASS\n'
