#!/bin/bash

# shutdownasap version 1.1.1

set -e

. /etc/shutdownasap.conf

mkdir -p "${tmpDir}"
cd "${tmpDir}"

if [ $# -eq 1 ] && [ "x$1" = 'x-g' ]; then
  [ -r "${tmpDir}/pid" ] \
  && [ -d "/proc/$(cat "${tmpDir}/pid")" ] \
  && cat "${tmpDir}/intention" \
  || echo 'none'
  exit
fi

quiet=false
intentionSet=false
while [ $# -gt 0 ]; do
  case "$1" in
    '-a')
      echo 'none' >"${tmpDir}/intention"
      exit
    ;;
    '-q')
      quiet=true
    ;;
    '-r')
      echo 'reboot' >"${tmpDir}/intention"
      intentionSet=true
    ;;
    '-R')
      if [ -r "${tmpDir}/intention" ] \
      && grep -qxF 'shutdown' "${tmpDir}/intention" \
      && [ -r "${tmpDir}/pid" ] \
      && [ -d "/proc/$(cat "${tmpDir}/pid")" ]; then
        exit
      fi
      echo 'reboot' >"${tmpDir}/intention"
      intentionSet=true
    ;;
    *)
      >&2 echo 'usage: shutdownasap [-q] [-a|-r|-R]'
      >&2 echo ' -a abort'
      >&2 echo ' -g get intention'
      >&2 echo ' -q quiet'
      >&2 echo ' -r reboot'
      >&2 echo ' -R reboot if not yet shutdown'
      exit 1
    ;;
  esac
  shift
done

if ! ${intentionSet}; then
  echo 'shutdown' >"${tmpDir}/intention"
fi

[ -r "${tmpDir}/pid" ] \
&& [ -d "/proc/$(cat "${tmpDir}/pid")" ] \
&& exit

echo $$ > "${tmpDir}/pid"

capture_output() {
  local exit_code
  local output
  output=$(
    "$@" 2>&1
  ) \
  || exit_code=$?
  if ! ${quiet}; then
    printf '%s\n' "${output}"
  fi
  return ${exit_code}
}

beforeWatchHook

i=1
while [ ${i} -gt 0 ] || ! capture_output additionalWatchHookSlow
do
  if [ ${i} -eq 0 ]
  then
    i=1
  fi
  sleep 1

  nochwarten=false

  if [ -d "${waitForDir}" ] && ls -1A "${waitForDir}" | grep -q "."
  then
    nochwarten=true
    if ! ${quiet}; then
      echo ".warteauf: "
      ls -1A "${waitForDir}"
    fi
  fi

  if users | grep -q "."
  then
    nochwarten=true
    if ! ${quiet}; then
      echo -n "users: "
      users
    fi
  fi

  errors=$(
    [ -d /sys/devices/virtual/block/ ] \
    && find /sys/devices/virtual/block/ \
      -name 'array_state' \
      -exec grep -HvxF "$(printf '%s\n' 'clean' 'active')" {} + \
      , \
      -name 'sync_action' \
      -exec grep -HxF "$(printf '%s\n' 'recover' 'reshape')" {} + \
      , \
      -name 'degraded' \
      -exec grep -HvxF '0' {} +
  ) || true
  if [ -n "${errors}" ]; then
    nochwarten=true
    if ! ${quiet}; then
      printf 'unclean raid array(s):\n%s\n' "${errors}"
    fi
  fi

  for s in "${!shutDownNoGoProcesses[@]}"
  do
    if pgrep -af "(\s|/|^)${shutDownNoGoProcesses[${s}]}(\$|\s)"
    then
      nochwarten=true
      if ! ${quiet}; then
        echo "prozess: ${s}"
      fi
    fi
  done

  for s in "${!shutDownNoGoFiles[@]}"
  do
    if [ -e "${shutDownNoGoFiles[${s}]}" ] && [ -d "/proc/$(cat "${shutDownNoGoFiles[${s}]}")" ]
    then
      nochwarten=true
      if ! ${quiet}; then
        echo "datei: ${s}"
      fi
    fi
  done

  if ! capture_output additionalWatchHookFast
  then
    nochwarten=true
    if ! ${quiet}; then
      echo "additionalWatchHookFast"
    fi
  fi

  if ${nochwarten}
  then
    if ! ${quiet}; then
      echo "warten ..."
    fi
    i=10
    continue
  else
    if ! ${quiet}; then
      echo "noch ${i} Sekunden"
    fi
  fi
  i=$[${i}-1]
done

capture_output beforeShutDownHook

if command -v sudo >/dev/null \
&& [ "$(whoami)" != 'root' ]; then
  pre='sudo'
else
  pre=''
fi

case "$(head -n1 "${tmpDir}/intention")" in
  'reboot')
    ${pre} /sbin/reboot
  ;;
  'shutdown')
    ${pre} /sbin/poweroff
  ;;
  'none')
    echo 'shutdown was aborted'
  ;;
  *)
    printf 'intention "%s" not implemented\n' "$(head -n1 "${tmpDir}/intention")"
    exit 1
  ;;
esac

cd /
rm -rf --one-file-system "${tmpDir}"
