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

CUR_DIR="$( cd "$( dirname "$0"  )" && pwd )"
source $CUR_DIR/common.sh
INSTALL_DIR="/opt/oceanstor/dataturbo"
readonly SHIM_CONF_FILE="${INSTALL_DIR}/conf/shim_config.xml"
readonly LOG_FILE="/var/log/dataturbo/dataturbo_script/dataturbo.action.log"

DEFAULT_USER_NAME="dataturbo"
DEFAULT_GROUP_NAME="dataturbo"
CUSTOM_USER=${CUSTOM_USER=${DEFAULT_USER_NAME}}

# 服务校验array，后续新增服务，在此新增
readonly srv_array=(dataturbo)

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 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
        print_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 switch_user()
{
    echo "CUSTOM_USER=${CUSTOM_USER}"
    if [ ! ${CUSTOM_USER} ]; then
        print_error "usage: CUSTOM_USER=\"your custom user name\""
        return 1
    elif [ "${CUSTOM_USER}" != "${DEFAULT_USER_NAME}" ]; then
        # 检查传入的自定义用户是否存在
        id -u ${CUSTOM_USER} >/dev/null 2>&1
        if [ $? -ne 0 ]; then
           print_error "${CUSTOM_USER} is not exist! Please check it is already exist in this system before installing";
           return 1
        fi
    else # 用户未传入自定义用户名，使用默认用户
        echo "begin to create default user[${DEFAULT_USER_NAME}] and group[${DEFAULT_GROUP_NAME}] ......"
        group_name=${DEFAULT_GROUP_NAME}
        groupadd $group_name >/dev/null 2>&1

        user_name=${DEFAULT_USER_NAME}
        useradd -m -g $group_name -d /home/$user_name $user_name -s /sbin/nologin >/dev/null 2>&1
        if [ $? == 1 ]; then
            print_error "useradd faild, can't update system password file."
            return 1
        fi
        usermod -g $user_name $group_name >/dev/null 2>&1
        bash_file="/home/${user_name}/.bashrc"
        if [ ! -d /home/${user_name} ] || [ ! -f "${bash_file}" ] || [ -L "${bash_file}" ]; then 
            return 0
        fi

        # 第一次直接echo并设置标记，后续做替换
        if [ $(grep -c "#UMASK_SET" "${bash_file}") -eq 0 ]; then 
            echo "#UMASK_SET" >> "${bash_file}"
            echo "umask 027" >> "${bash_file}"
        else
            sed -i "s/umask[ ][ ]*[0-9]\{3\}/umask 027/g" "${bash_file}" >/dev/null 2>&1
        fi

        return 0
    fi
    return 0
}

function install_deb()
{
    local package_status=$(dpkg -l |grep dataturbo | awk '{print $1}' | cut -c 2)
    if [ "${package_status}" == "i" ]; then
        print_error "dataturbo package already installed."
        return 1
    fi

    #安装deb包
    dpkg -i ${CUR_DIR}/packages/oceanstor_dataturbo*.deb
    if [ $? -ne 0 ]; then
        print_error "install dataturbo deb fail."
        return 1
    fi

    return 0
}

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

    # install rpm
    if [ "$(uname -p)" == "aarch64" ]; then
        rpm -ivh --nodeps ${CUR_DIR}/packages/oceanstor_dataturbo*.aarch64.rpm
    else
        rpm -ivh --nodeps ${CUR_DIR}/packages/oceanstor_dataturbo*.x86_64.rpm
    fi
    
    if [ $? -ne 0 ]; then
        print_error "install dataturbo rpm fail."
        return 1
    fi

    return 0
}

function set_dataturbo_level()
{
    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."
    local choose_level
    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}
}

function install_dataturbo()
{
    install_check
    if [ $? -ne 0 ]; then
        return 1
    fi

    switch_user
    if [ $? -ne 0 ]; then
        return 1
    fi

    local package_tail=""
    local os_name=$(cat /etc/os-release |grep ^NAME | awk -F "=" '{print $2}' | sed 's/\"//g')
    if [ "${os_name}" == "Ubuntu" ]; then
        package_tail="deb"
        install_deb
    else
        package_tail="rpm"
        install_rpm
    fi
    if [ $? -ne 0 ]; then
        return 1
    fi

    set_dataturbo_level

    cp -af ${CUR_DIR}/packages/oceanstor_dataturbo*.${package_tail} ${INSTALL_DIR}/packages/
    if [ $? -ne 0 ]; then
        log_warn_print "Failed to backup dataturbo package."
    fi
    log_info_print "Install dataturbo successfully."

    dataturbo_pkg=$(ls ${CUR_DIR}/packages/ | grep dataturbo | grep ${package_tail})
    dataturbo_pkg_version=${dataturbo_pkg%%-*}
    dataturbo_pkg_version=${dataturbo_pkg_version##*_}
    release=${dataturbo_pkg#*-}
    release=${release%%.*}

    log_info "current package version = ${dataturbo_pkg_version}-${release}"
    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
            print_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} -eq 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} -eq 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
    print_error "Parameter is invaild."
    usage
    exit 1
fi

PARA="$1"
if [ -z "${PARA}" ]; then
    install_dataturbo
    if [ $? -ne 0 ]; then
        print_error "Failed to install the DataTurbo."
        exit 1
    fi
    exit 0
fi

while getopts hs:S options 2>/dev/null
do
    case $options in
        h)  #显示帮助信息
            usage
            exit 0
        ;;
        s)  #install and start 对应服务
            if [ "$#" != "2" ];then
                print_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_dataturbo
            if [ $? -ne 0 ]; then
                print_error "Failed to install the DataTurbo."
                exit 1
            fi

            start_srv_by_name "$2"
            if [ "$?" != "0" ] ; then
                print_error "Start service failed, please manually start the service."
                exit 1
            fi
            exit 0
        ;;
        S)
            install_dataturbo
            if [ $? -ne 0 ]; then
                print_error "Failed to install the DataTurbo."
                exit 1
            fi

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