#!/bin/bash
# test/verify_packages.sh
#
# Post-install verification of the packages the smoke test installs.
# Given a package-list file (one package per line, `@section` markers
# allowed - only the section content is verified), it checks that every
# listed package is:
#   1. installed in the pacman DB   -> `pacman -Q <pkg>`
#   2. its expected binary exists and reports a version (curated mapping)
#
# Layer 2 runs a real `--version`-style probe for packages that install a
# binary, so a broken/renamed executable is caught even if pacman reports
# the package as installed. Fonts/libs/modules without a binary are verified
# by Layer 1 only.
#
# Usage:  bash test/verify_packages.sh <package-list-file>

set -uo pipefail

PKGS_FILE="${1:?usage: verify_packages.sh <package-list-file>}"
[[ -f "$PKGS_FILE" ]] || { echo "verify_packages.sh: not a file: $PKGS_FILE" >&2; exit 1; }

PASS=0
FAIL=0
say_ok()   { printf '   ok:   %s\n' "$*"; PASS=$((PASS+1)); }
say_fail() { printf '   FAIL: %s\n' "$*"; FAIL=$((FAIL+1)); }

# ---------------------------------------------------------------------------
# Curated mapping: package -> "binary version_flag"
#   - packages not listed here are checked with pacman -Q only
#   - flag missing (empty) => existence check only
# ---------------------------------------------------------------------------
declare -A BINS=(
    [fish]="fish --version"
    [kitty]="kitty --version"
    [neovim]="nvim --version"
    [openssh]="ssh -V"
    [rclone]="rclone --version"
    [rsync]="rsync --version"
    [unison]="unison -version"
    [stow]="stow --version"
    [nodejs]="node --version"
    [npm]="npm --version"
    [starship]="starship --version"
    [fastfetch]="fastfetch --version"
    [tree-sitter-cli]="tree-sitter --version"
    [python]="python --version"
    [python-pip]="pip3 --version"
    [unzip]="unzip -v"
    [selene]="selene --version"
    [tmux]="tmux -V"
    [yazi]="yazi --version"
    [zoxide]="zoxide --version"
    [fzf]="fzf --version"
    [chromium]="chromium --version"
    [locate]="locate --version"
)

# python-pip may expose `pip` instead of `pip3` on some setups; treat them
# as interchangeable so the probe does not spuriously fail.
probe_pip() {
    for b in pip3 pip; do
        if command -v "$b" >/dev/null 2>&1; then
            out=$("$b" --version 2>&1) && [[ -n "$out" ]] && { say_ok "$b --version ($out)"; return 0; }
        fi
    done
    say_fail "python-pip: neither pip3 nor pip found/probe failed"
    return 1
}

echo "== Verifying installed packages from: $PKGS_FILE =="

while IFS= read -r line || [[ -n "$line" ]]; do
    line="${line%%#*}"               # strip trailing comments
    line="${line// /}"               # drop inline whitespace
    [[ -z "$line" ]] && continue
    [[ "$line" == @* ]] && continue  # skip @pacman/@aur/@npm section markers

    pkg="${line#*/}"                 # strip repo prefix (extra/kitty -> kitty)
    if [[ -z "$pkg" ]]; then
        say_fail "empty package name in '$line'"
        continue
    fi

    # Layer 1: installed in the pacman DB?
    if pacman -Q "$pkg" >/dev/null 2>&1; then
        say_ok "pacman -Q $pkg (installed)"
    else
        say_fail "pacman -Q $pkg (not installed)"
        continue
    fi

    # Layer 2: runtime binary probe (curated mapping)?
    spec="${BINS[$pkg]:-}"
    [[ -z "$spec" ]] && continue     # no binary (font/lib/module) - Layer 1 only

    # python-pip has special multi-candidate handling
    [[ "$pkg" == "python-pip" ]] && { probe_pip; continue; }

    read -r bin flag <<< "$spec"
    if command -v "$bin" >/dev/null 2>&1; then
        if [[ -z "$flag" ]]; then
            say_ok "command -v $bin (present)"
        else
            out=$("$bin" $flag 2>&1) && [[ -n "$out" ]]
            if [[ $? -eq 0 ]]; then
                say_ok "$bin $flag ($out)"
            else
                say_fail "$bin $flag (binary present but probe failed)"
            fi
        fi
    else
        say_fail "command -v $bin (expected from package '$pkg')"
    fi
done < "$PKGS_FILE"

echo
echo "----------------------------------------------"
echo "verify_packages.sh: $PASS passed, $FAIL failed"
echo "----------------------------------------------"
[[ $FAIL -eq 0 ]]