#!/bin/bash
# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

# Reason for this no-op: shellcheck disable=... before the first command disables the error for the
# entire script.
:

# Disable unused variable error (needed to keep track of version)
# shellcheck disable=SC2034
CMK_VERSION="2.3.0p10"

# sample output of pgrep command
# 1051 /usr/bin/redis-server 127.0.0.1:6380
# 1324 /usr/bin/redis-server 127.0.0.1:6379

# example cfg file /etc/check_mk/mk_redis.cfg
#
# REDIS_INSTANCES=(My_First_Redis My_Second_Redis My_socket_Redis)
#
# REDIS_HOST_My_First_Redis="127.0.0.1"
# REDIS_PORT_My_First_Redis="6380"
# REDIS_PASSWORD_My_First_Redis='MYPASSWORD'
#
# REDIS_HOST_My_Second_Redis="127.0.0.1"
# REDIS_PORT_My_Second_Redis="6379"

# REDIS_HOST_My_socket_Redis="/var/redis/redis.sock"
# REDIS_PORT_My_socket_Redis="unix-socket"

load_config() {
    # source optional configuration file
    if [ -e "$MK_CONFDIR/mk_redis.cfg" ]; then
        # shellcheck source=../cfg_examples/mk_redis.cfg
        . "$MK_CONFDIR/mk_redis.cfg"
    fi
}

redis_args() {
    INSTANCE=$1

    HOST="REDIS_HOST_$INSTANCE"
    PORT="REDIS_PORT_$INSTANCE"
    PASSWORD="REDIS_PASSWORD_$INSTANCE"

    # if autodetection is used, rewrite instance name for section output
    if [[ "$IS_DETECTED" == true ]]; then
        INSTANCE="${!HOST};${!PORT}"
    fi

    if [[ "${!PORT}" == "unix-socket" ]]; then
        REDIS_ARGS=("-s" "${!HOST}")
    else
        REDIS_ARGS=("-h" "${!HOST}" "-p" "${!PORT}")
    fi

    if [[ "${!PASSWORD}" ]] && [[ "${!PASSWORD}" != "None" ]]; then
        REDIS_CLI_COMMAND="REDISCLI_AUTH='${!PASSWORD}' redis-cli"
    else
        REDIS_CLI_COMMAND="redis-cli"
    fi

    REDIS_ARGS+=("info")
}

main() {
    set -e -o pipefail

    REDIS_INSTANCES=()
    IS_DETECTED=false

    load_config

    # if no servers in config file, try to detect
    if [ ${#REDIS_INSTANCES[@]} -eq 0 ]; then
        IS_DETECTED=true
        # find instances and remove entries like "*:6879", possible with docker container
        DETECTED=$(pgrep -xa "redis-server" 2>/dev/null | awk '/:[0-9]+/ && !/\*/ { print $3 }')

        # add found redis instances
        for REDIS_INSTANCE in $DETECTED; do
            for inst in $REDIS_INSTANCE; do
                IFS=":" read -ra parts <<<"$inst"

                # dot of IP can not be used in variable names
                REDIS_NAME=$(echo "$inst" | tr :. _)

                # create dynamic variables
                declare "REDIS_HOST_$REDIS_NAME=${parts[0]}"
                declare "REDIS_PORT_$REDIS_NAME=${parts[1]}"

                # append instance to array
                REDIS_INSTANCES+=("${REDIS_NAME}")
            done
        done
    fi

    # print redis section, if servers are found
    [ "${REDIS_INSTANCES[*]}" ] || exit 0

    echo "<<<redis_info:sep(58)>>>"

    for INSTANCE in "${REDIS_INSTANCES[@]}"; do
        redis_args "${INSTANCE}"
        # print server section
        echo "[[[$INSTANCE|${!HOST}|${!PORT}]]]"

        # TODO: Use an array instead of the suppression for the command, too.
        # shellcheck disable=SC2086
        waitmax 3 bash -c "${REDIS_CLI_COMMAND} ${REDIS_ARGS[*]}" || true
        echo
    done

}

[ -z "${MK_SOURCE_ONLY}" ] && main "$@"
