#!/usr/bin/env bash

# panama-wifi-qr renders a saved network as a QR code a phone can scan.
#
# The QR contains the network PASSWORD in machine-readable form, so most of what
# is worth testing here is about handling that safely rather than about QR
# codes. Both nmcli and qrencode are stubbed: the real ones would read this
# machine's actual passphrases, and a test that writes the daily driver's Wi-Fi
# password into a fixture directory is not one worth having.

set -uo pipefail

repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
helper="$repo_dir/config/dot/quickshell/scripts/panama-wifi-qr"

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

work="$(mktemp -d /tmp/panama-wifiqr.XXXXXX)"
trap 'rm -rf "$work"' EXIT
mkdir -p "$work/bin" "$work/run"

readonly SECRET='hunter2-secret'

cat >"$work/bin/nmcli" <<STUB
#!/usr/bin/env bash
# -e no -t -f NAME connection show: one name per line, no field to split, so
# a name containing ':' or '\\' (real nmcli would otherwise backslash-escape
# both) comes back byte-for-byte.
if [[ "\$*" == *"-f NAME connection show"* ]]; then
    printf 'home net\n'
    printf 'work-eap\n'
    printf 'Cafe: Guest\n'
    printf 'Wired connection 1\n'
    exit 0
fi
name="\${@: -1}"
case "\$*" in
    *connection.type*)
        case "\$name" in
            "home net"|"work-eap"|"Cafe: Guest") printf '802-11-wireless\n' ;;
            "Wired connection 1") printf '802-3-ethernet\n' ;;
        esac ;;
    *802-11-wireless.ssid*)
        # An SSID containing reserved characters, to prove they are escaped.
        case "\$name" in
            "home net") printf 'home;net\n' ;;
            "work-eap") printf 'work-eap\n' ;;
            "Cafe: Guest") printf 'Cafe: Guest\n' ;;
        esac ;;
    *802-11-wireless.hidden*) printf 'no\n' ;;
    *802-11-wireless-security.psk*)
        # work-eap is enterprise: no passphrase exists to share.
        [[ "\$name" == "home net" ]] && printf '%s\n' "$SECRET" ;;
esac
exit 0
STUB
chmod +x "$work/bin/nmcli"

# Records its argv and its stdin separately, so the test can prove the secret
# arrived on stdin and never on the command line -- argv is world-readable
# through /proc while a process runs.
cat >"$work/bin/qrencode" <<'STUB'
#!/usr/bin/env bash
printf '%s\n' "$*" >>"$QRENCODE_ARGV_LOG"
out=""
prev=""
for arg in "$@"; do
    [[ "$prev" == "-o" ]] && out="$arg"
    prev="$arg"
done
cat >"$QRENCODE_STDIN_LOG"
printf 'fake-png' >"$out"
exit 0
STUB
chmod +x "$work/bin/qrencode"

export QRENCODE_ARGV_LOG="$work/argv.log"
export QRENCODE_STDIN_LOG="$work/stdin.log"
: >"$QRENCODE_ARGV_LOG"
: >"$QRENCODE_STDIN_LOG"

run() { PATH="$work/bin:$PATH" XDG_RUNTIME_DIR="$work/run" "$helper" "$@"; }

# ── Listing distinguishes shareable from not ────────────────────────────────
out="$(run list)"
jq -e . >/dev/null 2>&1 <<<"$out" || fail "list did not emit JSON: $out"
[[ "$(jq -r '.networks | length' <<<"$out")" == "3" ]] \
    || fail "only wireless connections belong in the list: $out"
jq -e '.networks[] | select(.name == "home net") | .shareable == true' >/dev/null <<<"$out" \
    || fail "a network with a passphrase must be shareable: $out"
jq -e '.networks[] | select(.name == "work-eap") | .shareable == false' >/dev/null <<<"$out" \
    || fail "an enterprise network has no passphrase, so a QR code for it cannot work: $out"

# A name containing a colon must survive intact: nmcli's terse mode would
# backslash-escape it (real nmcli escapes ':' and '\' in terse/-g output), and
# a naive colon-split parser truncates the name and misaligns the next field,
# dropping the network from the list entirely.
jq -e '.networks[] | select(.name == "Cafe: Guest")' >/dev/null <<<"$out" \
    || fail "a network name containing a colon was mangled or dropped: $out"

# ── The payload ─────────────────────────────────────────────────────────────
path="$(run qr 'home net' | jq -r .path)"
[[ -n "$path" && -e "$path" ]] || fail 'no image was produced'

payload="$(cat "$QRENCODE_STDIN_LOG")"
grep -q "P:$SECRET;" <<<"$payload" \
    || fail 'the passphrase did not reach the payload intact'

# The SSID is "home;net": unescaped, the semicolon ends the S: field early and
# the code describes a different network.
grep -qF 'S:home\;net;' <<<"$payload" \
    || fail "a reserved character in the SSID was not escaped: $payload"

[[ "$(wc -l <"$QRENCODE_STDIN_LOG")" == "0" ]] \
    || fail "the payload contains a newline; nmcli's trailing newline must be stripped: $(cat -A "$QRENCODE_STDIN_LOG")"

grep -q ';;$' <<<"$payload" || fail "the WIFI: URI must be terminated with ;;: $payload"

# ── The secret must never appear in argv ────────────────────────────────────
grep -q "$SECRET" "$QRENCODE_ARGV_LOG" \
    && fail 'the passphrase was passed as a command-line argument, where /proc exposes it to every process on the machine'

# ── The image and its directory must not be readable by others ──────────────
[[ "$(stat -c '%a' "$path")" == "600" ]] \
    || fail "the QR image is mode $(stat -c '%a' "$path"); it contains a password"
[[ "$(stat -c '%a' "$(dirname "$path")")" == "700" ]] \
    || fail "the directory holding QR images is mode $(stat -c '%a' "$(dirname "$path")")"

# ── No temporary payload files may survive ──────────────────────────────────
leftovers="$(find "$work/run" -name 'payload.*' | wc -l)"
[[ "$leftovers" == "0" ]] \
    || fail "$leftovers temporary payload file(s) containing the passphrase were left behind"

# ── An unknown network is an error, not an empty image ──────────────────────
out="$(run qr 'no-such-network')"
jq -e '.path == "" and .error != ""' >/dev/null <<<"$out" \
    || fail "an unknown network must be reported: $out"

# ── A name with a colon round-trips from list into qr ───────────────────────
# The name `list` emits must be exactly what `qr` needs to look the network
# back up; escaping it either direction breaks this lookup.
out="$(run qr 'Cafe: Guest')"
[[ "$(jq -r '.path' <<<"$out")" != "" ]] \
    || fail "a saved network name containing a colon could not be looked back up: $out"

printf 'wifi qr contract: PASS\n'
