#!/bin/bash
# ======================================================================
#
# Shared functions for DOCKER checks
#
# requirements:
# - docker
# - jq
#
# ----------------------------------------------------------------------
# Cli docs:
# https://docs.docker.com/engine/reference/commandline/docker/
# ----------------------------------------------------------------------
# 2024-01-19  v1.0  <axel.hahn@unibe.ch>      init
# 2024-01-29  v1.1  <axel.hahn@unibe.ch>      _detectDockererror
# ======================================================================


. $(dirname $0)/inc_pluginfunctions

_is_docker_rootless=0
_is_docker_detected=0

# ----------------------------------------------------------------------
# FUNCTIONS
# ----------------------------------------------------------------------

# filter json data with jq
# param  string  json data
# param  string  jq filter
function _filterJson(){
    echo "$1" | jq -r "$2"
}

# filter json data with jq (by expecting a single result) and remove quotes
# param  string  json data
# param  string  jq filter
function _getString(){
    _filterJson "$1" "$2" | sed "s#^null\$##g"
}

# if DOCKER_HOST is not set we try to detect the user running "containerd"
# create an env var DOCKER_HOST="unix:///run/user/<ID>/docker.sock"
function _detectDockerenv(){
    local dockeruid=
    if [ -z "$DOCKER_HOST" ]; then
        dockeruid=$( ps -ef | grep containerd | grep -Eo "/run/user/([0-9]*)/" | head -1 | cut -f 4 -d '/' )
        if [ -n "$dockeruid" ]; then
            _is_docker_detected=1
            export DOCKER_HOST="unix:///run/user/$dockeruid/docker.sock"
        fi
        # Don't abort - it is allowed that the variable DOCKER_HOST is missing
    fi
    if grep "/run/user/[0-9]*" <<< "$DOCKER_HOST" >/dev/null; then
        _is_docker_rootless=1
    fi
}

# show some debug infos to be shown if needed.
function _debugInfos(){
    echo
    echo "DEBUG INFOS:"
    echo "DOCKER_HOST = $DOCKER_HOST"
    test "$_is_docker_detected" -eq 0 && echo "It was set in the environment."
    test "$_is_docker_detected" -eq 1 && echo "It was detected from process list."
    echo
}
# detect error after dicker command. It stops if
# - no content was fetched
# - content contains key "ServerErrors"
# param  string  output of docker command (json)
# param  bool    flag: is output from docker system info
function _detectDockererror(){

    local data="$1"
    if [ -z "$data" ] ; then
        if [ "$2" != "1" ]; then
            # zero output could mean:
            # - connect to docker failed
            # - no data because no container is running
            # --> let's detect it...
            infos=$( sudo -n --preserve-env docker system info --format '{{ json . }}' )
            _detectDockererror "$infos"

            typeset -i iCRunning;
            iCRunning=$(_getString "$data" ".ContainersRunning" )
            if [ "$iCRunning" -eq "0" ]; then
                ph.status "No data. No container is running"
                ph.exit
            fi
        fi

        ph.setStatus unknown
        ph.status "No data. Unable to fetch Docker information."
        ph.exit
    fi

    if grep '"ServerErrors"' <<<"$data" >/dev/null; then
        ph.setStatus unknown
        ph.status "Unable to connect to Docker:"
        _filterJson "$data" ".ServerErrors" | grep "^ "
        ph.exit
    fi

}
# ----------------------------------------------------------------------