#!/bin/sh
set -eu

ROOT="${SOLO_XORG_ROOT:-}"
STATE_DIR="$ROOT/var/lib/solosupport-host-agent/display-manager"
MODE="${1:-install}"

backup_file() {
  relative_path="$1"
  backup_name="$2"
  target="$ROOT$relative_path"
  install -d -m 0700 "$STATE_DIR"
  if [ -f "$STATE_DIR/$backup_name.presence" ]; then
    return
  fi
  printf '%s
' "$relative_path" > "$STATE_DIR/$backup_name.path"
  if [ -e "$target" ]; then
    cp -p "$target" "$STATE_DIR/$backup_name.backup"
    printf 'present
' > "$STATE_DIR/$backup_name.presence"
  else
    printf 'absent
' > "$STATE_DIR/$backup_name.presence"
  fi
}

restore_file() {
  backup_name="$1"
  if [ ! -f "$STATE_DIR/$backup_name.presence" ] || [ ! -f "$STATE_DIR/$backup_name.path" ]; then
    return
  fi
  relative_path="$(sed -n '1p' "$STATE_DIR/$backup_name.path")"
  target="$ROOT$relative_path"
  if [ "$(sed -n '1p' "$STATE_DIR/$backup_name.presence")" = "present" ]; then
    install -d -m 0755 "$(dirname "$target")"
    cp -p "$STATE_DIR/$backup_name.backup" "$target"
  else
    rm -f "$target"
  fi
  rm -f "$STATE_DIR/$backup_name.backup" "$STATE_DIR/$backup_name.path" "$STATE_DIR/$backup_name.presence"
}

set_ini_value() {
  target="$1"
  section="$2"
  key="$3"
  value="$4"
  temporary="$(mktemp "$target.tmp.XXXXXX")"
  awk -v target_section="$section" -v target_key="$key" -v target_value="$value" '
    BEGIN { in_target = 0; found_section = 0; wrote_key = 0 }
    /^[[:space:]]*\[[^]]+\][[:space:]]*$/ {
      if (in_target && !wrote_key) {
        print target_key "=" target_value
        wrote_key = 1
      }
      section_name = $0
      sub(/^[[:space:]]*\[/, "", section_name)
      sub(/\][[:space:]]*$/, "", section_name)
      in_target = section_name == target_section
      if (in_target) found_section = 1
      print
      next
    }
    in_target && $0 ~ "^[[:space:]]*[#;]?[[:space:]]*" target_key "[[:space:]]*=" {
      if (!wrote_key) {
        print target_key "=" target_value
        wrote_key = 1
      }
      next
    }
    { print }
    END {
      if (!found_section) {
        if (NR > 0) print ""
        print "[" target_section "]"
        print target_key "=" target_value
      } else if (in_target && !wrote_key) {
        print target_key "=" target_value
      }
    }
  ' "$target" > "$temporary"
  chmod 0644 "$temporary"
  mv "$temporary" "$target"
}

mark_reboot_required() {
  install -d -m 0755 "$ROOT/var/run"
  : > "$ROOT/var/run/reboot-required"
  package_list="$ROOT/var/run/reboot-required.pkgs"
  touch "$package_list"
  if ! grep -Fqx 'solosupport-host-agent' "$package_list"; then
    printf 'solosupport-host-agent
' >> "$package_list"
  fi
}

require_xorg_session() {
  set -- "$ROOT/usr/share/xsessions/"*.desktop
  if [ ! -e "$1" ]; then
    echo "SoLoSupport requires an installed Xorg desktop session under /usr/share/xsessions before unattended login can be enabled." >&2
    exit 1
  fi
}

detect_display_manager() {
  configured="$ROOT/etc/X11/default-display-manager"
  if [ -r "$configured" ]; then
    basename "$(sed -n '1p' "$configured")"
    return
  fi
  if [ -e "$ROOT/etc/gdm3/custom.conf" ]; then
    printf 'gdm3
'
  elif [ -e "$ROOT/etc/gdm/custom.conf" ]; then
    printf 'gdm
'
  elif [ -d "$ROOT/etc/sddm.conf.d" ] || [ -e "$ROOT/etc/sddm.conf" ]; then
    printf 'sddm
'
  elif [ -d "$ROOT/etc/lightdm" ]; then
    printf 'lightdm
'
  fi
}

configure_gdm() {
  manager="$1"
  if [ "$manager" = "gdm3" ]; then
    relative_path="/etc/gdm3/custom.conf"
  else
    relative_path="/etc/gdm/custom.conf"
  fi
  target="$ROOT$relative_path"
  backup_file "$relative_path" gdm
  install -d -m 0755 "$(dirname "$target")"
  if [ ! -e "$target" ]; then
    printf '[daemon]
' > "$target"
  fi
  set_ini_value "$target" daemon WaylandEnable false
}

configure_sddm() {
  relative_path="/etc/sddm.conf.d/99-solosupport-xorg.conf"
  target="$ROOT$relative_path"
  backup_file "$relative_path" sddm
  install -d -m 0755 "$(dirname "$target")"
  install -d -m 0700 "$ROOT/var/lib/solosupport-host-agent/disabled-wayland-sessions"
  printf '%s
'     '[General]'     'DisplayServer=x11'     ''     '[X11]'     'SessionDir=/usr/local/share/xsessions,/usr/share/xsessions'     ''     '[Wayland]'     'SessionDir=/var/lib/solosupport-host-agent/disabled-wayland-sessions'     > "$target"
  chmod 0644 "$target"

  main_relative_path="/etc/sddm.conf"
  main_target="$ROOT$main_relative_path"
  backup_file "$main_relative_path" sddm-main
  if [ ! -e "$main_target" ]; then
    : > "$main_target"
  fi
  set_ini_value "$main_target" General DisplayServer x11
  set_ini_value "$main_target" X11 SessionDir /usr/local/share/xsessions,/usr/share/xsessions
  set_ini_value "$main_target" Wayland SessionDir /var/lib/solosupport-host-agent/disabled-wayland-sessions
}

configure_lightdm() {
  relative_path="/etc/lightdm/lightdm.conf.d/99-solosupport-xorg.conf"
  target="$ROOT$relative_path"
  backup_file "$relative_path" lightdm
  install -d -m 0755 "$(dirname "$target")"
  printf '%s
'     '[LightDM]'     'sessions-directory=/usr/local/share/xsessions:/usr/share/xsessions'     > "$target"
  chmod 0644 "$target"

  main_relative_path="/etc/lightdm/lightdm.conf"
  main_target="$ROOT$main_relative_path"
  backup_file "$main_relative_path" lightdm-main
  if [ ! -e "$main_target" ]; then
    : > "$main_target"
  fi
  set_ini_value "$main_target" LightDM sessions-directory /usr/local/share/xsessions:/usr/share/xsessions
}

if [ "$MODE" = "purge" ]; then
  restore_file gdm
  restore_file sddm-main
  restore_file sddm
  restore_file lightdm-main
  restore_file lightdm
  mark_reboot_required
  exit 0
fi

if [ "$MODE" != "install" ]; then
  echo "Usage: configure-xorg-login install|purge" >&2
  exit 2
fi

require_xorg_session
display_manager="$(detect_display_manager)"
case "$display_manager" in
  gdm3|gdm)
    configure_gdm "$display_manager"
    ;;
  sddm)
    configure_sddm
    ;;
  lightdm)
    configure_lightdm
    ;;
  *)
    echo "SoLoSupport could not identify a supported display manager. Supported managers are GDM, SDDM, and LightDM." >&2
    exit 1
    ;;
esac

mark_reboot_required
echo "SoLoSupport configured $display_manager for unattended Xorg login. Reboot the computer to apply the login-screen change."
