#!/bin/bash

function cpu_check() {
    local req_cpus=$REQ_CPUS
    local cpus=$(lscpu | awk '/^CPU(\(s\))?:/{print $2}')
    if [[ -n ${req_cpus} && -n ${cpus} ]]; then
        if [[ $(awk 'BEGIN{print('"$cpus"'<'"$req_cpus"')?0:1}') -eq 0 ]]; then
            log_error "运行环境：$RUNENV, CPU 核心数要求：$req_cpus core, 实际CPU核心数：$cpus core, 不符合运行要求"
            exit 10
        else
            log_info "运行环境：$RUNENV, CPU 核心数要求：$req_cpus core, 实际CPU核心数：$cpus core"
        fi
    else
        log_error "获取宿主机cpu核心数失败"
    fi
}

function mem_check() {
    local mem_total=$(cat /proc/meminfo | awk '/MemTotal:/{print $2$3}')
    local mem_gb=$(unit_convert $mem_total)
    local req_mem=${REQ_MEM:0:-1}
    if [[ -n ${req_mem} && -n ${mem_gb} ]]; then
        if [[ $(awk 'BEGIN{print('"$mem_gb"'<'"$req_mem"')?0:1}') -eq 0 && $(awk 'BEGIN{print('"$mem_gb"'-'"$req_mem"'<=-1)?0:1}') -eq 0 ]]; then
            log_error "运行环境：$RUNENV, 内存大小要求：${req_mem}gb, 实际内存大小：${mem_gb}gb, 不符合运行要求"
            exit 11
        else
            log_info "运行环境：$RUNENV, 内存大小要求：${req_mem}gb, 实际内存大小：${mem_gb}gb"
        fi
    else
        log_error "获取宿主机内存失败"
    fi
}

function disk_iops_test() {
    local disk=$1
    local iops=$(fio -filename=${disk}/fio.txt -direct=1 -iodepth 6 -thread -rw=write -ioengine=psync -bs=4k -size=5G -numjobs=8 -runtime=30 -group_reporting -name=mytest | grep IOPS | awk -F'IOPS=|,' '{print $2}' && rm -f ${disk}/fio.txt)
    local iops=$(iops_unit_convert $iops)
    local req_mid_disk_iops=${REQ_MID_DISK_IOPS:0:-1}
    if [[ -n ${req_mid_disk_iops} && -n ${iops} ]]; then
        if [[ $(awk 'BEGIN{print('"$iops"'<'"$req_mid_disk_iops"')?0:1}') -eq 0 ]]; then
            log_error "运行环境：$RUNENV, 磁盘iops最低要求：${req_mid_disk_iops}k, 实际测试磁盘iops：${iops}k, 不符合运行要求"
            exit 12
        else
            log_info "运行环境：$RUNENV, 磁盘iops最低要求：${req_mid_disk_iops}k, 实际测试磁盘iops：${iops}k"
        fi
    else
        log_error "测试主机磁盘 $disk iops 失败"
    fi
}

function iops_unit_convert() {
    typeset -l size
    size=$1
    to_k=$(echo $size | awk '{
            if($1 ~ /k$/){
                sub(/k$/,"");
                print $1
            } else {
                print $1/1000
            }
        }')
    echo $to_k
}

function disk_partation_size_check() {
    local check_partation=$1
    local req_size=$2
    local mounted=
    local mounted_avail=

    if [ ! -d $check_partation ];then
        log_error "check_partation: $check_partation is not exist, please create it"
        exit
    fi
    mounted=$(df -h $check_partation | awk 'NR!=1{print $NF}')

    log_info "检测到目录 $1, 使用的挂载分区为: $mounted"

    mounted="${mounted//\//\\/}"
    mounted_avail=$(df -h | awk '$NF ~ /^'"$mounted"'$/{print $(NF-2)}')
    mounted_avail=$(unit_convert $mounted_avail)
    req_size=${req_size:0:-1}
    mounted_avail=${mounted_avail:0:-1}
    if [[ -n ${req_size} && -n ${mounted_avail} ]]; then
        if [[ $(awk 'BEGIN{print('"$mounted_avail"'<'"$req_size"')?0:1}') -eq 0 ]]; then
            log_error "运行环境：$RUNENV, 查看目录空间：$check_partation, 磁盘空间要求：${req_size}g, 实际可用空间：${mounted_avail}g, 不符合运行要求"
            exit 13
        else
            log_info "运行环境：$RUNENV, 查看目录空间：$check_partation, 磁盘空间要求：${req_size}g, 实际可用空间：${mounted_avail}g"
        fi
    else
        log_error "获取主机磁盘空间失败"
    fi
}

function unit_convert() {
    typeset -l size
    size=$1
    to_gb=$(echo $size | awk '{
            if ($1 ~ /pb$/ || $1 ~ /p$/){
                print $1 * 1024 * 1024
            } else if ($1 ~ /tb$/ || $1 ~ /t$/){
                print $1 * 1024
            } else if ($1 ~ /gb$/ || $1 ~ /g$/){
                print $1
            } else if ($1 ~ /mb$/ || $1 ~ /m$/){
                print $1/1024
            } else if ($1 ~ /kb$/ || $1 ~ /k$/){
                print $1/1024/1024
            } else if ($1 ~ /b$/){
                print $1/1024/1024/1024
            }
        }')
    echo $to_gb
}

# function start_iperf3() {
#     # start iperf3
#     for _ip in ${IP_LIST[@]}; do
#         $SSH root@${_ip} "ps -ef | grep iperf | grep -v grep | awk '{print \$2}' | xargs kill -9"
#         $SSH root@${_ip} "iperf3 -s -D -I /tmp/iperf.pid"
#     done
# }

# function stop_iperf3() {
#     # stop iperf3
#     for _ip in ${IP_LIST[@]}; do
#         $SSH root@${_ip} "ps -ef | grep iperf | grep -v grep | awk '{print \$2}' | xargs kill -9"
#     done
# }

# function bandwidth_check() {
#     start_iperf3

#     # 各个IP相互测试
#     declare -a finish_arr
#     for _ip in ${IP_LIST[@]}; do
#         other_arr=(${IP_LIST[@]//$_ip/})
#         for _other in ${other_arr[@]}; do
#             if $(array_contains finish_arr $_other); then
#                 continue
#             fi
#             $SSH root@${_ip} "iperf3 -c $_other -f m -t 30 > /tmp/iperf3.log"
#             bandwidth=$($SSH root@${_ip} "cat /tmp/iperf3.log | grep sender | awk '{print \$7}'")
#             log_info "client: $_ip ===> server: $_other 之间带宽: $bandwidth Mbps"
#             if [ $bandwidth -lt 500 ]; then
#                 log_error "client: $_ip ===> server: $_other 之间带宽: $bandwidth Mbps, 小于500Mbp, 不符合安装要求。"
#                 stop_iperf3
#                 exit
#             fi
#         done
#         finish_arr=($finish_arr $_ip)
#     done

#     stop_iperf3
# }

function hardware_perfcheck() {
    ## 设置内存和磁盘的单位注意是g(或G)，不是gb(GB)，不要转换为m之类的，这地方没做校验
    if [ "${RUNENV}"x == "test"x ]; then
        REQ_CPUS=8
        REQ_MEM=16g
        REQ_MID_DISK_IOPS=1k
    elif [ "${RUNENV}"x == "prod"x ]; then
        REQ_CPUS=16
        REQ_MEM=32g
        REQ_MID_DISK_IOPS=6k
    fi
    REQ_SYS_ROOT=25g
    REQ_DOCKER_ROOT=80g

    [ -d $DOCKER_DATA_ROOT ] || mkdir -p $DOCKER_DATA_ROOT
    [ -d $MIDDLEWARE_DATA_PATH ] || mkdir -p $MIDDLEWARE_DATA_PATH
    
    log_info "start hardware perf check..."
    cpu_check
    mem_check
    log_info "检测宿主机根目录：/ 存储空间大小..."
    disk_partation_size_check "/" $REQ_SYS_ROOT
    log_info "检测docker root目录：$DOCKER_DATA_ROOT存储空间大小..."
    disk_partation_size_check $DOCKER_DATA_ROOT $REQ_DOCKER_ROOT

    if [[ $MIDDLEWARE_DATA_PATH =~ ^/dev || $MIDDLEWARE_DATA_PATH =~ ^/boot ]]; then
        log_error "不能设置中间件存储路径MIDDLEWARE_DATA_PATH在 /dev或/boot下"
        exit
    fi

    log_info "测试中间件存储路径：$MIDDLEWARE_DATA_PATH 的iops"
    disk_iops_test $MIDDLEWARE_DATA_PATH
    if [ $REGION == "mainregion" ]; then
        log_info "测试NAS是否满足安装权限"
        [ -d "$MIDDLEWARE_DATA_PATH" ] && touch $MIDDLEWARE_DATA_PATH/nas_perm.test
        if [ $? -ne 0 ]; then
            log_error "不能在$MIDDLEWARE_DATA_PATH创建测试文件，请确认是否挂载nas或目录是否存在"
            exit
        fi
        chown 999.999 ${MIDDLEWARE_DATA_PATH}/nas_perm.test
        if [ $(ls -nd ${MIDDLEWARE_DATA_PATH}/nas_perm.test | awk '$3==999&&$4==999{print "ok"}')x == "okx" ]; then
            log_info "nas 存储权限测试成功，满足中间件安装需求"
            rm -f $MIDDLEWARE_DATA_PATH/nas_perm.test
        else
            log_error "nas 存储权限测试失败，无法进行文件权限更改，不满足中间件安装"
            rm -f $MIDDLEWARE_DATA_PATH/nas_perm.test
            exit
        fi
    fi

    # 节点带宽测试
    # bandwidth_check
}
