#!/bin/bash
#
# Purpose : Check that this CoreDesktop machine works: services, firewall,
#           desktop, and CoreDesktop's own commands. Runs in the smoketest VM.
#           Prints ok or FAIL for each check, and exits 1 if any failed.

COREDESKTOP="$HOME/.local/share/coredesktop"

# Units that may fail in the VM without anything being wrong with CoreDesktop
EXPECTED_FAILED_UNITS=(
  fwupd-refresh.service   # the VM's firmware has nothing for fwupd to check
)

FAILED=0

check() {
  local description="$1"
  shift
  if "$@" &> /dev/null; then
    echo "ok   $description"
  else
    echo "FAIL $description"
    FAILED=1
  fi
}

# Failed units, apart from EXPECTED_FAILED_UNITS. $1 is --system or --user.
failed_units() {
  systemctl "$1" list-units --state=failed --no-legend --plain | awk '{print $1}' \
    | grep -vxF -f <(printf '%s\n' "${EXPECTED_FAILED_UNITS[@]}")
}

# The unit is enabled, unless audit turned it off
enabled_unless_off() {
  grep -qsx "system $1" "$HOME/.config/coredesktop/services-off" && return 0
  systemctl is-enabled "$1"
}

up_to_date_with_upstream() {
  git -C "$COREDESKTOP" fetch --quiet \
    && [ "$(git -C "$COREDESKTOP" rev-parse HEAD)" = "$(git -C "$COREDESKTOP" rev-parse '@{upstream}')" ]
}

no_local_changes() {
  [ -z "$(git -C "$COREDESKTOP" status --porcelain --untracked-files=no)" ]
}

# GNOME Shell is running for this user on a graphical seat
desktop_running() {
  pgrep -u "$USER" -x gnome-shell \
    && loginctl list-sessions --no-legend | awk -v u="$USER" '$3 == u && $4 == "seat0"' | grep -q .
}

firewall_active() {
  sudo ufw status | grep -qx 'Status: active'
}

commands_current() {
  local cmd
  for cmd in update refresh sibling version configure audit; do
    cmp -s "$HOME/.local/bin/$cmd" "$COREDESKTOP/$cmd" || return 1
  done
}

version_ok() {
  local out
  out="$("$HOME/.local/bin/version")" || return 1
  [[ "$out" == CoreDesktop* && "$out" != *modified* ]]
}

for unit in --system --user; do
  failed="$(failed_units "$unit")"
  if [ -z "$failed" ]; then
    echo "ok   no failed ${unit#--} units"
  else
    echo "FAIL failed ${unit#--} units: $(echo "$failed" | tr '\n' ' ')"
    FAILED=1
  fi
done

# packages.conf lists the services install.sh enables
source "$COREDESKTOP/packages.conf"
for service in "${SERVICES[@]}" "${START_SERVICES[@]}"; do
  check "$service is enabled" enabled_unless_off "$service"
done
for service in "${START_SERVICES[@]}"; do
  check "$service is running" systemctl is-active "$service"
done

check "GNOME is running" desktop_running
check "the firewall is on" firewall_active
check "the Federated repo is in pacman.conf" grep -q '^\[federated\]' /etc/pacman.conf
check "Snapper is set up (if / is btrfs)" \
  bash -c '[ "$(findmnt -no FSTYPE /)" != btrfs ] || [ -f /etc/snapper/configs/root ]'
check "CoreDesktop is on upstream's latest commit" up_to_date_with_upstream
check "CoreDesktop's checkout has no local changes" no_local_changes
check "the commands in ~/.local/bin are current" commands_current
check "version works" version_ok
check "audit --list works" "$HOME/.local/bin/audit" --list
check "the shell setup is in ~/.bashrc" grep -q coredesktop "$HOME/.bashrc"

exit $FAILED
