#!/bin/bash
# Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
# Description: dataturbo
# Create: 2022/01/22
#

CUR_DIR="$( cd "$( dirname "$0"  )" && pwd )"
INSTALL_DIR="/opt/oceanstor/dataturbo"
readonly SHIM_CONF_FILE="${INSTALL_DIR}/conf/shim_config.xml"
readonly DPC_USER_CONF="${INSTALL_DIR}/conf/dpc_user_config.xml"
readonly LOG_FILE="/var/log/dataturbo/dataturbo_script/dataturbo.action.log"
# 服务校验array，后续新增服务，在此新增
readonly srv_array=(dataturbo)

CGROUP_LIMIT=( 
"8,30" 
"12,50"
"20,95"
)

function usage()
{
    echo "usage: $0 [-h|-s]"
    echo "  -h                         display help."
    echo "  -s [srv_name]              install and start srv_name service.[Multiple srv_name are separated by commas (,).]"
    echo "  -S                         install dataturbo and start all service."
}

#仅在rpm包安装后才可使用日志函数
function log_info()
{
    if  [ ! -f ${LOG_FILE} ] || [ -L ${LOG_FILE} ]; then
        return
    fi
    local func_name=${FUNCNAME[1]}
    if [ "$2" != "" ]; then
        func_name="$2"
    fi
    echo "[`date "+%Y-%m-%d %T"`:$$][INFO][dataturbo][${0##*/}][${func_name}]:" "$1" >> ${LOG_FILE}
}

function log_error()
{
    if  [ ! -f ${LOG_FILE} ] || [ -L ${LOG_FILE} ]; then
        return
    fi
    local func_name=${FUNCNAME[1]}
    if [ "$2" != "" ]; then
        func_name="$2"
    fi
    echo "[`date "+%Y-%m-%d %T"`:$$][ERR][dataturbo][${0##*/}][${func_name}]:" "$1" >> ${LOG_FILE}
}

function log_warn()
{
    if  [ ! -f ${LOG_FILE} ] || [ -L ${LOG_FILE} ]; then
        return
    fi

    local func_name=${FUNCNAME[1]}
    if [ "$2" != "" ]; then
        func_name="$2"
    fi
    echo "[`date "+%Y-%m-%d %T"`:$$][WARN][dataturbo][${0##*/}][${func_name}]:" "$1" >> ${LOG_FILE}
}

function log_info_print()
{
    echo -e "$1"
    log_info "$1" "${FUNCNAME[1]}"
}

function log_error_print()
{
    echo -e -n "\033[31m[ERROR]\033[0m"; echo -e "$1"
    log_error "$1" "${FUNCNAME[1]}"
}

function log_warn_print()
{
    echo -e -n "\033[31m[WARN]\033[0m"; echo -e "$1"
    log_warn "$1" "${FUNCNAME[1]}"
}

function set_cpu_limit()
{
    if [ ! -f "${DPC_USER_CONF}" ]; then
        echo "ERROR: ${DPC_USER_CONF} is not exsit, please reinstall."
        exit 1
    fi

    sed -i "s/<DpcCgroupLimitCPU min=\"1\" max=\"95\">[0-9]*<\/DpcCgroupLimitCPU>/<DpcCgroupLimitCPU min=\"1\" max=\"95\">$1<\/DpcCgroupLimitCPU>/g" "${DPC_USER_CONF}" >/dev/null 2>&1
}

function set_mem_limit()
{
    if [ ! -f "${DPC_USER_CONF}" ]; then
        echo "ERROR: ${DPC_USER_CONF} is not exsit, please reinstall."
        exit 1
    fi

    sed -i "s/<DpcCgroupLimitMemory min=\"4\" max=\"20\">[0-9]*<\/DpcCgroupLimitMemory>/<DpcCgroupLimitMemory min=\"4\" max=\"20\">$1<\/DpcCgroupLimitMemory>/g" "${DPC_USER_CONF}" >/dev/null 2>&1
}

function set_cgroup_limit_conf()
{
    local str=${CGROUP_LIMIT[$1-1]}
    local memory=$(echo "${str}" | awk -F "," '{print $1}')
    local cpu=$(echo "${str}" | awk -F "," '{print $2}')

    set_cpu_limit ${cpu}
    set_mem_limit ${memory}
    log_info "set cpu[${cpu}%] and memory[${memory}GB] limit OK."
}

function select_mem_level()
{
    local user_input=""

    while [ 1 ] 
    do
        echo "<0>--Select Default Level. The recommended level will be used."
        echo "<1>--Select Low Level. It is estimated that at most 4 GB memory is consumed."
        echo "<2>--Select Medium Level. It is estimated that at most 6 GB memory is consumed."
        echo "<3>--Select High Level. It is estimated that at most 12 GB memory is consumed."
        echo -n "please input your selection:"
        read user_input
        if [ "${user_input}" == "0" ] || [ "${user_input}" == "1" ] || [ "${user_input}" == "2" ] || [ "${user_input}" == "3" ]; then
            return ${user_input}
        else
            log_warn_print "you select is incorrect[${user_input}]"
            continue
        fi
    done
}

function set_mem_level()
{
    if [ ! -f "${SHIM_CONF_FILE}" ]; then
        echo "ERROR: ${SHIM_CONF_FILE} is not exsit, please reinstall."
        exit 1
    fi

    sed -i "s/<DpcLevelVal min=\"0\" max=\"3\">[0-9]<\/DpcLevelVal>/<DpcLevelVal min=\"0\" max=\"3\">$1<\/DpcLevelVal>/g" "${SHIM_CONF_FILE}" >/dev/null 2>&1
}

#高档位：12G及以上
#中档位：6G及以上
#低档位：小于6G（安装的时候会限制内存不低于2G，无需重复判断）
function choose_level_auto()
{
    if [ ${FREE_MEM} -ge 12 ]; then
        return 3
    elif [ ${FREE_MEM} -ge 6 ]; then
        return 2
    else
        return 1
    fi
}

function install_rpm()
{
    local choose_level
    rpm -qa |grep "dataturbo*" >/dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo "ERROR: dataturbo package already installed."
        exit 1
    fi

    #安装rpm包
    rpm -ivh --nodeps ${CUR_DIR}/packages/oceanstor_dataturbo*.rpm
    if [ $? -ne 0 ]; then
        echo "ERROR: install dataturbo rpm fail."
        return 1
    fi

    local cur_rpm_name=$(rpm -qa dataturbo 2>/dev/null)
    local cur_rpm_version=${cur_rpm_name#*-}
    cur_rpm_version=${cur_rpm_version%%-*}
    
    FREE_MEM=$(cat /proc/meminfo | awk '/MemAvailable/{print $2}')
    FREE_MEM=$(expr ${FREE_MEM} / 1024 / 1024)
    choose_level_auto
    local default_level=$?
    # 设置默认值
    set_mem_level ${default_level}
    set_cgroup_limit_conf ${default_level}
    log_info_print "The DataTurbo client supports three performance levels: high, medium, and low. A higher level consumes more memory and CPU, you can use cgroup \n\
command to limit the CPU usage of the DataTurbo process. The current remaining memory of the system is ${FREE_MEM} GB. You are advised to select \n\
level ${default_level}(recommended) or lower. If the level selection process stops abnormally, the recommended level will be used."
    
    select_mem_level
    choose_level=$?
    while [ ${choose_level} -gt ${default_level} ]
    do
        log_warn_print "you select is incorrect[${choose_level}], please select level ${default_level} or lower."
        select_mem_level
        choose_level=$?
    done
    log_info_print "your selection is [${choose_level}]"
    if [ ${choose_level} -eq 0 ]; then
        choose_level=${default_level}
    fi
    set_mem_level ${choose_level}
    set_cgroup_limit_conf ${choose_level}

    cp -af ${CUR_DIR}/packages/oceanstor_dataturbo*.rpm ${INSTALL_DIR}/packages/
    if [ $? -ne 0 ]; then
        log_warn_print "dataturbo package backup fail."
        return 1
    fi
    log_info_print "install dataturbo succeed."
    log_info "current package version = ${cur_package_version}"
    return 0
}

function  check_srv_name()
{
    local srv_name=$1
    input_srv_array=(${srv_name//,/ }) # 通过冒号分隔成数组
    for input_srv in "${input_srv_array[@]}";
    do
        echo "${srv_array[@]}" |grep -wq "$input_srv"
        if [ $? == 1 ];then
            echo "ERROR: The input srv name is not right, srv name must in:" "${srv_array[@]}"
            return 1
        fi
    done
    return 0
}

function start_srv_by_name()
{
    local result=0
    local srv_name=$1
    systemctl daemon-reload
    input_srv_array=(${srv_name//,/ }) # 通过冒号分隔成数组
    for srv in "${input_srv_array[@]}";
    do
        systemctl start ${srv}.service
        ret=$?
        if [ ${ret} == "0" ]; then
            log_info_print "Success to start dataturbo service!"
        else
            result=1
            log_error_print "Failed to start ${srv} service."
        fi
    done

    return $result
}

function start_all_srv() {
    local result=0
    systemctl daemon-reload
    for srv in "${srv_array[@]}";
    do
        systemctl start ${srv}.service
        ret=$?
        if [ ${ret} == "0" ]; then
            log_info_print "Success to start ${srv} service!"
        else
            log_error_print "Failed to start ${srv} service."
            result=1
            return $result
        fi
    done

    return $result
}


param=$*
echo "$param" | grep -q -E '^[ 0-9a-zA-Z,_@-]*$'
if [ $? -ne 0 ]; then
    echo "ERROR: Parameter is invaild."
    usage
    exit 1
fi

PARA="$1"
if [ -z "${PARA}" ]; then
    install_rpm
    exit $?
fi

while getopts hs:S options 2>/dev/null
do
    case $options in
        h)  #显示帮助信息
            usage
            exit 0
        ;;
        s)  #install and start 对应服务
            if [ "$#" != "2" ];then
                echo "ERROR: parameter error, Only one parameter is required after [-s], multiple srv_name are separated by commas (,)."
                exit 1
            fi

            check_srv_name "$2"
            if [ "$?" != "0" ] ; then
                exit 1
            fi

            install_rpm
            if [ "$?" -ne "0" ]; then
                echo "ERROR: install dataturbo rpm fail."
                exit 1
            fi

            start_srv_by_name "$2"
            if [ "$?" != "0" ] ; then
                echo "ERROR: start service failed, please manually start the service."
                exit 1
            fi
            exit 0
        ;;
       S)
            install_rpm
            if [ "$?" -ne "0" ]; then
                echo "ERROR: install dataturbo rpm fail."
                exit 1
            fi

            start_all_srv
            if [ "$?" -ne "0" ]; then
                echo "ERROR: Failed to start all service."
                exit 1
            fi
            exit 0
        ;;
        *)
            usage
            exit 1
            ;;
    esac
done
usage
exit 1
