#!/bin/sh

set -u

return=0
summary=""
details=""

is_alert5_enabled() {
  # It's not very clear how to reliably detect if a SysVinit script
  # wrapped in a systemd unit is enabled or not.
  # Even when the script is not started in any run level, systemd says "active".
  # So we test the SysVinit script path:
  # if present, we test for an rc2.d symlink
  # if missing, we ask systemd if a unit is active or not.
  if test -f /etc/init.d/alert5; then
    test -f /etc/rc2.d/S*alert5
  else
    systemctl is-enabled alert5 | grep -q "^enabled$"
  fi
}

is_minifirewall_enabled() {
  # TODO: instead of nested conditionals, we could loop with many possible paths
  # and grep the first found, or error if none is found
  if [ -f /etc/systemd/system/minifirewall.service ]; then
    systemctl is-enabled minifirewall 2>&1 > /dev/null
  else
    if test -f /etc/rc2.d/S*alert5; then
      grep -q "^/etc/init.d/minifirewall" /etc/rc2.d/S*alert5
    else
      if test -f /usr/share/scripts/alert5.sh; then
        grep -q "^/etc/init.d/minifirewall" /usr/share/scripts/alert5.sh
      else
        return_critical "No Alert5 scripts has been found."
      fi
    fi
  fi
}

is_minifirewall_started() {
  if [ -f /etc/systemd/system/minifirewall.service ]; then
    systemctl is-active minifirewall 2>&1 > /dev/null
  else
    if test -x /usr/share/scripts/minifirewall_status; then
      /usr/share/scripts/minifirewall_status > /dev/null
    else
      /sbin/iptables -L -n | grep -q -E "^(DROP\s+(udp|17)|ACCEPT\s+(icmp|1))\s+--\s+0\.0\.0\.0\/0\s+0\.0\.0\.0\/0\s*$"
    fi
  fi
}

summary_critical() {
  summary="CRITICAL: $1"
  [ "${return}" -le 2 ] && return=2
}
summary_warning() {
  summary="WARNING: $1"
  [ "${return}" -le 1 ] && return=1
}
summary_ok() {
  summary="OK: $1"
  [ "${return}" -le 0 ] && return=0
}
append_details() {
  if [ -z "${details}" ]; then
    details="${1}\n"
  else
    details="${details}$1\n"
  fi
}

main() {
  if is_alert5_enabled; then
    append_details "alert5 is enabled"

    if is_minifirewall_enabled; then
      append_details "minifirewall is enabled"

      if is_minifirewall_started; then
        append_details "minifirewall is started"

        check_result=$(/etc/init.d/minifirewall check-active-config)
        check_rc=$?

        if [ ${check_rc} -eq 0 ]; then
          append_details "configuration is up-to-date"
          summary_ok "minifirewall is started and configuration is up-to-date"
        else
          if echo "${check_result}" | grep --ignore-case --quiet --regexp 'usage'; then
            append_details "minifirewall is too old to check active configuration"
          else
            case "${check_rc}" in
                1)
                  summary_warning "minifirewall is started, but unknown configuration state"
                ;;
                2)
                  summary_critical "minifirewall is started, but configuration is outdated"
                  append_details "configuration is outdated"
                ;;
                *)
                  summary_unchk "minifirewall is started, but unknown configuration state"
                ;;
            esac
            append_details "=> run '/etc/init.d/minifirewall check-active-config' for details"
          fi
        fi
      else
        append_details "minifirewall is stopped"
        summary_critical "minifirewall is stopped, but enabled in alert5 or systemd"
      fi
    else
      append_details "minifirewall is disabled"

      if is_minifirewall_started; then
        append_details "minifirewall is started"
        summary_warning "minifirewall is started, but disabled in alert5 or systemd"
      else
        append_details "minifirewall is stopped"
        summary_ok "minifirewall is stopped, but disabled in alert5 or systemd"
      fi
    fi
  else
    append_details "alert5 is disabled"

    if is_minifirewall_started; then
      append_details "minifirewall is started"
      summary_warning "minifirewall is started, but alert5 is disabled"
    else
      append_details "minifirewall is stopped"
      summary_ok "minifirewall is stopped and alert5 is disabled"
    fi
  fi

  printf "%s\n\n%s\n" "${summary}" "${details}"

  exit "${return}"
}

main
