#!/bin/bash

if [ -f /etc/default/haproxy ]; then
	. /etc/default/haproxy
fi

if [ -f /etc/sysconfig/haproxy ]; then
	. /etc/sysconfig/haproxy
fi

RETVAL=1
USER=${HAPROXY_USER:-root}
BIN_FILE=${HAPROXY_BIN:-/usr/sbin/haproxy}
PID_FILE=${HAPROXY_PID:-/var/run/haproxy/kazoo-haproxy.pid}
CFG_FILE=${HAPROXY_CONFIG:-/etc/kazoo/haproxy/haproxy.cfg}
SOCKET=${HAPROXY_SOCKET:-/var/run/haproxy/haproxy.sock}
export HOME=${HAPROXY_HOME:-/var/lib/haproxy}

check_socket() {
    if [ -S "$SOCKET" ]; then
        return
    fi
    SOCKET=/tmp/haproxy.sock
}

# e.g. echo 'show stat' | send_socket $SOCKET
send_socket() {
    local socket="$1"
    socat stdio unix-connect:${socket}
}

show_stat() {
    local socket="$1"
    echo 'show stat' | send_socket ${socket}
}

prepare() {
	mkdir -p /var/log/haproxy
	chown -R ${USER} /var/log/haproxy
	mkdir -p /var/run/haproxy
	chown -R ${USER} /var/run/haproxy
	if [ -e ${PID_FILE} ]; then
		rm -rf ${PID_FILE}
	fi
        RETVAL=$?
}

start() {
	cd ${HOME}

	check_config
	if [ ${RETVAL} -ne 0 ]; then
		return
	fi

	if show_stat $SOCKET > /dev/null 2>&1; then
		echo "HAProxy is already running!"
		return
	fi

	set -- ${BIN_FILE} -f ${CFG_FILE} -p ${PID_FILE} ${OPTIONS} "$@"
	if [ "$(whoami)" = "${USER}" ]; then
		exec "$@"
	else
		runuser -s /bin/bash ${USER} -c "$*"
	fi
	RETVAL=$?

	if [ ${RETVAL} -ne 0 ]; then
		echo "Failed to start HAProxy!"
		RETVAL=1
	fi
}

stop() {
	[[ -f "${PID_FILE}" ]] && kill $(cat ${PID_FILE})
	RETVAL=$?
}

restart() {
	check_config
	if [ ${RETVAL} -ne 0 ]; then
		return
	fi

	stop
	start
}

status() {
	local STATS="pxname svname qcur qmax scur smax slim stot bin bout dreq dresp ereq econ eresp wretr wredis status weight act bck chkfail chdown lastchg downtime qlimit pid iid sid throttle lbtot tracked type rate rate_lim rate_max check_status check_code check_duration hrsp_1xx hrsp_2xx hrsp_3xx hrsp_4xx hrsp_5xx hrsp_other hanafail req_rate req_rate_max req_tot cli_abrt srv_abrt"
	local TABLE_HEADER="Host|25 Backend|15 Status Active Rate 1xx 2xx 3xx 4xx 5xx Ping"
	local TABLE_VARS="svname|25 pxname|15 status scur req_rate hrsp_1xx hrsp_2xx hrsp_3xx hrsp_4xx hrsp_5xx check_duration"
	if ! show_stat $SOCKET > /dev/null 2>&1; then
		echo "Unable to connect to HAProxy, ensure it is running!"
		return
	fi
	echo -n "|"
	for HEADER in $TABLE_HEADER; do
		if [[ "${HEADER}" =~ "|"  ]]; then
			NAME="${HEADER%%|*}"
			SIZE=${HEADER#*|}
		else
			NAME="${HEADER%%|*}"
			SIZE=6
		fi
		printf "%-${SIZE}s |" $NAME
	done
	echo
	show_stat $SOCKET \
	  | while IFS=',' read ${STATS}; do
		if [ -z "$svname" ]; then
			continue
		fi
		if [ "$svname" = 'svname' ]; then
			continue
		fi
		if [ "$svname" = 'BACKEND' ]; then
			continue
		fi
		if [ "$svname" = 'FRONTEND' ]; then
			continue
		fi
		echo -n "|"
		for VAR in $TABLE_VARS; do
			if [[ "${VAR}" =~ "|"  ]]; then
				NAME="${VAR%%|*}"
				SIZE=${VAR#*|}
			else
				NAME="${VAR%%|*}"
				SIZE=6
			fi
			eval VALUE=\$$NAME
			if [ "${VAR}" = 'check_duration' ]; then
				VALUE="${VALUE}ms"
			fi
			printf "%-${SIZE}s |" ${VALUE:-0}
		done
		echo
	done
	RETVAL=0
}

reload() {
	check_config
	if [ ${RETVAL} -ne 0 ]; then
		return
	fi

	${BIN_FILE} -f ${CFG_FILE} -p ${PID_FILE} ${OPTIONS} -sf $(cat ${PID_FILE}) $@
	RETVAL=$?
}

check_config() {
	/usr/sbin/haproxy -c -V -f ${CFG_FILE} ${OPTIONS}
	RETVAL=$?

	if [ ${RETVAL} -ne 0 ]; then
		echo "ERROR: Invalid/incorrect configuration file!"
	fi
}

pid() {
	cat ${PID_FILE}
	RETVAL=$?
}

check_socket
case "$1" in
	prepare)
		prepare
		;;
	background)
		shift
		start "-D $@"
		;;
	start)
		shift
		start "$@"
		;;
	stop)
		stop
		;;
	restart)
		restart
		;;
	status)
		status
		;;
	reload)
		reload
		;;
	check)
		check_config
		;;
	pid)
		pid
		;;
	*)
		echo $"Usage: $0 {prepare|start|background|stop|restart|status|reload|check|pid}"
esac

exit ${RETVAL}
