#!/usr/bin/bash
while [[ "$1" =~ ^-- ]]; do
        case "$1" in
                --memory-stats)
                        MEMSTATS=1
                        ;;

                --memory-query)
                        MEMQUERY=1
                        ;;

                --memory-usage)
                        MEMUSAGE=1
                        ;;

		--cpu-usage)
			CPUUSAGE=1
			;;

                *)
                        "Unknown option '$1'"
                        ;;
        esac
        shift
done

#
## MEMORY USAGE ##
#
# Memory related information is pulled from cgroup psuedo files
# as this is the most effective available method
#
if [[ $MEMSTATS -eq 1 ]]; then
	CNTRID="$1"
	METRIC="$2"
	set --
	awk -vM="$METRIC" -vR=ZBX_NOTSUPPORTED '{ if ($1 == M) R=$2 }; END { print R }' /sys/fs/cgroup/memory/system.slice/docker-"$CNTRID".scope/memory.stat
fi


if [[ $MEMQUERY -eq 1 ]]; then
	cat /sys/fs/cgroup/memory/system.slice/docker-"$1".scope/"$2"
fi

if [[ $MEMUSAGE -eq 1 ]]; then
	MEMUSAGE=$(cat /sys/fs/cgroup/memory/system.slice/docker-"$1".scope/memory.usage_in_bytes)
	MEMLIMIT=$(cat /sys/fs/cgroup/memory/system.slice/docker-"$1".scope/memory.limit_in_bytes)
	MEMT=$(awk '/MemTotal/ { byte = $2 *1024; print byte}' /proc/meminfo)

	# If docker reported memory limit is higher than system one, then there is no limit (use the system memory value)
	if [[ ${MEMLIMIT} -gt ${MEMT} ]]; then
	        MEMLIMIT=${MEMT}
	fi

	# Scale based on output of native percent item in zabbix (e.g. cpu)
	echo "scale=7; (${MEMUSAGE}/${MEMLIMIT}) *100" | bc
fi

#
## CPU USAGE ##
#
# The required CPU statistics to calculate the container cpu usage are not available through cgroup pseudo files
# Instead we use the docker (stats) API, which is SLOW - because the stats returned include variables which require multiple samplings and other time intensive tasks
# BUT - its still (2-3x) faster than using the 'docker stats' commmand (whut????)

#
# This code is basically a bash version of the native golang calculateCPUPercent function
# 
if [[ $CPUUSAGE -eq 1 ]]; then
	# See the CPUUsage and CPUStats structs from stats.go (docker source code)
	# for more information on each variable below
	#
	# Disable streaming - we only want one data sample
	apiStats=$(sudo /bin/curl --silent --unix-socket /var/run/docker.sock http://localhost/containers/"$1"/stats?stream=0)

	# PreCPUStats CPUStats (Pre=Previous)
	previousCPU=$(echo $apiStats | jq '.precpu_stats.cpu_usage.total_usage')
	previousSystem=$(echo $apiStats | jq '.precpu_stats.system_cpu_usage')

	# Base Statistics
	cpuPercent=0.0
	TotalUsage=$(echo $apiStats | jq '.cpu_stats.cpu_usage.total_usage')
	SystemUsage=$(echo $apiStats | jq '.cpu_stats.system_cpu_usage')
	PercpuUsage=$(echo $apiStats |  jq '.cpu_stats.cpu_usage.percpu_usage | length')

	# Float calc delta
	cpuDelta=$((${TotalUsage} - ${previousCPU}))
	systemDelta=$((${SystemUsage} - ${previousSystem}))

	# Source code treats deltas as floating points (even though they usually aren't) - we will do the same
	if [[ 1 -eq "$(echo "${systemDelta} > 0.0" | bc)" ]] && [[ 1 -eq "$(echo "${cpuDelta} > 0.0" | bc)" ]]; then
	#if [[ $systemDelta -gt 0 ]] && [[ $cpuDelta -gt 0 ]]; then
		# Scale based on output of native percent item in zabbix (e.g. cpu)
		cpuPercent=$(echo "scale=7; (${cpuDelta} / ${systemDelta}) * ${PercpuUsage} * 100.0" | bc)
	fi

	echo $cpuPercent
fi
