#!/bin/env bash
##Description: precheck before tidb dr swtich over 

function f_syntax
{
    [ ! -z "$1" ] && echo ">>[$(date "+%Y%m%d.%H%M%S")] $1"
    echo " "
    echo "bash ${ShellName}  [-hostname <hostname>]"
    echo "[-clsname <clsname>] "
    echo " "
    echo " #sample:"
    echo " #sh ${ShellName} -clsname sa2 "
    exit 22
}

function f_PrintLog
{
    _LogFlag=$(echo "$1"|tr "a-z" "A-Z")
    _LogMessage=$2
    declare LogFile="${LogFile:-"/tmp/${PShellName:-${ShellName}}.log"}"
    touch "${LogFile}" 2>/dev/null
    if [ -w "${LogFile}" ]
    then
        echo "[${_LogFlag}]:$(date "+%Y%m%d.%H%M%S"):${UserName}@${HostName}:${2}"|tee -a "${LogFile}";
    else
        echo "[${_LogFlag}]:$(date "+%Y%m%d.%H%M%S"):${UserName}@${HostName}:${2}";
    fi
}


###############################################################################
##Init##
ShellName="$(echo $0|awk -F / '{print $NF}')";ShellOption="$@";
WorkDir="$(echo $0|sed s/${ShellName}//g)";[ -z "${WorkDir}" ] && WorkDir=${PWD};cd ${WorkDir};WorkDir=${PWD}
LogDir="${WorkDir%/}/logs";mkdir -p ${LogDir};chmod ugo+rwx ${LogDir} 2>/dev/null
LogFile="${LogDir}/${ShellName}.$(date "+%Y%m%d.%H%M%S").log";LogLevel=3;
touch "${LogFile}" 2>/dev/null;chmod ugo+rw "${LogFile}" 2>/dev/null
declare Shellcksum=$(cksum ${WorkDir%/}/${ShellName} 2>/dev/null|awk '{printf "%d",$1}')
typeset -i UserID=$(id -u);typeset UserName=$(whoami);typeset HostName=$(hostname);
###############################################################################
##Get inopt
[ -z "${ShellOption}" ] && f_syntax;
for inopt in ${ShellOption}
do
    case $(echo $inopt|tr a-z A-Z) in
    -HOSTNAME|-HOST) CurOpt="-HOSTNAME";continue;;
    -CLSNAME|-C) CurOpt="-CLSNAME";continue;;
    -DRAINER|-D) CurOpt="-DRAINER";continue;;
    -PRIMARY|-P) CurOpt="-PRIMARY";declare In_ClsRole="PRIMARY";continue;;
    -STANDBY|-S) CurOpt="-STANDBY";declare In_ClsRole="STANDBY";continue;;
    -LOGLEVEL|-L) CurOpt="-LOGLEVEL";continue;;
    -HELP|--HELP|-H) f_syntax;;
    -*) CurOpt="";continue;;
    esac
    case "${CurOpt}" in
    -HOSTNAME) declare LocalHost="${inopt}";continue;;
    -CLSNAME) declare clsname="${inopt}";continue;;
    -DRAINER) declare DrainerName="${inopt}";continue;;
    -LOGLEVEL) declare -i LogLevel=${inopt:-3};[ ${LogLevel} -eq 5 ] && set -x;continue;;
    esac
done

f_PrintLog "Info" "Start to run Script ${ShellName}, the Shellcksum is ${Shellcksum}"
f_PrintLog "Debug" "Script Options:${ShellOption}"


function f_checkusedtool
{
    f_PrintLog "Info" "Start to run f_checkusedtool."
    binary_list="$1"
    f_PrintLog "Info" "Start to check command: ${binary_list}"
    total_fail=0
    total_cmd=0
    for bin_cmd in $(echo ${binary_list})
    do 
        _rt=$(which ${bin_cmd} 2>/dev/null)
        cmd_ok=$?
        if [ ${cmd_ok} -eq 0 ]
        then
            f_PrintLog "Info" "command ${bin_cmd} was installed on ${_rt}."
        else
            f_PrintLog "Info" "command ${bin_cmd} was not installed. ${_rt}"
            total_fail=$(($total_fail+1))
        fi
        total_cmd=$(($total_cmd+1))
    done
    [ ${total_fail} -gt 0 ] && f_PrintLog "Error" "check command failed, fail/total num is ${total_fail}/${total_cmd}"
}


function f_checktidbbinlog
{
    f_PrintLog "Info" "Start to run f_checkbinlog."
    binlog_url=$1
    # binlogstatus=$(curl "http://${binlog_url}/info/all")
    # f_formatjson ${binlogstatus}
    binlog_down=$(curl -s "http://${binlog_url}/info/all" | awk -F: '{
        if($1~"binlog_status" && $2!~"On"){gsub("[, ]","",$2);gsub("\"","",$2);printf "%s",$2;exit}
    }')

    binlog_up=$(curl -s "http://${binlog_url}/info/all" | awk -F: '{
        if($1~"binlog_status" && $2~"On"){gsub("[, ]","",$2);gsub("\"","",$2);printf "%s",$2;exit}
    }')
    
    curl -s "http://${binlog_url}/info/all" | awk -F: '
    /^[ "]*ip.*/{gsub("[, ]","",$2);gsub("\"","",$2);ip=$2}
    /^[ "]*listening_port.*/{gsub("[, ]","",$2);gsub("\"","",$2);port=$2}
    /^[ "]*binlog_status.*/{gsub("[, ]","",$2);gsub("\"","",$2);binlog=$2}
    /^[ "]*server_id.*/{TiDB[$2]=tidb;IP[$2]=ip;Port[$2]=port;Binlog[$2]=binlog;}
    END{for(a in TiDB){printf "binlog_status: %s:%s %s\n",IP[a],Port[a],Binlog[a]}}
    '

    if [ "${binlog_down:-On}" = "On" -a "${binlog_up:-Off}" = "On" ]
    then
        f_PrintLog "Info" "binlog_status is ok."
    else
        f_PrintLog "Error" "binlog_status check failed. binlog_status is ${binlog_up}:${binlog_down}"
        exit 1
    fi
}


function f_checkdrainer
{
    f_PrintLog "Info" "Start to run f_checkdrainer."
    drainer_name="$1"

    #clsinfo 
    dr_up=$(echo "${tidbclsinfo}"|awk -v drname="${drainer_name}" '{
        if(NF>=8 && $2=="drainer" && $1==drname){printf "%s",$6;exit}}
        ')
    if [ "${dr_up}" = "Up" ]
    then
        f_PrintLog "Info" "drainer ${drainer_name} status is ok."
    else
        f_PrintLog "Error" "drainer ${drainer_name} status check failed. drainer status is ${dr_up}"
        exit 1
    fi
}


function f_checktidb
{
    f_PrintLog "Info" "Start to run f_checktidb."
    tidb_clsname="$1"

    #tidb status
    f_PrintLog "Info" "the Up node list:" 
    echo "${tidbclsinfo}"|awk '{
        if(NF>=8 && $2~"[pd|ti|pr|pu|dr|pr]" && $6~"Up"){printf "%20s %15s %10s\n",$1,$2,$6}
        }'
    
    f_PrintLog "Info" "the Down node list:" 
    echo "${tidbclsinfo}"|awk '{
        if(NF>=8 && $2~"[pd|ti|pr|pu|dr|pr]" && $6!~"Up"){printf "%20s %15s %10s\n",$1,$2,$6}
        }'
}


function f_checkmain
{
    #check binary command
    # binary_list="tiup mysql bash sqlplus curl dumpling lightning"
    # f_checkusedtool "${binary_list}"
    

    #check tidb
    tiup cluster list
    clslist=$(tiup cluster list |awk '{
        if($3~"v" && $4~"tiup"){printf "%s:%s\n",$1,$3;}
        }') 
    if [ -z "$(echo ${clslist} | grep -w ${clsname})" ]
    then
        f_PrintLog "Error" "TiDB cluster ${clsname} not found, valid cluster: ${clslist} !!!"
        exit 1
    else
        tiup cluster display ${clsname}
        tidbclsinfo=$(tiup cluster display ${clsname})
        f_checktidb ${clsname}
    fi

    
    #check binlog status
    tidburl=$(echo "${tidbclsinfo}"|awk '{
        if(NF>=8 && $2=="tidb" && $6=="Up" ){gsub(".*/","",$4);printf "%s:%s\n",$3,$4;exit}
        }')
    if [ -z "${tidburl}" ] 
    then
        f_PrintLog "Error" "Failed to check tidb binlog status. tidburl is null!!!"
    else
        f_PrintLog "Info" "Start to check tidb binlog status. tidburl: ${tidburl}"
        f_checktidbbinlog ${tidburl}
    fi

    #check drainer status
    drainerurl=$(echo "${tidbclsinfo}"|awk '{
        if(NF>=8 && $2=="drainer"){printf "%s\n",$1}
        }')

}

###################
####    Main   ####
###################

f_checkmain


