#!/bin/bash
ARGS=("$@")
DISCOVERY_TYPE=$1
REDIS_CLI="/usr/bin/redis-cli"
STBDBUF_DEFAULT_PATH="/usr/bin/stdbuf"
# USE FIRST ARGUMENT TO UNDERSTAND WHICH DISCOVERY TO PERFORM
shift
IFS=$'\n'
PASSWORDS=( "$@" )
LIST=$(ps -eo user,args | grep -v grep | grep redis-server | awk -F " " '{print $3}')

discover_redis_instance() {
    HOST=$1
    PORT=$2
    PASSWORD=$3

    ALIVE=$($REDIS_CLI -h $HOST -p $PORT -a "$PASSWORD" ping 2>/dev/null)

    if [[ $ALIVE != "PONG" ]]; then
        return 1
    else
        INSTANCE=$($REDIS_CLI -h $HOST -p $PORT -a "$PASSWORD" info 2>/dev/null | grep config_file | cut -d ":" -f2 | sed 's/.conf//g' | rev | cut -d "/" -f1 | rev | tr -d [:space:] | tr [:lower:] [:upper:])
        # WHEN UNABLE TO IDENTIFY INSTANCE NAME BASED ON CONFIG
        if [ "$INSTANCE" = "" ]; then
            INSTANCE=$(echo "$HOST:$PORT")
        fi
        INSTANCE_RDB_PATH=$($REDIS_CLI -h $HOST -p $PORT -a "$PASSWORD" 4riDsjTToqLsSqaitj0dl6tcjR7lVIt get "dir" 2>/dev/null | cut -d " " -f2 | sed -n 2p)
        INSTANCE_RDB_FILE=$($REDIS_CLI -h $HOST -p $PORT -a "$PASSWORD" 4riDsjTToqLsSqaitj0dl6tcjR7lVIt get "dbfilename" 2>/dev/null | cut -d " " -f2 | sed -n 2p)
    fi

    echo $INSTANCE
}

discover_redis_rdb_database() {
    HOST=$1
    PORT=$2
    PASSWORD=$3

    ALIVE=$($REDIS_CLI -h $HOST -p $PORT -a "$PASSWORD" ping 2>/dev/null)

    if [[ $ALIVE != "PONG" ]]; then
        return 1
    else
        INSTANCE_RDB_PATH=$($REDIS_CLI -h $HOST -p $PORT -a "$PASSWORD" 4riDsjTToqLsSqaitj0dl6tcjR7lVIt get "dir" 2>/dev/null | cut -d " " -f2 | sed -n 2p)
        INSTANCE_RDB_FILE=$($REDIS_CLI -h $HOST -p $PORT -a "$PASSWORD" 4riDsjTToqLsSqaitj0dl6tcjR7lVIt get "dbfilename" 2>/dev/null | cut -d " " -f2 | sed -n 2p)
    fi

    echo $INSTANCE_RDB_PATH/$INSTANCE_RDB_FILE
}

discover_redis_available_commands() {
    HOST=$1
    PORT=$2
    PASSWORD=$3

    ALIVE=$($REDIS_CLI -h $HOST -p $PORT -a "$PASSWORD" ping 2>/dev/null)

    if [[ $ALIVE != "PONG" ]]; then
        return 1
    else
        REDIS_COMMANDS=$($REDIS_CLI -h $HOST -p $PORT -a "$PASSWORD" info all 2>/dev/null | grep cmdstat | cut -d":" -f1)
    fi

    ( IFS=$'\n'; echo "${REDIS_COMMANDS[*]}" )
}

discover_redis_available_slaves() {
    HOST=$1
    PORT=$2
    PASSWORD=$3

    ALIVE=$($REDIS_CLI -h $HOST -p $PORT -a "$PASSWORD" ping 2>/dev/null)

    if [[ $ALIVE != "PONG" ]]; then
        return 1
    else
        REDIS_SLAVES=$($REDIS_CLI -h $HOST -p $PORT -a "$PASSWORD" info all 2>/dev/null | grep ^slave | cut -d ":" -f1 | grep [0-1024])
    fi

    ( IFS=$'\n'; echo "${REDIS_SLAVES[*]}" )
}

generate_general_discovery_json() {
    HOST=$1
    PORT=$2
    INSTANCE=$3
    RDB_PATH=$4

    echo -n '{'
    echo -n '"{#HOST}":"'$HOST'",'
    echo -n '"{#PORT}":"'$PORT'",'
    echo -n '"{#INSTANCE}":"'$INSTANCE'",'
    echo -n '"{#RDB_PATH}":"'$RDB_PATH'"'
    echo -n '},'
}

generate_commands_discovery_json() {
    HOST=$1
    PORT=$2
    COMMAND=$3
    INSTANCE=$4

    echo -n '{'
    echo -n '"{#HOST}":"'$HOST'",'
    echo -n '"{#PORT}":"'$PORT'",'
    echo -n '"{#COMMAND}":"'$COMMAND'",'
    echo -n '"{#INSTANCE}":"'$INSTANCE'"'
    echo -n '},'
}

generate_replication_discovery_json() {
    HOST=$1
    PORT=$2
    SLAVE=$3
    INSTANCE=$4

    echo -n '{'
    echo -n '"{#HOST}":"'$HOST'",'
    echo -n '"{#PORT}":"'$PORT'",'
    echo -n '"{#SLAVE}":"'$SLAVE'",'
    echo -n '"{#INSTANCE}":"'$INSTANCE'"'
    echo -n '},'
}

generate_redis_stats_report() {
    HOST=$1
    PORT=$2
    PASSWORD=$3

    local REDIS_REPORT_RESULT="/tmp/redis-$HOST-$PORT"
    local REDIS_REPORT_RESULT_TMP="/tmp/redis-$HOST-$PORT.tmp"
    REDIS_REPORT=$($REDIS_CLI -h $HOST -p $PORT -a "$PASSWORD" info all 2>/dev/null > $REDIS_REPORT_RESULT_TMP)
    REDIS_REPORT_RC=$?

    local REDIS_SLOWLOG_LEN_RESULT="/tmp/redis-$HOST-$PORT-slowlog-len"
    local REDIS_SLOWLOG_LEN_RESULT_TMP="/tmp/redis-$HOST-$PORT-slowlog-len.tmp"
    REDIS_SLOWLOG_LEN=$($REDIS_CLI -h $HOST -p $PORT -a "$PASSWORD" slowlog len 2>/dev/null | cut -d " " -f2 > $REDIS_SLOWLOG_LEN_RESULT_TMP; $REDIS_CLI -h $HOST -p $PORT -a $PASSWORD slowlog reset 2>/dev/null > /dev/null )
    REDIS_SLOWLOG_LEN_RC=$?

    local REDIS_SLOWLOG_RAW_RESULT="/tmp/redis-$HOST-$PORT-slowlog-raw"
    local REDIS_SLOWLOG_RAW_RESULT_TMP="/tmp/redis-$HOST-$PORT-slowlog-raw.tmp"
    REDIS_SLOWLOG_RAW=$($REDIS_CLI -h $HOST -p $PORT -a "$PASSWORD" slowlog get 2>/dev/null > $REDIS_SLOWLOG_RAW_RESULT_TMP)
    REDIS_SLOWLOG_RAW_RC=$?

    local REDIS_MAX_CLIENTS_RESULT="/tmp/redis-$HOST-$PORT-maxclients"
    local REDIS_MAX_CLIENTS_RESULT_TMP="/tmp/redis-$HOST-$PORT-maxclients.tmp"
    REDIS_MAX_CLIENTS=$($REDIS_CLI -h $HOST -p $PORT -a "$PASSWORD" 4riDsjTToqLsSqaitj0dl6tcjR7lVIt get *"maxclients"* 2>/dev/null | cut -d " " -f2 | sed -n 2p > $REDIS_MAX_CLIENTS_RESULT_TMP)
    REDIS_MAX_CLIENTS_RC=$?

    if [[ -e $REDIS_REPORT_RESULT_TMP ]] && [[ $REDIS_REPORT_RC -eq 0 ]];then
        REDIS_REPORT_DUMP=$(mv $REDIS_REPORT_RESULT_TMP $REDIS_REPORT_RESULT)
        if [[ $? -ne 0 ]]; then
            return 1
        fi
    fi

    if [[ -e $REDIS_SLOWLOG_LEN_RESULT_TMP ]] && [[ $REDIS_SLOWLOG_LEN -eq 0 ]];then
        REDIS_REPORT_DUMP=$(mv $REDIS_SLOWLOG_LEN_RESULT_TMP $REDIS_SLOWLOG_LEN_RESULT)
        if [[ $? -ne 0 ]]; then
            return 2
        fi
    fi

    if [[ -e $REDIS_MAX_CLIENTS_RESULT_TMP ]] && [[ $REDIS_SLOWLOG_RAW_RC -eq 0 ]];then
        REDIS_REPORT_DUMP=$(mv $REDIS_SLOWLOG_RAW_RESULT_TMP $REDIS_SLOWLOG_RAW_RESULT)
        if [[ $? -ne 0 ]]; then
            return 2
        fi
    fi

    if [[ -e $REDIS_MAX_CLIENTS_RESULT_TMP ]] && [[ $REDIS_MAX_CLIENTS_RC -eq 0 ]];then
        REDIS_REPORT_DUMP=$(mv $REDIS_MAX_CLIENTS_RESULT_TMP $REDIS_MAX_CLIENTS_RESULT)
        if [[ $? -ne 0 ]]; then
            return 2
        fi
    fi

}

echo -n '{"data":['
for s in $LIST; do
    HOST=$(echo $s | sed 's/*/127.0.0.1/g' | awk -F ":" '{print $1}')
    PORT=$(echo $s | sed 's/*/127.0.0.1/g' | awk -F ":" '{print $2}')
    for (( i=0; i<${#PASSWORDS[@]}; i++ ));
      do
          PASSWORD=${PASSWORDS[$i]}
          INSTANCE=$(discover_redis_instance $HOST $PORT $PASSWORD)
          RDB_PATH=$(discover_redis_rdb_database $HOST $PORT $PASSWORD)
          COMMANDS=$(discover_redis_available_commands $HOST $PORT $PASSWORD)
          SLAVES=$(discover_redis_available_slaves $HOST $PORT $PASSWORD)
          if [[ -n $INSTANCE ]]; then
            if [[ $DISCOVERY_TYPE == "general" ]]; then
                generate_redis_stats_report $HOST $PORT $PASSWORD
                generate_general_discovery_json $HOST $PORT $INSTANCE $RDB_PATH
            elif [[ $DISCOVERY_TYPE == "stats" ]]; then
               for COMMAND in ${COMMANDS}; do
                 generate_commands_discovery_json $HOST $PORT $COMMAND $INSTANCE
               done
            elif [[ $DISCOVERY_TYPE == "replication" ]]; then
               for SLAVE in ${SLAVES}; do
                 generate_replication_discovery_json $HOST $PORT $SLAVE $INSTANCE
               done
            fi
          fi
    done
unset
done | sed -e 's:\},$:\}:'
echo -n ']}'
echo ''
unset IFS
