# This file is part of ctkarch-sysconfig.
#
# ctkarch-sysconfig is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.

menu() {
  local items=('chlogindconf' "$_logindevents"
               'chhiberswap'  "$_hiberswap")
  local item="${items[0]}" err
  while
    item="$(dialogmenu --default-item "$item" 2>&1>&3)"
    [[ "$item" != '' ]]
  do
    err="$("$item" 2>&1>&3)" || mydialog --msgbox "${err}" 10 72
  done
  return 0
}

defaults() {
  # Set the first swap partition, if any, to be used for hibernation
  sethiberswap "$(blkid -lt TYPE=swap -o device)" || echo 'sethiberswap FAILED' >&2

  # Suspend when pressing the power button, because shutting down is annoying
  setlogindconf HandlePowerKey suspend || echo 'setlogindconf FAILED' >&2
}

chlogindconf() {
  local i donestuff
  while
    local items=() option _title="$_logindevents"
    for i in $(<"${moduledir}/res/logind.conf.defaults");do
      items+=("${i%=*}" "${i%=*}")
    done
    option="$(dialogmenu --default-item "$option" 2>&1>&3)"
    [[ "$option" != '' ]]
  do
    if
      local items=() value _title="$_logindevents - $option" default=''
      for i in $(<"${moduledir}/res/logind.conf.values");do
        items+=("$i" "$i")
      done
      # Load value from /etc/logind.conf; if none, its (commented) default; if none, our default
      default="$(sed -nE "s/^[[:space:]]*${option}[[:space:]]*=([^[:space:]]*)[[:space:]]*\$/\1/p;ta;b;:a;q" "${systemroot}/etc/systemd/logind.conf")"
      [ -z "$default" ] && default="$(sed -nE "s/^[[:space:]#]*${option}[[:space:]]*=([^[:space:]]*)[[:space:]]*\$/\1/p;ta;b;:a;q" "${systemroot}/etc/systemd/logind.conf")"
      [ -z "$default" ] && default="$(sed -nE "s/^[[:space:]]*${option}[[:space:]]*=([^[:space:]]*)[[:space:]]*\$/\1/p;ta;b;:a;q" "${moduledir}/res/logind.conf.defaults")"
      value="$(dialogmenu --default-item "$default" 2>&1>&3)"
      [[ "$value" != '' ]]
    then
      setlogindconf "$option" "$value" || return 1
      donestuff=1
    fi
  done
  [ -n "$donestuff" ] && mydialog --msgbox "$_explain_logindevents" 10 72
  return 0
}

# Edit uncommented variable=value line(s) in file
# parms: variable newvalue file
setvalue() {
  # here we're not editing a commented line
  if grep -qE "^[[:space:]]*${1}[[:space:]]*=" "$3" &>/dev/null;then
    sed -Ei "s/^[[:space:]]*${1}[[:space:]]*=.*$/${1}=${2}/" "$3" || return 1
  else
    echo "${1}=${2}" >> "$3" || return 1
  fi
}

# Set one of our known options (key-value pair) in /etc/logind.conf
# parms: option newvalue
setlogindconf() {
  local i keyok valueok

  # validate option name
  for i in $(<"${moduledir}/res/logind.conf.defaults");do
    [ "$1" = "${i%=*}" ] && { keyok=1; break; }
  done
  [ "$keyok" = 1 ] || { echo "invalid option '$1'" >&2; return 1; }

  # validate value
  for i in $(<"${moduledir}/res/logind.conf.values");do
    [ "$2" = "$i" ] && { valueok=1; break; }
  done
  [ "$valueok" = 1 ] || { echo "invalid value '$1=$2'" >&2; return 1; }

  # set the value in logind.conf
  setvalue "$1" "$2" "${systemroot}/etc/systemd/logind.conf" || return 1
  echo "logind, $1: $2"
}

chhiberswap() {
  local i
  local items
  mydialog --infobox "$_partitionscan" 4 40
  for i in $(blkid -t TYPE=swap -o device);do
    items+=("$i" "${i}, $(LANG=C fdisk -l "$i" | sed -n "s|^Disk ${i}: \([^,]*\),.*\$|\1|p")")
  done
  items+=('' "$_hiberswap_undo")

  local partition
  local _title="$_hiberswap"
  if partition="$(dialogmenu 2>&1>&3)";then
    mydialog --infobox "$_genramdisk" 4 60
    sethiberswap "$partition" || return 1
    mydialog --msgbox "$_explain_hiberswap" 10 72
  fi
}

# Set the swap partition to resume from in bootloaders and the initramfs hook, or unset all that
# parm: swap_partition|''
sethiberswap() {
  local swap="$1"
  if [ -n "$1" ];then
    declare -A attrs
    local i
    for i in $(blkid "$1" -o export);do attrs["${i%=*}"]="${i#*=}";done

    # exit if we're not given swap
    [[ "${attrs[TYPE]}" == 'swap' ]] || { echo "$1 is not swap." >&2; return 1; }

    # configure resume=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx in bootloaders
    local param="resume=UUID=${attrs[UUID]}"
    # in /boot/syslinux/syslinux.cfg, /boot/grub/grub.cfg & /boot/grub/menu.lst
    for i in "${systemroot}/boot/"{syslinux/syslinux.cfg,grub/menu.lst,grub/grub.cfg};do
      if [ -f "$i" ];then
        sed -Ei '/^[[:space:]]*(kernel|KERNEL|linux|LINUX)[[:space:]]+.*vmlinuz-linux.*$/s/[[:space:]]resume=[^[:space:]$]*//' "$i"
        sed -Ei 's/^([[:space:]]*(kernel|KERNEL|linux|LINUX)[[:space:]]+.*vmlinuz-linux.*)$/\1 '"${param}"'/' "$i"
      fi
    done
    # and in /etc/default/grub for people who use grub-mkconfig
    if [ -f "${systemroot}/etc/default/grub" ];then
      # remove resume=foo and add it again with the right partition
      sed -Ei "/^([[:space:]]*GRUB_CMDLINE_LINUX=.*)/{s/[[:space:]]*resume=[^[:space:]\"']*//
               s/([[:space:]])[[:space:]]*/\1/g}" "${systemroot}/etc/default/grub"
      sed -Ei "s/^([[:space:]]*GRUB_CMDLINE_LINUX=(\"|')?[^\"']*)((\"|')?)[[:space:]]*$/\1 ${param}\3/
               s/^([[:space:]]*GRUB_CMDLINE_LINUX=(\"|')?) /\1/" "${systemroot}/etc/default/grub"
    fi

    # make sure the resume hook is in the initramfs
    if ! grep -qE '^[[:space:]]*HOOKS=.*resume' "${systemroot}/etc/mkinitcpio.conf";then
      sed -Ei '/^[[:space:]]*HOOKS=/s/filesystems/resume filesystems/' "${systemroot}/etc/mkinitcpio.conf" || return 1
      chroot_command mkinitcpio -p linux >&2 || return 1
    fi
  else
    swap='none'
    # remove resume=something everywhere it might be
    for i in "${systemroot}/boot/"{syslinux/syslinux.cfg,grub/menu.lst,grub/grub.cfg};do
      if [ -f "$i" ];then
        sed -Ei '/^[[:space:]]*(kernel|KERNEL|linux|LINUX)[[:space:]]+.*vmlinuz-linux.*$/s/[[:space:]]resume=[^[:space:]$]*//' "$i"
      fi
    done
    if [ -f "${systemroot}/etc/default/grub" ];then
      sed -Ei "/^([[:space:]]*GRUB_CMDLINE_LINUX=.*)/{s/[[:space:]]*resume=[^[:space:]\"']*//
               s/([[:space:]])[[:space:]]*/\1/g}" "${systemroot}/etc/default/grub"
    fi

    # remove the resume hook from the initramfs
    if grep -qE '^[[:space:]]*HOOKS=.*resume' "${systemroot}/etc/mkinitcpio.conf";then
      sed -Ei '/^[[:space:]]*HOOKS=/s/[[:space:]]resume//' "${systemroot}/etc/mkinitcpio.conf"
      chroot_command mkinitcpio -p linux >&2 || return 1
    fi
  fi

  echo "hibernation swap partition: $swap"
}
#IMPROVE check the swap partition used for suspending to disk: how does linux choose it? Unsolved.
