# daun v0.4
# Desktop-agnostic upgrade notifier - library
# Copyright (c) 2026 Raphaël Halimi <raphael.halimi@gmail.com>

#
# Variables
#

STATE="/run/daun"
REBOOT="/run/reboot-required"
PROGS="Firefox Thunderbird LibreOffice"
RESET=3000
CONFIG="/etc/daun.conf"
UID_MIN=1000
LOGINDEFS="/etc/login.defs"

# Load configuration file
[ -e "$CONFIG" ] && . "$CONFIG"

# Source gettext files
. gettext.sh
export TEXTDOMAIN=daun
export TEXTDOMAINDIR=/usr/share/locale

# Create/reset state file
if [ -e "$STATE" ] ; then
  [ $RESET -lt 0 ] && return
  NOW="$(date +%s)"
  TS="$(date -r "$STATE" +%s)"
  [ $((NOW-TS)) -ge $RESET ] && : > "$STATE"
else
  touch "$STATE"
fi


#
# Functions
#

# Print message
# ARGS: STRING
print_message () { printf "[%s] %s\n" "$0" "$1" >&2 ; }

# Print error
# ARGS: STRING
print_error () { print_message "ERROR: $1" ; }

# Die
# ARGS: STRING
die () { print_error "${1:-Fatal error}" ; exit 1 ; }

# Get list of logged-in UIDs
# ARGS: none
get_uids () { loginctl list-users --no-legend | cut -d ' ' -f 1 | sort -u ; }

# Check if we should/can notify
check_notify () {
  local UID MIN
  UID="$1"

  # Check system user
  [ -e "$LOGINDEFS" ] && MIN="$(sed -n -E '/^UID_MIN/ { s/^.*[[:blank:]]+// ; p ; q }' "$LOGINDEFS")"
  [ $UID -ge ${MIN:-$UID_MIN} ] || { print_error "System user" ; return 1 ; }

  # Check notification daemon
  busctl --machine="$(id -un $UID)"@ --user status org.freedesktop.Notifications >/dev/null 2>&1 || { print_error "Notification daemon not found" ; return 1 ; }
}

# Get user's locale
# ARGS: UID
set_locale () {
  local SESSION LEADER SESSLANG
  for SESSION in $(loginctl show-user $1 -p Sessions --value) ; do
    LEADER="$(loginctl show-session $SESSION -p Leader --value 2>/dev/null)"
    SESSLANG="$(sed -z -n s/^LANG=//p "/proc/$LEADER/environ" 2>/dev/null)"
    [ "$SESSLANG" ] && { export LANG="$SESSLANG" ; return ; }
  done
  export LANG=C
}

# Notify user
# ARGS: UID TYPE [PROG]
notify () {
  local UID TYPE PROG TITLE BODY
  UID="$1"
  TYPE="$2"
  PROG="$3"

  # Check state file
  grep -q -E -x "$UID,$TYPE,$PROG" "$STATE" && return 0

  # Set notification text
  case "$TYPE" in
    reboot) TITLE="$(gettext "System reboot required")" BODY="$(gettext "An essential system component has been updated. Please reboot your computer as soon as possible.")" ;;
    session) TITLE="$(gettext "Session restart required")" BODY="$(gettext "The system has been updated. Please restart your session as soon as possible.")" ;;
    program) TITLE="$(gettext "Restart of") $PROG $(gettext "required")" BODY="$PROG $(gettext "(or one of its libraries) has been updated. Please restart it as soon as possible.")" ;;
  esac

  # Notify user
  busctl --user --machine="$(id -un $UID)"@ -- call org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications Notify 'susssasa{sv}i' "$(gettext "Upgrade notifier")" 0 "dialog-warning" "$TITLE" "$BODY" 0 1 "urgency" y 2 -1 >/dev/null || return 1

  # Update state file
  printf "%s,%s,%s\n" "$UID" "$TYPE" "$PROG" >> "$STATE"
}


#
# Checks
#

# Check dependencies
for COMMAND in loginctl busctl ; do
  command -v "$COMMAND" >/dev/null || die "Command '$COMMAND' not found"
done

# vim: ft=sh
