#!/bin/sh
#
# Nagios plugin to monitor the state of drupal sites.
#

################################################################################
#
# V A R I A B L E S
#
################################################################################

# Some creds
INFO_NAME="check_drupal"
INFO_AUTHOR="Patrick Plocke <patrick@plocke.de>"
INFO_GPGKEY="0x28BF179F"
INFO_DATE="2016-06-03"
INFO_LICENSE="MIT"
INFO_VERSION="0.6"

# Get the path
export PATH="$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"

# Nagios error codes
EXIT_OK=0
EXIT_WARN=1
EXIT_ERR=2
EXIT_UNKNOWN=3


# Locale command prefix
if locale -a | grep 'en_US.UTF-8' > /dev/null 2>&1; then
	LOCALE="en_US.UTF-8"
else
	LOCALE="C"
fi

# Might come in handy later
#PHP_OPTS="-d intl.default_locale='en_US'"

# Drush executeable
DRUSH="$(which drush 2>/dev/null)"




################################################################################
#
# F U N C T I O N S
#
################################################################################

############################################################
# Helper
############################################################

# Trim leading and trailing whitespace
# @param  string  The input string
# @output string  The output string
# @return 0
trim() {
	_str="${1}"
	echo "${_str}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
}

# Remove empty lines
# @param  string  The input string
# @output string  The output string
# @return 0
trim_lines() {
	_str="${1}"
	echo "${_str}" | grep -v '^$'
}

#
# Remove annoying BOM
#
remove_bom() {
	_str="${1}"
	echo "${_str}" | sed '1s/^\xEF\xBB\xBF//'
}


# Check for a valid severity and return the
# appropriate nagios exit code
# Allowed values: 'w' or 'e'
# @param  string  The severity.
# @output integer Nagios exit code
# return  integer 0: OK, 1: Wrong
get_severity() {
	_code="${1}"

	if [ "${_code}" = "e" ]; then
		echo "$EXIT_ERR"
		return 0
	elif [ "${_code}" = "w" ]; then
		echo "$EXIT_WARN"
		return 0
	else
		return 1
	fi
}



# Aggregate nagios exit code.
# OK < Warning < Error < Unknown
# @param  integer The current exit code.
# @param  integer The new exit code
# @output integer The combined exit code
# @return integer The combined exit code
merge_exit_codes() {
	_curr_exit="$1"
	_next_exit="$2"

	# OK
	if [ "${_curr_exit}" = "0" ]; then
		_curr_exit="${_next_exit}"
	# Warning
	elif [ "${_curr_exit}" = "1" ]; then
		if [ "${_next_exit}" = "0" ]; then
			_curr_exit="1"
		elif [ "${_next_exit}" = "1" ]; then
			_curr_exit="1"
		elif [ "${_next_exit}" = "2" ]; then
			_curr_exit="2"
		elif [ "${_next_exit}" = "3" ]; then # UNKNOWN -> WARNING
			_curr_exit="1"
		fi
	# Error
	elif [ "${_curr_exit}" = "2" ]; then
		_curr_exit="2"
	# Unknown
	elif [ "${_curr_exit}" = "3" ]; then
		if [ "${_next_exit}" = "0" ]; then
			_curr_exit="3"
		elif [ "${_next_exit}" = "1" ]; then
			_curr_exit="1"
		elif [ "${_next_exit}" = "2" ]; then
			_curr_exit="2"
		elif [ "${_next_exit}" = "3" ]; then # UNKNOWN -> WARNING
			_curr_exit="3"
		fi
	fi
	echo "${_curr_exit}"
	return ${_curr_exit}
}


# Merge two texts with a delimiter
#
# @param  string  The current text
# @param  string  The new text
# @param  string  The separator
# @output stringr The combined text
merge_text() {
	_curr_text="$1"
	_next_text="$2"
	_separator="$3"

	if [ "$_separator" = "" ]; then
		_separator="\n"
	fi

	if [ "$_curr_text" = "" ]; then
		_curr_text="$_next_text"
	else
		_curr_text="${_curr_text}${_separator}${_next_text}"
	fi
	echo "${_curr_text}"
}


# Prepend each line with a prefix
# @param  string  The text (multiline)
# @param  string  The prefix to prepend to each lines
# @outpt  string  The new string
prepend_line() {
	_text="${1}"
	_prefix="${2}"

	echo "${_text}" | awk -v pre="${_prefix}" '{print pre""$0}'
}

############################################################
# Drupal helper
############################################################

# Some hacky way to tell if it is the drupal
# directory root.
# @param  string  Path to Drupal root
# @return integer 0: OK | 1: Not OK
is_drupal_root() {
	# Test if directory exists
	if [ ! -d "${1}" ]; then
		return 1
	fi

	# Test for index.php
	if [ ! -f "${1}/index.php" ]; then
		return 1
	fi

	# Use drush to test root
	if ! drush -r "${1}" status | grep 'Drupal root' 1>/dev/null; then
		return 1
	fi
	return 0
}

# Create randomly named drushrc file
# @output	string	Returns path to file on success
# @return	integer Success
write_drushrc() {
	_ret=0

	# Generate random tmpfile
	if ! command -v mktemp >/dev/null 2>&1; then
		_rand="$(LC_ALL=C tr -dc 'a-z0-9' < /dev/urandom | head -c 32)"
		_file="/tmp/.drushrc.${_rand}"
		touch "${_file}"
		_ret=$?
	else
		_file="$(mktemp)"
		_ret=$?
	fi

	# Quit on error immediately
	if [ ${_ret} -ne 0 ]; then
		return ${_ret}
	fi

	# Write file
	{
		echo "<?php"
		echo "// Drush commands should always be run in en."
		echo "\$options['variables']['language_default'] = (object) array("
		echo "  'language' => 'en',"
		echo "  'name' => 'English',"
		echo "  'native' => 'English',"
		echo "  'direction' => '0',"
		echo "  'enabled' => 1,"
		echo "  'plurals' => '0',"
		echo "  'formula' => '',"
		echo "  'domain' => '',"
		echo "  'prefix' => 'en',"
		echo "  'weight' => '0',"
		echo "  'javascript' => '',"
		echo ");"
	} > "${_file}"

	# Return filename
	echo "${_file}"
	return 0
}


# Removes the drushrc.php file from /tmp if it exists
# @param	string	Path to drush file
remove_drushrc() {
	_file="${1}"
	if [ -f "${_file}" ]; then
		rm -f "${_file}"
	fi
}


############################################################
# Drush check functions
############################################################

# Check if security updates are required.
#
# @param  string  Path to Drupal root.
# @param  string  Drupal multisite URI
# @output string  Drupal Security Updates.
# @return integer Nagios exit code.
check_security_updates() {

	_drupal_root="${1}"
	_multisite_uri="${2}"

	# No URI specified (single site)
	if [ -z "${_multisite_uri}" ]; then
		_updates="$(LC_MESSAGES=${LOCALE} ${DRUSH} --root="${_drupal_root}" pm-updatestatus --nocolor --security-only --format=csv --fields='name,installed version,proposed version,message' 2> /dev/null)"
	else
		_updates="$(LC_MESSAGES=${LOCALE} ${DRUSH} --root="${_drupal_root}" --uri="${_multisite_uri}" pm-updatestatus --nocolor --security-only --format=csv --fields='name,installed version,proposed version,message' 2> /dev/null)"
	fi

	# Error might have multiple causes...
	# Drupal database not connected?
	# Drupal root wrong?
	if [ $? -ne 0 ]; then
		return $EXIT_UNKNOWN
	fi

	if [ "${_updates}" != "" ]; then
		# Format security updates
		# "<name> <ver> -> <ver>"
		_updates="$(echo "${_updates}" | awk 'BEGIN {FS=","} ; { print $1" "$2" -> "$3 }')"

		# tango out
		echo "${_updates}"
		return $EXIT_ERR
	fi
	return $EXIT_OK
}

# Check if normal system updates are required.
#
# @param  string  Path to Drupal root.
# @param  string  Drupal multisite URI
# @output string  Drupal System Updates.
# @return integer Nagios exit code.
check_system_updates() {

	_drupal_root="${1}"
	_multisite_uri="${2}"

	# read comma separated security updates
	# No URI specified (single site)
	if [ -z "${_multisite_uri}" ]; then
		_updates="$(LC_MESSAGES=${LOCALE} ${DRUSH} --root="${_drupal_root}" pm-updatestatus --nocolor --format=csv --fields='name,installed version,proposed version,message' 2> /dev/null)"
	else
		_updates="$(LC_MESSAGES=${LOCALE} ${DRUSH} --root="${_drupal_root}" --uri="${_multisite_uri}" pm-updatestatus --nocolor --format=csv --fields='name,installed version,proposed version,message' 2> /dev/null)"
	fi

	# Error might have multiple causes...
	# Drupal database not connected?
	# Drupal root wrong?
	if [ $? -ne 0 ]; then
		return $EXIT_UNKNOWN
	fi

	# Remove normal updates and only keep security updates
	_updates="$(echo "${_updates}" | grep -v 'SECURITY UPDATE')"


	if [ "${_updates}" != "" ]; then
		# Format security updates
		# "<name> <ver> -> <ver>"
		_updates="$(echo "${_updates}" | awk 'BEGIN {FS=","} ; { print $1" "$2" -> "$3 }')"

		# tango out
		echo "${_updates}"
		return $EXIT_ERR
	fi
	return $EXIT_OK
}

# Check if core errors are present.
#
# @param  string  Path to Drupal root.
# @param  string  Drupal multisite URI
# @output string  Drupal Core errors.
# @return integer Nagios exit code.
check_core_errors() {

	_drupal_root="${1}"
	_multisite_uri="${2}"

	# read comma separated core errors
	# No URI specified (single site)
	if [ -z "${_multisite_uri}" ]; then
		_core_errors="$(LC_MESSAGES=${LOCALE} ${DRUSH} --root="${_drupal_root}" core-requirements --severity=2 --field-labels=0 --format=table --fields='severity,title' 2>/dev/null)"
	else
		_core_errors="$(LC_MESSAGES=${LOCALE} ${DRUSH} --root="${_drupal_root}" --uri="${_multisite_uri}" core-requirements --severity=2 --field-labels=0 --format=table --fields='severity,title' 2>/dev/null)"
	fi

	# Error might have multiple causes...
	# Drupal database not connected?
	# Drupal root wrong?
	if [ $? -ne 0 ]; then
		return $EXIT_UNKNOWN
	fi

	# Trim the string
	_core_errors="$(remove_bom "${_core_errors}")"
	_core_errors="$(trim_lines "${_core_errors}")"
	_core_errors="$(trim "${_core_errors}")"

	# Format output
	# "ERROR    <short desc>"
	if [ "${_core_errors}" != "" ]; then

		# Remove leading 'error'
		_core_errors="$(echo "${_core_errors}" | awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}')"

		# Tango out
		echo "${_core_errors}"
		return $EXIT_ERR
	fi

	return $EXIT_OK
}

# Check if core warnings are present.
#
# @param  string  Path to Drupal root.
# @param  string  Drupal multisite URI
# @output string  Drupal Core errors.
# @return integer Nagios exit code.
check_core_warnings() {

	_drupal_root="${1}"
	_multisite_uri="${2}"

	# read comma separated core warnings
	# No URI specified (single site)
	if [ -z "${_multisite_uri}" ]; then
		_core_warnings="$(LC_MESSAGES=${LOCALE} ${DRUSH} --root="${_drupal_root}" core-requirements --severity=1 --no-field-labels --format=table --fields='severity,title' 2>/dev/null)"
	else
		_core_warnings="$(LC_MESSAGES=${LOCALE} ${DRUSH} --root="${_drupal_root}" --uri="${_multisite_uri}" core-requirements --severity=1 --no-field-labels --format=table --fields='severity,title' 2>/dev/null)"
	fi

	# Error might have multiple causes...
	# Drupal database not connected?
	# Drupal root wrong?
	if [ $? -ne 0 ]; then
		return $EXIT_UNKNOWN
	fi

	# Only keep "Warning"
	_core_warnings="$(echo "${_core_warnings}" | grep -E 'Warning')"

	# Trim the string
	_core_warnings="$(trim_lines "${_core_warnings}")"
	_core_warnings="$(trim "${_core_warnings}")"

	# Format output
	# "ERROR    <short desc>"
	if [ "${_core_warnings}" != "" ]; then

		# Remove leading 'error'
		_core_warnings="$(echo "${_core_warnings}" | awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}')"

		# Tango out
		echo "${_core_warnings}"
		return $EXIT_ERR
	fi

	return $EXIT_OK
}

# Check if the database requires updates.
#
# @param  string  Path to Drupal root.
# @param  string  Drupal multisite URI
# @output string  Required db updates.
# @return integer Nagios exit code.
check_db_updates() {

	_drupal_root="${1}"
	_multisite_uri="${2}"

	# read comma separated db migrations
	# No URI specified (single site)
	if [ -z "${_multisite_uri}" ]; then
		_updates="$(LC_MESSAGES=${LOCALE} ${DRUSH} --root="${_drupal_root}" pm-updatestatus --nocolor --no-field-labels --format=csv --fields='module,update_id' 2> /dev/null)"
	else
		_updates="$(LC_MESSAGES=${LOCALE} ${DRUSH} --root="${_drupal_root}" --uri="${_multisite_uri}" pm-updatestatus --nocolor --no-field-labels --format=csv --fields='module,update_id' 2> /dev/null)"
	fi

	# Error might have multiple causes...
	# Drupal database not connected?
	# Drupal root wrong?
	if [ $? -ne 0 ]; then
		return $EXIT_UNKNOWN
	fi

	# Remove normal updates and only keep security updates
	_updates="$(echo "${_updates}" | grep -v 'SECURITY UPDATE')"


	if [ "${_updates}" != "" ]; then
		# Format security updates
		# "<name> <ver> -> <ver>"
		_updates="$(echo "${_updates}" | awk 'BEGIN {FS=","} ; { print $1" "$2" -> "$3 }')"

		# tango out
		echo "${_updates}"
		return $EXIT_ERR
	fi
	return $EXIT_OK
}


############################################################
# Program Functions
############################################################

# Give some creds
# @output string  The creds.
# @return integer 0
print_version() {
	printf "Name:    %s\n" "${INFO_NAME}"
	printf "Version: %s (%s)\n" "${INFO_VERSION}" "${INFO_DATE}"
	printf "Author:  %s (%s)\n" "${INFO_AUTHOR}" "${INFO_GPGKEY}"
	printf "License: %s\n" "${INFO_LICENSE}"
	return 0
}

# Check requirements.
# @output string  The requirements.
# @return integer 0 on success, 2 on fail
check() {
	if command -v drush > /dev/null 2>&1; then
		echo "[OK] drush found"
		return "$EXIT_ERR"
	else
		echo "[ERR] drush not found"
		return "$EXIT_OK"
	fi
}

# Usage
# @output string  The usage screen.
# @return integer 0
print_usage() {
	printf "Usage: %s -d <drupal root> [-n <name>] [-s <w|e>] [-u <w|e>] [-e <w|e>] [-w <w|e>] [-m <w|e>] [-i <uri>] [-l <log file>]\n" "${INFO_NAME}"
	printf "OR     %s --check\n" "${INFO_NAME}"
	printf "OR     %s --help\n" "${INFO_NAME}"
	printf "OR     %s --version\n\n" "${INFO_NAME}"
	return 0
}

# Help
# @output string  The help screen.
# @return integer 0
print_help() {

	# Show usage first
	print_usage

	# Show help and details
	printf "Nagios plugin that will check drupal sites for errors.\n"
	printf "Errors include the following: available security updates,\n"
	printf "missed database migrations and drupal status errors.\n"
	printf "For each check you can specify the nagios severity (error or warning).\n\n"

	printf "  -d <drupal root>       The full path to the drupal document root (usually\n"
	printf "                         the 'drupal' folder. This parameter is required.\n\n"

	printf "  -n <name>              [optional] Specify a name for the drupal instance to\n"
	printf "                         appear on the nagios output. The default is 'Drupal'\n\n"

	printf "                         the 'drupal' folder. This parameter is required.\n\n"

	printf "  -s <w|e>               [optional] Check for drupal core and module security\n"
	printf "                         updates and return nagios error or warning.\n"
	printf "                         Warning:  -s w\n"
	printf "                         Error:    -s e\n\n"

	printf "  -u <w|e>               [optional] Check for drupal core and module updates\n"
	printf "                         in general and return nagios error or warning.\n"
	printf "                         Warning:  -u w\n"
	printf "                         Error:    -u e\n\n"

	printf "  -e <w|e>               [optional] Check for drupal status errors and return\n"
	printf "                         nagios error or warning.\n"
	printf "                         Warning:  -e w\n"
	printf "                         Error:    -e e\n\n"

	printf "  -w <w|e>               [optional] Check for drupal status warnings and return\n"
	printf "                         nagios error or warning.\n"
	printf "                         Warning:  -w w\n"
	printf "                         Error:    -w e\n\n"

	printf "  -m <w|e>               [optional] Check for drupal missed database migrations\n"
	printf "                         and return nagios error or warning. (They can occur\n"
	printf "                         when you update core or modules and forget the db).\n"
	printf "                         Warning:  -m w\n"
	printf "                         Error:    -m e\n\n"

	printf "  -i <uri>               [optional] Parse in an url for a drupal multisite instance.\n"
	printf "                         'drush --uri':\n"
	printf "                         In Drupal 7, the value of --uri should always be\n"
	printf "                         the same as when the site is being accessed from a web browser\n"
	printf "                         (e.g. http://mysite.org, although the http:// is optional).\n"
	printf "                         In Drupal 6, the value of --uri should always be the same as the\n"
	printf "                         site's folder name in the 'sites' folder (e.g. default); it is best\n"
	printf "                         if the site folder name matches the URI from the browser, and is consistent\n"
	printf "                         on every instance of the same site\n"
	printf "                         (e.g. also use sites/mysite.org for http://dev.mysite.org).\n\n"

	printf "  -l <log file>          [optional] Instead of checking all of the above via nagios\n"
	printf "                         every five minutes or so, run this script via cron once a day\n"
	printf "                         (or twice) and write the output into a logfile. This logfile can\n"
	printf "                         then be checked by the nagios plugin 'check_drupal_log' which is\n"
	printf "                         less costy in terms of load/cpu.\n"
	printf "                         See 'check_drupal_log --help' for more info.\n"
	printf "                         Example:\n"
	printf "                         check_drupal -d /var/www -s e -e e -w w -l /var/log/drupal.log\n"
	printf "                         check_drupal_log -l /var/log/drupal.log\n\n"

	printf "  --check                Check for program requirements.\n"
	printf "  --help                 Show this help\n"
	printf "  --version              Show version information.\n"
	return 0
}



################################################################################
#
# E N T R Y   P O I N T
#
################################################################################

############################################################
# Check for --check, --help or --version arguments
############################################################
if [ "${1}" = "--check" ]; then
	check
	exit $EXIT_OK
fi
if [ "${1}" = "--help" ]; then
	print_help
	exit $EXIT_OK
fi
if [ "${1}" = "--version" ]; then
	print_version
	exit $EXIT_OK
fi


############################################################
# Check requirements
############################################################

# Do we have 'drush'?
if ! command -v drush > /dev/null 2>&1 ; then
	printf "[UNKNOWN] 'drush' not found.\n"
	exit $EXIT_UNKNOWN
fi


############################################################
# Internal Variables
############################################################

# This will be filled in the the specified arguments.
DRUPAL_NAME="Drupal"

# Url for drupal multisite
MULTISITE_URI=""

# Extended Status Message
MSG_SECURITY_UPDATE=""
MSG_SYSTEM_UPDATE=""
MSG_CORE_ERROR=""
MSG_CORE_WARNING=""
MSG_DB_UPDATE=""

# Info for normal Status message if there is an error/warning
CNT_SECURITY_UPDATE_ERROR="0"
CNT_SYSTEM_UPDATE_ERROR="0"
CNT_CORE_ERR_ERROR="0"
CNT_CORE_WARN_ERROR="0"
CNT_DB_UPDATE_ERROR="0"

# Count warnings and errors for performance data
CNT_ALL=0
CNT_OK=0
CNT_ERROR=0
CNT_WARNING=0

# Final exit code
NAGIOS_EXIT="${EXIT_OK}"


############################################################
# Retrieve arguments
############################################################
while test -n "$1"; do
	case "$1" in
		# ---- 1. Drupal root
		-d)
			# Get next arg in list (Path)
			shift
			DRUPAL_ROOT="$1"
			;;
		# ---- 1. Drupal name
		-n)
			# Get next arg in list (Name)
			shift
			DRUPAL_NAME="$1"
			;;
		# ---- 2. Security Updates
		-s)
			# Get next arg in list (Severity <w|e>)
			shift
			if ! CHECK_S="$(get_severity "$1")" > /dev/null 2>&1; then
				echo "Invalid value \"$1\" for option \"-s\"."
				exit $EXIT_UNKNOWN
			fi
			;;
		# ---- 3. System Updates
		-u)
			# Get next arg in list (Severity <w|e>)
			shift
			if ! CHECK_U="$(get_severity "$1")" > /dev/null 2>&1; then
				echo "Invalid value \"$1\" for option \"-u\"."
				exit $EXIT_UNKNOWN
			fi
			;;
		# ---- 5. Core errors
		-e)
			# Get next arg in list (Severity <w|e>)
			shift
			if ! CHECK_E="$(get_severity "$1")" > /dev/null 2>&1; then
				echo "Invalid value \"$1\" for option \"-e\"."
				exit $EXIT_UNKNOWN
			fi
			;;
		# ---- 6. Core warnings
		-w)
			# Get next arg in list (Severity <w|e>)
			shift
			if ! CHECK_W="$(get_severity "$1")" > /dev/null 2>&1; then
				echo "Invalid value \"$1\" for option \"-w\"."
				exit $EXIT_UNKNOWN
			fi
			;;
		# ---- 7. Missing DB updates
		-m)
			# Get next arg in list (Severity <w|e>)
			shift
			if ! CHECK_M="$(get_severity "$1")" > /dev/null 2>&1; then
				echo "Invalid value \"$1\" for option \"-m\"."
				exit $EXIT_UNKNOWN
			fi
			;;
		# ---- 8. Do we have an URI for a multisite?
		-i)
			# Get next arg in list (URL)
			shift
			MULTISITE_URI="$1"
			;;
			# ---- 9. Do we log to file?
		-l)
			# Get next arg in list (log file)
			shift
			LOGGING="$1"
			;;
		*)
			printf "Unknown argument: %s\n" "$1"
			print_usage
			exit $EXIT_UNKNOWN
			;;
	esac
	shift
done

# Use a drushrc.php file to set the language to english
DRUSHRC="$(write_drushrc)"
if [ $? -ne 0 ]; then
	printf "[UNKNOWN] Unable to create tmpfile\n"
	exit $EXIT_UNKNOWN
fi

DRUSH="${DRUSH} --config=${DRUSHRC}"


############################################################
# Validate arguments
############################################################

# -d is mandatory!!!
if [ -z "$DRUPAL_ROOT" ]; then
	printf "[UNKNOWN] Drupal root parameter '-d' not specified.\n"
	print_usage
	exit $EXIT_UNKNOWN
fi

# Check if it is a valid drupal doc root
if ! is_drupal_root "${DRUPAL_ROOT}" > /dev/null 2>&1; then
	echo "[UNKNOWN] '${DRUPAL_ROOT}' is not a valid drupal root directory."
	exit $EXIT_UNKNOWN
fi

# Are we logging?
if [ -n "$LOGGING" ]; then

	# Does the log file exist?
	if [ -f "$LOGGING" ]; then
		# Is it writeable?
		if [ ! -w "$LOGGING" ]; then
			printf "[UNKNOWN] Logfile not writeable: %s\n" "${LOGGING}"
			exit $EXIT_UNKNOWN
		fi
	else
		# Create the file
		if ! touch "${LOGGING}" > /dev/null 2>&1; then
			printf "[UNKNOWN] Unable to create logfile in %s\n" "${LOGGING}"
			exit $EXIT_UNKNOWN
		fi
	fi
fi


############################################################
# Go Go Go!!!!
############################################################


#### 1. Check for Drupal Security Updates
if [ -n "$CHECK_S" ]; then

	SEVERITY="$CHECK_S"

	# Execute Command
	MSG_SECURITY_UPDATE="$(check_security_updates "${DRUPAL_ROOT}" "${MULTISITE_URI}")"
	TMP_EXIT="$?"

	# Merge exit codes
	if [ "$TMP_EXIT" != "0" ]; then
		# Count lines as number of issues
		CNT_SECURITY_UPDATE_ERROR="$(echo "${MSG_SECURITY_UPDATE}" | wc -l | xargs)"

		if [ "$SEVERITY" = "$EXIT_ERR" ]; then
			CNT_ERROR=$((CNT_ERROR+1))
			MSG_SECURITY_UPDATE="$(prepend_line "${MSG_SECURITY_UPDATE}" "[CRITICAL] ")"
			MSG_SECURITY_UPDATE="==== SECURITY UPDATES ====\n${MSG_SECURITY_UPDATE}"
			NAGIOS_EXIT="$(merge_exit_codes "$NAGIOS_EXIT" "2")"
		else
			CNT_WARNING=$((CNT_WARNING+1))
			MSG_SECURITY_UPDATE="$(prepend_line "${MSG_SECURITY_UPDATE}" "[WARNING] ")"
			MSG_SECURITY_UPDATE="==== SECURITY UPDATES ====\n${MSG_SECURITY_UPDATE}"
			NAGIOS_EXIT="$(merge_exit_codes "$NAGIOS_EXIT" "1")"
		fi
	else
		CNT_OK=$((CNT_OK+1))
		MSG_SECURITY_UPDATE="==== SECURITY UPDATES ====\n[OK] No Security updates required"
		NAGIOS_EXIT="$(merge_exit_codes "$NAGIOS_EXIT" "0")"
	fi
	CNT_ALL=$((CNT_ALL+1))

fi


#### 2. Check for Drupal normal Updates
if [ -n "$CHECK_U" ]; then

	SEVERITY="$CHECK_U"

	# Execute Command
	MSG_SYSTEM_UPDATE="$(check_system_updates "${DRUPAL_ROOT}" "${MULTISITE_URI}")"
	TMP_EXIT="$?"

	# Merge exit codes
	if [ "$TMP_EXIT" != "0" ]; then
		# Count lines as number of issues
		CNT_SYSTEM_UPDATE_ERROR="$(echo "${MSG_SYSTEM_UPDATE}" | wc -l | xargs)"

		if [ "$SEVERITY" = "$EXIT_ERR" ]; then
			CNT_ERROR=$((CNT_ERROR+1))
			MSG_SYSTEM_UPDATE="$(prepend_line "${MSG_SYSTEM_UPDATE}" "[CRITICAL] ")"
			MSG_SYSTEM_UPDATE="==== SYSTEM UPDATES ====\n${MSG_SYSTEM_UPDATE}"
			NAGIOS_EXIT="$(merge_exit_codes "$NAGIOS_EXIT" "2")"
		else
			CNT_WARNING=$((CNT_WARNING+1))
			MSG_SYSTEM_UPDATE="$(prepend_line "${MSG_SYSTEM_UPDATE}" "[WARNING] ")"
			MSG_SYSTEM_UPDATE="==== SYSTEM UPDATES ====\n${MSG_SYSTEM_UPDATE}"
			NAGIOS_EXIT="$(merge_exit_codes "$NAGIOS_EXIT" "1")"
		fi
	else
		CNT_OK=$((CNT_OK+1))
		MSG_SYSTEM_UPDATE="==== SYSTEM UPDATES ====\n[OK]\nNo Updates required"
		NAGIOS_EXIT="$(merge_exit_codes "$NAGIOS_EXIT" "0")"
	fi
	CNT_ALL=$((CNT_ALL+1))

fi


#### 3. Check for Drupal core errors
if [ -n "$CHECK_E" ]; then

	SEVERITY="$CHECK_E"

	# Execute Command
	MSG_CORE_ERROR="$(check_core_errors "${DRUPAL_ROOT}" "${MULTISITE_URI}")"
	TMP_EXIT="$?"

	# Merge exit codes
	if [ "$TMP_EXIT" != "0" ]; then
		# Count lines as number of issues
		CNT_CORE_ERR_ERROR="$(echo "${MSG_CORE_ERROR}" | wc -l | xargs)"

		if [ "$SEVERITY" = "$EXIT_ERR" ]; then
			CNT_ERROR=$((CNT_ERROR+1))
			MSG_CORE_ERROR="$(prepend_line "${MSG_CORE_ERROR}" "[CRITICAL] ")"
			MSG_CORE_ERROR="==== CORE ERRORS ====\n${MSG_CORE_ERROR}"
			NAGIOS_EXIT="$(merge_exit_codes "$NAGIOS_EXIT" "2")"
		else
			CNT_WARNING=$((CNT_WARNING+1))
			MSG_CORE_ERROR="$(prepend_line "${MSG_CORE_ERROR}" "[WARNING] ")"
			MSG_CORE_ERROR="==== CORE ERRORS ====\n${MSG_CORE_ERROR}"
			NAGIOS_EXIT="$(merge_exit_codes "$NAGIOS_EXIT" "1")"
		fi
	else
		CNT_OK=$((CNT_OK+1))
		MSG_CORE_ERROR="==== CORE ERRORS ====\n[OK] No core errors"
		NAGIOS_EXIT="$(merge_exit_codes "$NAGIOS_EXIT" "0")"
	fi
	CNT_ALL=$((CNT_ALL+1))

fi


#### 4. Check for Drupal core warnings
if [ -n "$CHECK_W" ]; then

	SEVERITY="$CHECK_W"

	# Execute Command
	MSG_CORE_WARNING="$(check_core_warnings "${DRUPAL_ROOT}" "${MULTISITE_URI}")"
	TMP_EXIT="$?"

	# Merge exit codes
	if [ "$TMP_EXIT" != "0" ]; then
		# Count lines as number of issues
		CNT_CORE_WARN_ERROR="$(echo "${MSG_CORE_WARNING}" | wc -l | xargs)"

		if [ "$SEVERITY" = "$EXIT_ERR" ]; then
			CNT_ERROR=$((CNT_ERROR+1))
			MSG_CORE_WARNING="$(prepend_line "${MSG_CORE_WARNING}" "[CRITICAL] ")"
			MSG_CORE_WARNING="==== CORE WARNINGS ====\n${MSG_CORE_WARNING}"
			NAGIOS_EXIT="$(merge_exit_codes "$NAGIOS_EXIT" "2")"
		else
			CNT_WARNING=$((CNT_WARNING+1))
			MSG_CORE_WARNING="$(prepend_line "${MSG_CORE_WARNING}" "[WARNING] ")"
			MSG_CORE_WARNING="==== CORE WARNINGS ====\n${MSG_CORE_WARNING}"
			NAGIOS_EXIT="$(merge_exit_codes "$NAGIOS_EXIT" "1")"
		fi
	else
		CNT_OK=$((CNT_OK+1))
		MSG_CORE_WARNING="==== CORE WARNINGS ====\n[OK] No core warnings"
		NAGIOS_EXIT="$(merge_exit_codes "$NAGIOS_EXIT" "0")"
	fi
	CNT_ALL=$((CNT_ALL+1))

fi


#### 5. Check for Drupal missing db updates
if [ -n "$CHECK_M" ]; then

	SEVERITY="$CHECK_M"

	# Execute Command
	MSG_DB_UPDATE="$(check_db_updates "${DRUPAL_ROOT}" "${MULTISITE_URI}")"
	TMP_EXIT="$?"

	# Merge exit codes
	if [ "$TMP_EXIT" != "0" ]; then
		# Count lines as number of issues
		CNT_DB_UPDATE_ERROR="$(echo "${MSG_DB_UPDATE}" | wc -l | xargs)"

		if [ "$SEVERITY" = "$EXIT_ERR" ]; then
			CNT_ERROR=$((CNT_ERROR+1))
			MSG_DB_UPDATE="$(prepend_line "${MSG_DB_UPDATE}" "[CRITICAL] ")"
			MSG_DB_UPDATE="==== DB UPDATES ====\n${MSG_DB_UPDATE}"
			NAGIOS_EXIT="$(merge_exit_codes "$NAGIOS_EXIT" "2")"
		else
			CNT_WARNING=$((CNT_WARNING+1))
			MSG_DB_UPDATE="$(prepend_line "${MSG_DB_UPDATE}" "[WARNING] ")"
			MSG_DB_UPDATE="==== DB UPDATES ====\n${MSG_DB_UPDATE}"
			NAGIOS_EXIT="$(merge_exit_codes "$NAGIOS_EXIT" "1")"
		fi
	else
		CNT_OK=$((CNT_OK+1))
		MSG_DB_UPDATE="==== DB UPDATES ====\n[OK] No database migrations required"
		NAGIOS_EXIT="$(merge_exit_codes "$NAGIOS_EXIT" "0")"
	fi
	CNT_ALL=$((CNT_ALL+1))

fi



############################################################
# Cleanup
############################################################

# Remove temporary file
remove_drushrc "${DRUSHRC}"



############################################################
# Eval results
############################################################

#### Build status text
INFO=""
if [ "$CNT_SECURITY_UPDATE_ERROR" != "0" ]; then
	if [ "$CNT_SECURITY_UPDATE_ERROR" = "1" ]; then
		INFO="$(merge_text "${INFO}" "1 Security update" ", ")"
	else
		INFO="$(merge_text "${INFO}" "${CNT_SECURITY_UPDATE_ERROR} Security updates" ", ")"
	fi
fi
if [ "$CNT_SYSTEM_UPDATE_ERROR" != "0" ]; then
	if [ "$CNT_SYSTEM_UPDATE_ERROR" = "1" ]; then
		INFO="$(merge_text "${INFO}" "1 Update" ", ")"
	else
		INFO="$(merge_text "${INFO}" "${CNT_SYSTEM_UPDATE_ERROR} Updates" ", ")"
	fi
fi
if [ "$CNT_CORE_ERR_ERROR" != "0" ]; then
	if [ "$CNT_CORE_ERR_ERROR" = "1" ]; then
		INFO="$(merge_text "${INFO}" "1 Core error" ", ")"
	else
		INFO="$(merge_text "${INFO}" "${CNT_CORE_ERR_ERROR} Core errors" ", ")"
	fi
fi
if [ "$CNT_CORE_WARN_ERROR" != "0" ]; then
	if [ "$CNT_CORE_WARN_ERROR" = "1" ]; then
		INFO="$(merge_text "${INFO}" "1 Core warning" ", ")"
	else
		INFO="$(merge_text "${INFO}" "${CNT_CORE_WARN_ERROR} Core warnings" ", ")"
	fi
fi
if [ "$CNT_DB_UPDATE_ERROR" != "0" ]; then
	if [ "$CNT_DB_UPDATE_ERROR" = "1" ]; then
		INFO="$(merge_text "${INFO}" "1 DB migration" ", ")"
	else
		INFO="$(merge_text "${INFO}" "${CNT_DB_UPDATE_ERROR} DB migrations" ", ")"
	fi
fi

#### Short output (std status)
OUTPUT=""
if [ "$NAGIOS_EXIT" = "$EXIT_OK" ]; then
	OUTPUT="$(printf "[OK] %s is healthy" "${DRUPAL_NAME}")"
elif [ "$NAGIOS_EXIT" = "$EXIT_WARN" ]; then
	OUTPUT="$(printf "[WARNING] %s has warnings: %s" "${DRUPAL_NAME}" "${INFO}")"
elif [ "$NAGIOS_EXIT" = "$EXIT_ERR" ]; then
	OUTPUT="$(printf "[CRITICAL] %s has errors: %s" "${DRUPAL_NAME}" "${INFO}")"
else
	OUTPUT="$(printf "[UNKNOWN] %s is at unknown state - check extended info" "${DRUPAL_NAME}")"
fi


#### Performance Data
# @see http://docs.icinga.org/latest/en/perfdata.html
# 'label'=value[UOM];[warn];[crit];[min];[max]
PERF=""
PERF="$(printf "%s'Security Updates'=%d;;;; "    "${PERF}" "${CNT_SECURITY_UPDATE_ERROR}")"
PERF="$(printf "%s'Updates'=%d;;;; "             "${PERF}" "${CNT_SYSTEM_UPDATE_ERROR}")"
PERF="$(printf "%s'Core Errors'=%d;;;; "         "${PERF}" "${CNT_CORE_ERR_ERROR}")"
PERF="$(printf "%s'Core Warnings'=%d;;;; "       "${PERF}" "${CNT_CORE_WARN_ERROR}")"
PERF="$(printf "%s'Database Migrations'=%d;;;; " "${PERF}" "${CNT_DB_UPDATE_ERROR}")"

PERF="$(printf "%s'OK'=%d;;;0;%d "        "${PERF}" "${CNT_OK}"      "${CNT_ALL}")"
PERF="$(printf "%s'Errors'=%d;1;1;0;%d "  "${PERF}" "${CNT_ERROR}"   "${CNT_ALL}")"
PERF="$(printf "%s'Warnings'=%d;1;;0;%d " "${PERF}" "${CNT_WARNING}" "${CNT_ALL}")"
PERF="$(printf "%s'Unknown'=0;;;0;%d "    "${PERF}" "${CNT_ALL}")"


#### Extended status data
if [ "$MSG_SECURITY_UPDATE" != "" ]; then E_OUTPUT="$(merge_text "${E_OUTPUT}" "${MSG_SECURITY_UPDATE}" "\n")"; fi
if [ "$MSG_SYSTEM_UPDATE"   != "" ]; then E_OUTPUT="$(merge_text "${E_OUTPUT}" "${MSG_SYSTEM_UPDATE}" "\n")";   fi
if [ "$MSG_CORE_ERROR"      != "" ]; then E_OUTPUT="$(merge_text "${E_OUTPUT}" "${MSG_CORE_ERROR}" "\n")";      fi
if [ "$MSG_CORE_WARNING"    != "" ]; then E_OUTPUT="$(merge_text "${E_OUTPUT}" "${MSG_CORE_WARNING}" "\n")";    fi
if [ "$MSG_DB_UPDATE"       != "" ]; then E_OUTPUT="$(merge_text "${E_OUTPUT}" "${MSG_DB_UPDATE}" "\n")";       fi


#### Log to file?
if [ -n "$LOGGING" ]; then
	echo "${OUTPUT} | ${PERF}"	 > "$LOGGING"
	echo "${E_OUTPUT}"			>> "$LOGGING"
	echo "${NAGIOS_EXIT}"		>> "$LOGGING"
	exit 0
else
	echo "${OUTPUT} | ${PERF}"
	echo "${E_OUTPUT}"
	exit "$NAGIOS_EXIT"
fi


# " vim: set ts=4:

