# 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=('chlimitjournal'   "$_limitjournalsize"
               'chservicetimeout' "$_systemdtimeout"
               'chlogcoredumps'   "$_coredumplogs"
               'chlogstorage'     "$_logstorage")
  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() {
  # Limit total journal size to 50MB, it's better than unlimited.
  setlimitjournal 50 || echo 'setlimitjournal FAILED' >&2

  # 30 seconds seems long enough; anyway 90 is way too much on a personal computer
  setsystemdtimeouts 30 || echo 'setsystemdtimeouts FAILED' >&2

  # By default, do not incomprehensibly overload disk IO with logging core dumps.
  # It generally fails anyway, after having slowed down the system.
  setlogcoredumps no || echo 'setlogcoredumps FAILED' >&2

  # Leave log storage type to auto, do nothing here.
  # Users can delete /var/log/journal/ if they don't want logs on disk.
}

chlimitjournal() {
  local journalmegs

  # Try to load a value from journald.conf, set a default if none
  if [ -f "${systemroot}/etc/systemd/journald.conf" ];then
    # First uncommented value; then first commented one if nothing was found
    journalmegs="$(sed -nE 's/^[[:space:]]*SystemMaxUse[[:space:]]*=[[:space:]]*([0-9]+)[[:space:]]*M[[:space:]]*$/\1/p;ta;b;:a;q' "${systemroot}/etc/systemd/journald.conf")"
    [ -z "$journalmegs" ] && journalmegs="$(sed -nE 's/^[#[:space:]]*SystemMaxUse[[:space:]]*=[[:space:]]*([0-9]+)[[:space:]]*M[[:space:]]*$/\1/p;ta;b;:a;q' "${systemroot}/etc/systemd/journald.conf")"
  fi
  [[ "$journalmegs" =~ ^[1-9][0-9]*$ ]] || journalmegs=50

  if journalmegs="$(mydialog --title "$_limitjournalsize" --inputbox '' 6 70 "$journalmegs" 2>&1>&3)";then
    setlimitjournal "$journalmegs" || return 1
    mydialog --msgbox "$_explain_limitjournalsize" 10 72
  fi
}

# Set value in ini file
# parm: option new_value file
setvalue() {
  [ -f "$3" ] || { echo "${3#"${systemroot}"} - $_doesntexist" >&2; return 1; }

  # if we don't need to change anything (which would confuse the logic of the steps below), return
  [ "$(sed -nE "s/^[[:space:]]*${1}[[:space:]]*=[[:space:]]*([^[:space:]]+)[[:space:]]*\$/\1/p;ta;b;:a;q" "$3")" = "$2" ] && return 0

  initialhash="$(md5sum < "$3")"

  # first try to change the first matching uncommented line
  sed -i "0,/^[[:space:]]*${1}[[:space:]]*=/s/^[[:space:]]*${1}[[:space:]]*=.*\$/${1}=${2}/" "$3" || return 1

  # if that didn't do anything, extend matching to the first commented line
  if [ "$initialhash" = "$(md5sum < "$3")" ] ;then
    sed -i "0,/^[#[:space:]]*${1}[[:space:]]*=/s/^[#[:space:]]*${1}[[:space:]]*=.*\$/${1}=${2}/" "$3" || return 1
  fi

  # if that still didn't change anything, simply add the line
  if [ "$initialhash" = "$(md5sum < "$3")" ] ;then
    echo "${1}=${2}" >> "$3" || return 1
  fi
}

# Set maximum systemd-journald journal size in megabytes
# parm: maximum_size_MB
setlimitjournal() {
  # validate for a positive integer
  [[ "$1" =~ ^[1-9][0-9]*$ ]] || { echo 'NaN' >&2; return 1; }
  setvalue SystemMaxUse "${1}M" "${systemroot}/etc/systemd/journald.conf" || return 1
  setvalue RuntimeMaxUse "${1}M" "${systemroot}/etc/systemd/journald.conf" || return 1
  echo "systemd journal size: ${1}MB"
}

chservicetimeout() {
  local timeoutsecs

  # Try to load a value from system.conf, set a default if none
  if [ -f "${systemroot}/etc/systemd/system.conf" ];then
    # First uncommented value; then first commented one if nothing was found
    timeoutsecs="$(sed -nE 's/^[[:space:]]*DefaultTimeoutStopSec[[:space:]]*=[[:space:]]*([0-9]+)[[:space:]]*s[[:space:]]*$/\1/p;ta;b;:a;q' "${systemroot}/etc/systemd/system.conf")"
    [ -z "$timeoutsecs" ] && timeoutsecs="$(sed -nE 's/^[#[:space:]]*DefaultTimeoutStopSec[[:space:]]*=[[:space:]]*([0-9]+)[[:space:]]*s[[:space:]]*$/\1/p;ta;b;:a;q' "${systemroot}/etc/systemd/system.conf")"
  fi
  [[ "$timeoutsecs" =~ ^[1-9][0-9]*$ ]] || timeoutsecs=30

  if timeoutsecs="$(mydialog --title "$_systemdtimeout" --inputbox "$_systemdtimeouthint" "$((6+(${#_systemdtimeouthint}-1)/(70-4)))" 70 "$timeoutsecs" 2>&1>&3)";then
    setsystemdtimeouts "$timeoutsecs" || return 1
    mydialog --msgbox "$_explain_systemdtimeout" 10 72
  fi
}

# Set the timeout for stopping systemd units, in seconds
# parm: seconds
setsystemdtimeouts() {
  # validate for a positive integer
  [[ "$1" =~ ^[1-9][0-9]*$ ]] || { echo 'NaN' >&2; return 1; }
  setvalue DefaultTimeoutStopSec "${1}s" "${systemroot}/etc/systemd/system.conf" || return 1
  echo "systemd default service timeout: ${1}s"
}
 
chlogcoredumps() {
  local items=('no'  "$_dontlogcoredumps"
               'yes' "$_logcoredumps")
  local choice _title="$_coredumplogs"
  if choice="$(dialogmenu 2>&1>&3)" ;then
    setlogcoredumps "$choice" || return 1
    mydialog --msgbox "$_explain_coredumplogs" 10 72
  fi
}

# Choose whether to let systemd log core dumps or not
# parm: yes|no
setlogcoredumps() {
  case "$1" in
    'yes') rm -f  "${systemroot}/etc/sysctl.d/99-nocoredumps.conf" || return 1 ;;
    'no')  install -m644 "${moduledir}/res/99-nocoredumps.conf" "${systemroot}/etc/sysctl.d/99-nocoredumps.conf" || return 1 ;;
    *)     echo "invalid parameter '$1'" >&2; return 1 ;;
  esac
  echo "log core dumps: $1"
}

chlogstorage() {
  local items=('disk' "$_logstorage_disk"
               'ram'  "$_logstorage_ram"
               'auto' "$_logstorage_auto"
               'none' "$_logstorage_none")
  local choice _title="$_logstorage"
  if choice="$(dialogmenu 2>&1>&3)" ;then
    setlogstorage "$choice" || return 1
    mydialog --msgbox "$_explain_logstorage" 10 72
  fi
}

# Choose how to store logs with journald
# parm: disk|ram|auto|none
setlogstorage() {
  case "$1" in
    'disk') setvalue Storage persistent "${systemroot}/etc/systemd/journald.conf" || return 1 ;;
    'ram')  setvalue Storage volatile   "${systemroot}/etc/systemd/journald.conf" || return 1 ;;
    'auto') setvalue Storage auto       "${systemroot}/etc/systemd/journald.conf" || return 1 ;;
    'none') setvalue Storage none       "${systemroot}/etc/systemd/journald.conf" || return 1 ;;
    *)      echo "invalid parameter '$1'" >&2; return 1 ;;
  esac
  echo "journald log storage: $1"
}
