#!/bin/bash
# Запуск Хоста из меню приложений с повышением прав через pkexec.
# Действие: config (по умолчанию) - окно настроек, start / stop - запуск и
# остановка службы. -start и -stop требуют root: раньше пункты «Start Host» и
# «Stop Host» звали бинарник напрямую, он отказывал, а ошибка уходила только
# в журнал (Terminal=false) - снаружи «ничего не происходит».
# Ход запуска пишется в syslog (journalctl -t r-host-config-launcher), отказ
# показывается окном: с меню Fly (Astra Linux) иначе не понять, доходит ли дело
# до pkexec и чем он кончился.

host=/opt/rut/r-host
tag=r-host-config-launcher
title="Remote Utilities Host"

log()
{
  logger -t "${tag}" -- "$*" 2>/dev/null || true
  echo "${tag}: $*" >&2
}

# Сначала - запись в журнал, потом разбор аргументов: меню DE может добавить к
# Exec свои аргументы (путь .desktop, URL), и выход на Usage до записи выглядел
# снаружи как «ничего не происходит». Неизвестный первый аргумент считаем
# запуском окна настроек.
log "started: args=[$*] uid=$(id -u) ppid=$PPID"
action="${1:-config}"
case "${action}" in
  config|start|stop) ;;
  *) log "unexpected argument '${action}', assuming config"; action=config ;;
esac

# Окно с ошибкой тем диалогом, что найдётся в системе; без него - только журнал.
show_error()
{
  local text="$1"
  if command -v kdialog >/dev/null 2>&1; then
    kdialog --title "${title}" --error "${text}" >/dev/null 2>&1 && return
  fi
  if command -v zenity >/dev/null 2>&1; then
    zenity --error --title "${title}" --text "${text}" >/dev/null 2>&1 && return
  fi
  if command -v xmessage >/dev/null 2>&1; then
    xmessage -center "${title}: ${text}" >/dev/null 2>&1 && return
  fi
}

# Current UID (don't use the built-in read-only $UID variable in bash)
uid="$(id -u)"

# Core environment with safe defaults:
# - XDG_RUNTIME_DIR is where per-user runtime files live
# - DBUS_SESSION_BUS_ADDRESS points to the user's D-Bus session bus
# - DISPLAY defaults to :0 if not provided
: "${XDG_RUNTIME_DIR:=/run/user/${uid}}"
: "${DBUS_SESSION_BUS_ADDRESS:=unix:path=${XDG_RUNTIME_DIR}/bus}"
: "${DISPLAY:=:0}"

# If XAUTHORITY is not set, try the standard location in XDG_RUNTIME_DIR
if [[ -z "${XAUTHORITY:-}" && -f "${XDG_RUNTIME_DIR}/Xauthority" ]]; then
  XAUTHORITY="${XDG_RUNTIME_DIR}/Xauthority"
fi

if [[ ! -x "${host}" ]]; then
  log "${host} is missing or not executable"
  show_error "${host} is missing or not executable."
  exit 127
fi

if ! command -v pkexec >/dev/null 2>&1; then
  log "pkexec not found (polkit is not installed)"
  show_error "pkexec (polkit) is not installed. Run '${host} -${action}' as root."
  exit 127
fi

log "action=${action} uid=${uid} DISPLAY=${DISPLAY} XAUTHORITY=${XAUTHORITY:-} XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR} DBUS_SESSION_BUS_ADDRESS=${DBUS_SESSION_BUS_ADDRESS}"

# Elevate with pkexec and pass through the required X11/DBus environment
# QT_QPA_PLATFORM=xcb forces Qt to use X11 (xcb) instead of Wayland
pkexec env \
  DISPLAY="${DISPLAY}" \
  XAUTHORITY="${XAUTHORITY:-}" \
  XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR}" \
  DBUS_SESSION_BUS_ADDRESS="${DBUS_SESSION_BUS_ADDRESS}" \
  QT_QPA_PLATFORM="xcb" \
  "${host}" "-${action}"
rc=$?

# 126 - отказ в авторизации или закрытый диалог polkit (пользователь сам
# отказался - окно не показываем), 127 - polkit не нашёл агента в сеансе или
# pkexec не запустил команду; остальное - код самого Хоста.
case "${rc}" in
  0)   log "action=${action} finished (rc=0)" ;;
  126) log "action=${action}: authorization was not granted (pkexec rc=126)" ;;
  127) log "action=${action}: pkexec could not run the command (rc=127; no polkit authentication agent in this session?)"
       show_error "Authorization failed: no polkit authentication agent is available in this session (pkexec rc=127)." ;;
  *)   log "action=${action}: ${host} exited with rc=${rc}"
       show_error "${host} -${action} exited with code ${rc}. See the host log." ;;
esac
exit "${rc}"
