#!/bin/env bash
##Description: normal check


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

function f_PrintLog
{
    _LogFlag=$(echo "$1"|tr "a-z" "A-Z")
    _LogMessage=$2
    [ $(echo "$1"|wc -L) -eq 4 ] && _LogFlag=$(echo "${_LogFlag}_")
    if [ -w "${LogFile}" ]
    then
      echo "$(date "+%Y%m%d.%H%M%S"):[${_LogFlag}]:${UserName}@${HostName}:${2}"|tee -a "${LogFile}"
    else
      echo "$(date "+%Y%m%d.%H%M%S"):[${_LogFlag}]:${UserName}@${HostName}:${2}"
    fi
    
    [ "${_LogFlag}" = "ERROR" ] && exit 33 || return 0;

}

###############################################################################


###############################################################################
##Init##
export LANG=en_US
TidbHome=$(awk -F: -v un="tidb" '{if($1==un){print $6;exit}}' /etc/passwd 2>/dev/null)
NumProc=$(awk '/^processor[ |\t]*:/{c++}END{print c}' /proc/cpuinfo 2>/dev/null)
ShellName="$(echo $0|awk -F / '{print $NF}')";ShellOption="$@";
WorkDir="${TidbHome}/scripts/normalcheck"
LogDir="${TidbHome}/scripts/normalcheck/logs";mkdir -p ${LogDir};
RunTs=$(date "+%Y%m%d.%H%M%S")
LogFile="${LogDir}/${ShellName}.${RunTs}.log";touch ${LogFile};
Shellcksum=$(cksum ${WorkDir%/}/${ShellName} 2>/dev/null|awk '{printf "%d",$1}')
declare -i UserID=$(id -u);declare UserName=$(whoami);declare HostName=$(hostname);
###############################################################################
##TiDB Var##
locallogin="tidblogin"
adminusers="root,tidb,timon,repl,dsg"
user="timon";pAsswd="VGltb25fMjAyMQo"
###############################################################################
###############################################################################
function f_generate_variable_file
{
    f_PrintLog "Info" "Start to run function f_generate_variable_file."
    # echo -e "Pls input the tikv node nums on one machine:"
    # read NODE_NUM
    # echo -e "Pls input the system top level[A|B|C|D]:"
    # read TOP
    >${WorkDir}/config/tidb_vars.config
    echo "OS_USER=tidb"    >> ${WorkDir}/config/tidb_vars.config
    echo "TOP_LEVEL=C"    >> ${WorkDir}/config/tidb_vars.config
    echo "ADMINUSERS=${adminusers}"    >> ${WorkDir}/config/tidb_vars.config
    echo "CPU_TYPE=`uname -p`"    >> ${WorkDir}/config/tidb_vars.config
    echo "CPU_CNT=${NumProc}"    >> ${WorkDir}/config/tidb_vars.config
    echo "MEM_TOTAL=`cat /proc/meminfo | awk -F: '{if($1=="MemTotal"){printf "%d",$2}}'`"    >> ${WorkDir}/config/tidb_vars.config
    echo "NODE_NUM=3"    >> ${WorkDir}/config/tidb_vars.config
    echo "PASSWD=VGltb25fMjAyMQo"   >> ${WorkDir}/config/tidb_vars.config

    # 获取集群名称
    if [ -n "${ClsName}" ]
    then
        CLUSTER_NAME=$(tiup cluster list | awk -v cs="${ClsName}" '{if($1==cs){print $1;exit}}')
    fi
    
    if [ -z "${CLUSTER_NAME}" ]
    then
        CLUSTER_NAME=$(tiup cluster list | sed -n '3p' | awk '{print $1}')
    fi
    

    clsVersion=$(tiup cluster list | awk -v cs="${CLUSTER_NAME}" '{if($1==cs){print $3;exit}}')
    localProc=$(ps -ef | grep "tidb-server -P 4000"| grep -v grep)
    localIp=$(echo ${localProc}|awk -F"--advertise-address=" '{print $2}'|awk '{printf "%s",$1}')
    clsNodes=$(tiup cluster display ${CLUSTER_NAME}|awk '{if($1~"^[1-9]"){gsub(":.*","",$1);N[$1]=1}}END{for(ip in N){printf "%s ",ip}}')
    clsRoles=$(tiup cluster display ${CLUSTER_NAME}|awk '{if($1~"^[1-9]"){N[$2]=1}}END{for(role in N){printf "%s,",role}}')
    promNode=$(tiup cluster display ${CLUSTER_NAME}|awk '{if($1~"^[1-9]" && $2=="prometheus")N[$3]=1}END{for(ip in N){printf "%s ",ip}}')
    
    echo "CLUSTERNAME=${CLUSTER_NAME}"   >> ${WorkDir}/config/tidb_vars.config
    echo "CLUSTERVERSION=${clsVersion}"   >> ${WorkDir}/config/tidb_vars.config
    echo "CLUSTERCOMPONENTS=${clsRoles%,*}"   >> ${WorkDir}/config/tidb_vars.config
    echo "LOCALNODE=${localIp}"   >> ${WorkDir}/config/tidb_vars.config
    echo "CLUSTERNODES=\"${clsNodes}\""   >> ${WorkDir}/config/tidb_vars.config
    echo "PROMETHEUSNODE=\"${promNode}\""   >> ${WorkDir}/config/tidb_vars.config
}


function f_generate_parameter_config_file
{
    f_PrintLog "Info" "Start to run function f_generate_parameter_config_file."
    #根据csv文件生成参数合规配置文件
    if [ ! -f ${WorkDir}/config/tidb_parameter.csv ]
    then 
        f_PrintLog "Error" "TiDB parameter config csv not exist, pls provide ${WorkDir}/config/tidb_parameter.csv, exit!!!"
    fi

    f_PrintLog "Info" "run python ${WorkDir}/generate_parameter_config.py ${WorkDir} ${WorkDir}/config/tidb_parameter.csv!"
    python ${WorkDir}/generate_parameter_config.py ${WorkDir} ${WorkDir}/config/tidb_parameter.csv
    if [ $? -eq 0 -a -f ${WorkDir}/config/tidb_parameter.config ]
    then
        f_PrintLog "Info" "TiDB parameter config generate successful, config file is ${WorkDir}/config/tidb_parameter.config!"
    else
        f_PrintLog "Error" "TiDB parameter config generate failed, config file is ${WorkDir}/config/tidb_parameter.config, exit!!!"
    fi
}


function f_push_scripts
{
    f_PrintLog "Info" "Start to run function f_push_scripts."
    
    #传输需要远程执行的检查脚本
    f_PrintLog "Info" "Start to push all scripts."
    scripts_lst=$(awk -F: '{if($1=="ENABLE" && $2=="all"){printf "%s ",$5}}' ${WorkDir}/config/tidb_check_item.config 2>/dev/null)
    if [ -z "${scripts_lst}" ]
    then
        f_PrintLog "Warn" "No script need to push remote host."
        return 0
    else
        f_PrintLog "Info" "start to push scripts: ${scripts_lst}"
    fi

    for node in ${CLUSTERNODES}
    do
        if [ "${LOCALNODE}" = "${node}" ];then
          continue
        fi
        f_PrintLog "Info" "start push scripts to remote host ${node}"
        tiup cluster exec ${CLUSTERNAME} --command="mkdir -p ${WorkDir}/script" -N${node}
        for sc in ${scripts_lst}
        do
            tiup cluster push ${CLUSTERNAME} "${WorkDir}/script/${sc}" "${WorkDir}/script/${sc}" -N${node} --yes
            if [ $? -ne 0 ]
            then 
                f_PrintLog "Warn" "Push script ${sc}  failed."
            fi
        done  
    done

    #传输prometheus需要远程执行的检查脚本
    f_PrintLog "Info" "Start to push prometheus scripts."
    scripts_lst=$(awk -F: '{if($1=="ENABLE" && $2=="prometheus"){printf "%s ",$5}}' ${WorkDir}/config/tidb_check_item.config 2>/dev/null)
    if [ -z "${scripts_lst}" ]
    then
        f_PrintLog "Warn" "No script need to push remote prometheus host."
        return 0
    else
        f_PrintLog "Info" "start to push scripts: ${scripts_lst}"
    fi

    for node in ${PROMETHEUSNODE}
    do
        if [ "${LOCALNODE}" = "${node}" ];then
          continue
        fi
        f_PrintLog "Info" "start push scripts to remote host ${node}"
        tiup cluster exec ${CLUSTERNAME} --command="mkdir -p ${WorkDir}/script" -N${node}
        tiup cluster exec ${CLUSTERNAME} --command="mkdir -p ${WorkDir}/config" -N${node}
        tiup cluster push ${CLUSTERNAME} "${WorkDir}/config/tidb_vars.config" "${WorkDir}/config/tidb_vars.config" -N${node} --yes

        for sc in ${scripts_lst}
        do
            tiup cluster push ${CLUSTERNAME} "${WorkDir}/script/${sc}" "${WorkDir}/script/${sc}" -N${node} --yes
            if [ $? -ne 0 ]
            then 
                f_PrintLog "Warn" "Push script ${sc}  failed."
            fi
        done  
    done

}


function f_run_scripts
{
    f_PrintLog "Info" "Start to run function f_run_scripts."
    f_PrintLog "Info" " python ${WorkDir}/run_normalcheck.py ${WorkDir} ${CLUSTERNAME}" 
    python "${WorkDir}"/run_normalcheck.py "${WorkDir}" "${CLUSTERNAME}" 
    if [ $? -eq 0 ]
    then
      f_PrintLog  "Info" "run normalcheck finished!"
    else
      f_PrintLog  "Error" "run normalcheck failed!"
    fi
}

###################
####    Main   ####
###################
function f_normalcheck_main
{
    f_PrintLog "Info" "Start to run Script ${ShellName} on ${HostName}, I am ${UserName}."
    #tiup检查
    which tiup 2>/dev/null
    if [ $? -ne 0 ]
    then
        f_PrintLog "Error" "Script should run on tiup host, pls check tiup was installed, exit!!!"
    fi

    #判断脚本执行所需的文件存在

    #首次执行,生成脚本执行所需的变量
    if [ ! -f "${WorkDir}/config/tidb_vars.config" ] 
    then
        f_generate_variable_file
    else
        f_PrintLog "Info" "Normal Check var config already exist, ${WorkDir}/config/tidb_vars.config"
    fi
    
    #首次执行,生产数据库参数配置文件
    if [ ! -f "${WorkDir}/config/tidb_parameter.config" ] 
    then
        f_generate_parameter_config_file
    else
        f_PrintLog "Info" "Normal Check parameter config already exist, ${WorkDir}/config/tidb_parameter.config"
    fi

    source ${WorkDir}/config/tidb_vars.config

    #传输可执行脚本到远程服务器
    f_push_scripts
    f_run_scripts

}


f_normalcheck_main



