#!/usr/bin/env bash

function _stdout {
    echo "[rondb-diagnostics] $1"
}

_stdout "+------------------------+"
_stdout "| RonDB diagnostics tool |"
_stdout "+------------------------+"

if [[ "$#" -lt 1 ]];
then
    echo "Usage: $0 TYPE [hosts]"
    echo " > TYPE must be one of MGMD NDBD or MYSQLD"
    echo " > optionally specify a list of space separated hosts that must be reachable from this VM"
    exit 0
fi

user=$(whoami)
if [[ "$user" != "root" ]];
then
    echo "You must run this script as root"
    exit 2
fi

read -p "We are going to gather logs from $HOSTNAME Proceed? (y/n)" proceed
if [[ ! $proceed =~ ^[Yy]$ ]];
then
    echo "OK"
    exit 0
fi

# First argument is the the type of node we gather logs for
TYPE=$1
# Anything afterwards is a list of hosts to check connectivity
hosts=(${@:2})

tmpdir=$(dirname $(mktemp -u))
_date=$(date '+%Y-%m-%d-%H-%M-%S')
root_diagnostics="${tmpdir}/rondb-diagnostics-${HOSTNAME}_${_date}"
diagnostics_base=$(basename ${root_diagnostics})
rm -rf $root_diagnostics
mkdir -p $root_diagnostics

ARCHIVE="${diagnostics_base}.tar.gz"
GENERAL_LOG="${root_diagnostics}/general.txt"
PROCESSES_LOG="${root_diagnostics}/processes.txt"
DMESG_LOG="${root_diagnostics}/dmesg.txt"
NETWORK_LOG="${root_diagnostics}/network.txt"

MYSQL_CLUSTER="/srv/hops/mysql-cluster"

function _general_log {
    _log2file "${1}" $GENERAL_LOG
}

function _processes_log {
    _log2file "${1}" $PROCESSES_LOG
}

function _dmesg_log {
    _log2file "${1}" $DMESG_LOG
}

function _net_log {
    _log2file "${1}" $NETWORK_LOG
}

function _log2file {
    msg=$1
    target=$2
    echo "$msg" >> $2
}

_stdout "Getting basic information"

_stdout "Hostname"
hostname=$(hostname -A)
_general_log ">> HOSTNAME: ${hostname}"
_general_log ""

_stdout "IP addresses"
ip_info=$(ip addr show)
_general_log "+--------------+"
_general_log "| IP addresses |"
_general_log "+--------------+"
_general_log "${ip_info}"
_general_log ""

_stdout "CPU info"
_general_log "+----------+"
_general_log "| CPU info |"
_general_log "+----------+"
cat /proc/cpuinfo >> $GENERAL_LOG
_general_log ""

_stdout "Memory"
_general_log "+--------+"
_general_log "| Memory |"
_general_log "+--------+"
mem=$(free -m)
_general_log "${mem}"
_general_log ""

_stdout "Filesystems information"
mounts=$(mount)
_general_log "+-------------------+"
_general_log "| Filesystem mounts |"
_general_log "+-------------------+"
_general_log "${mounts}"
_general_log ""

df=$(df -h)
_general_log "+------------------+"
_general_log "| Filesystem usage |"
_general_log "+------------------+"
_general_log "${df}"
_general_log ""

block_devs=$(lsblk)
_general_log "+---------------+"
_general_log "| Block devices |"
_general_log "+---------------+"
_general_log "${block_devs}"
_general_log ""

_stdout "Currently running processes"
procs=$(ps aux)
_processes_log "+-------------------+"
_processes_log "| Running processes |"
_processes_log "+-------------------+"
_processes_log "${procs}"

_stdout "System logs"
dmesg=$(dmesg)
_dmesg_log "+-------+"
_dmesg_log "| dmesg |"
_dmesg_log "+-------+"
_dmesg_log "${dmesg}"

mkdir -p ${root_diagnostics}/sys_logs
cp -RL /var/log/* ${root_diagnostics}/sys_logs

_stdout "ndb-agent logs"
journalctl -u ndb-agent.service > ${root_diagnostics}/ndb-agent.log

_stdout "Network ports"
command -v netstat &> /dev/null
exists=$?
if [[ $exists -eq 0 ]];
then
    _net_log "+----------------+"
    _net_log "| Netstat result |"
    _net_log "+----------------+"
    ports=$(netstat -apn)
    _net_log "$ports"
    _net_log ""
else
    _stdout ">> Skip gathering network ports. netstat is not installed"
fi

_stdout "Check hosts connectivity"
if [ -n "$hosts" ]; then
    _net_log "+----------------------+"
    _net_log "| Connectivity results |"
    _net_log "+----------------------+"
    for h in "${hosts[@]}"
    do
        ping_result=$(ping -c 1 -W 2 ${h})
        _net_log "$ping_result"
        _net_log ""
    done
fi

function _mgm_logs {
    MGMD_LOGS="${root_diagnostics}/mgmd"
    mkdir -p "${MGMD_LOGS}"
    _stdout "Getting RonDB cluster status"
    cluster_status=$(${MYSQL_CLUSTER}/ndb/scripts/mgm-client.sh -e show)
    echo "$cluster_status" >> $MGMD_LOGS/cluster-status.txt
    echo "" >> $MGMD_LOGS/cluster-status.txt

    cluster_memory=$(${MYSQL_CLUSTER}/ndb/scripts/mgm-client.sh -e "ALL REPORT MEMORYUSAGE")
    echo "$cluster_memory" >> $MGMD_LOGS/cluster-status.txt

    _stdout "Copying RonDB mgmd logs"
    cp -RL "${MYSQL_CLUSTER}/log" $MGMD_LOGS
}

function _ndbd_logs {
    NDBD_LOGS="${root_diagnostics}/ndbd"
    mkdir -p "${NDBD_LOGS}"

    _stdout "Copying RonDB ndbd logs"
    cp -RL "${MYSQL_CLUSTER}/log" $NDBD_LOGS
}

function _mysqld_logs {
    tablespaces=$(${MYSQL_CLUSTER}/ndb/scripts/mysql-client.sh -e "SELECT TABLESPACE_NAME, FREE_EXTENTS, TOTAL_EXTENTS, EXTENT_SIZE FROM information_schema.FILES WHERE FILE_TYPE='DATAFILE'")
    echo "$tablespaces" >> "${root_diagnostics}/tablespaces.txt"
    
    MYSQLD_LOGS="${root_diagnostics}/mysqld"
    mkdir -p "${MYSQLD_LOGS}"

    _stdout "Copying MySQLd logs"
    cp -RL "${MYSQL_CLUSTER}/log" $MYSQLD_LOGS
}

case $TYPE in
    MGMD)
        _stdout "Gathering logs for RonDB Management server"
        _mgm_logs
        ;;
    
    NDBD)
        _stdout "Gathering logs for RonDB Datanode"
        _ndbd_logs
        ;;
    MYSQLD)
        _stdout "Gathering logs for MySQL server"
        _mysqld_logs
        ;;
    *)
        _stdout "Unknown type. Must be MGMD || NDBD || MYSQLD"
        exit 1
        ;;
esac


_stdout "Archiving logs to ${tmpdir}/$ARCHIVE"
pushd $tmpdir
tar czf $ARCHIVE ${diagnostics_base}
_stdout "Finished"