#!/bin/bash

scriptName=$(basename $0)
logFile="/var/log/dsware/${scriptName/.sh/.log}"
if [ ! -e ${logFile} ]
then
    mkdir -p /var/log/dsware/
    touch ${logFile}
    chmod 640 ${logFile}
fi

FAILLIST=''
ERR99=99   #参数个数不符合要求
ERR100=100 #安装包不存在
ERR101=101 #存在多个安装包
ERR102=102 #当前版本小于目标版本
ERR103=103 #安装包类型[V3/V5]不一致
ERR104=104 #当前节点不是arm服务器
ERR105=105 #zip文件解压失败
ERR106=106 #安装失败
ERR107=107 #安装超时

logger()
{
    local info=$*
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S") process:${PPID},lineno:${BASH_LINENO}] ${info}" >> ${logFile}
}

# 根据欧拉版本判断待安装驱动包
  ## HCS811配套管理存储欧拉版本
  #  4.18.0-147.5.2.4.h700_234.x86_64
  #  4.19.90-vhulk2111.1.0.h893.eulerosv2r10.aarch64
  ## HCS811配套业务存储812欧拉版本
  #  实际转测版本
  #  4.18.0-147.5.2.2.h657.eulerosv2r10.x86_64
  #  4.19.90-vhulk2108.6.0.h832.eulerosv2r10.aarch64
  # 基础设施对齐版本
  #  4.18.0-147.5.2.2.h657.eulerosv2r10.x86_64
  #  4.19.90-vhulk2108.6.0.h832.eulerosv2r10.aarch64
get_driver_version_info()
{
  # HCS811配套业务存储810/811欧拉版本
  local v2r9h451=4.18.0-147.5.1.6.h451.eulerosv2r9.x86_64
  local v2r9h462=4.19.90-vhulk2103.1.0.h462.eulerosv2r9.aarch64
  local v2r9h314=4.18.0-147.5.1.2.h314.eulerosv2r9.x86_64
  local v2r9h352=4.19.90-vhulk2011.1.0.h352.eulerosv2r9.aarch64
  local euler_version
  euler_version=$(uname -r)
  if [ x"$v2r9h451" == x"$euler_version" ] || [ x"$v2r9h314" == x"$euler_version" ];then # 配套存储811/810 x86
    DRIVER_PKG=HUAWEI_SSD_Driver_6.0.4.2.zip
    TOOL_PKG=HUAWEI_SSD_Tool_6.0.4.2.zip
    DRIVER_RPM=HUAWEI_SSD_Driver_6.0.4.2/linux/x86_64/euleros2.9c10spc100/kmod-hiodriver-6.0.4.2-4.18.0_147.5.1.2.h314.eulerosv2r9.euleros.x86_64.rpm
    TOOL_RPM="HUAWEI_SSD_Tool_6.0.4.2/linux/x86_64/hioadm-*.rpm"
    FIRMWARE_RPM=''
  elif [ x"$v2r9h462" == x"$euler_version" ] || [ x"$v2r9h352" == x"$euler_version" ];then # 配套存储811/810 arm
    DRIVER_PKG=HUAWEI_SSD_Driver_6.0.4.2.zip
    TOOL_PKG=HUAWEI_SSD_Tool_6.0.4.2.zip
    DRIVER_RPM=HUAWEI_SSD_Driver_6.0.4.2/linux/aarch64/arm4.19.90-vhulk2009/kmod-hiodriver-6.0.4.2-4.19.90_vhulk2009.2.0.h269.eulerosv2r9.euleros.aarch64.rpm
    TOOL_RPM="HUAWEI_SSD_Tool_6.0.4.2/linux/aarch64/hioadm-*.rpm"
    FIRMWARE_RPM=''
  else
    logger "The open-source inbox driver is installed in the current version：$euler_version"
    exit 0
  fi
}

get_driver_version_info

check_rpm_package()
{
    local pkg_name=$1
    rpm -qa | awk -F. '{print substr($1,0,length($1)-2)}' | grep -qE "$pkg_name"
    return $?
}

install_rpm_package()
{
    local pkg_name=$1
    local pkg_path=$2
    if [ ! -f "${pkg_path}" ]
    then
        logger "Not found $pkg_path package"
        return 1
    fi

    logger "Start to install $pkg_name"
    rpm -Uvh $pkg_path
    local result=$?
    logger "End to install ${pkg_name[$result]}"
    if [ $result -ne 0 ]
    then
        rpm -Uvh --replacepkgs $pkg_path
        local result=$?
        logger "End to install by replacepkgs: ${pkg_name[$result]}"
    fi
    return $result
}

install_es3000_drivers()
{
    local package_name=$DRIVER_PKG
    local install_package=$DRIVER_RPM
    logger "Star to install ES3000 drivers"
    check_package_num $package_name || return $?

    check_rpm_package "kmod-hiodriver"
    if [ $? -ne 0 ]
    then
        touch /tmp/es3000_install_flag_file
        logger "Set install flag:\n$(ls -l /tmp/es3000_install_flag_file)"
    fi
    install_es3000_nvme_driver $package_name $install_package 1>>${logFile} 2>&1
    result=$?
    if [ $result -ne 0 ]
    then
        FAILLIST=${FAILLIST}",kmod-hiodriver"
        return $result
    fi
    return 0
}

check_package_num()
{
    local pkg_name=$1
    local pkg_num=0
    pkg_num=$(ls -1 | grep -wE "$pkg_name" | wc -l)
    if [ $pkg_num -eq 0 ]
    then
        logger "No pakage[$pkg_name] package exist. Detail:\n$(ls -1 | grep "$pkg_name")"
        return $ERR100
    elif [ $pkg_num -gt 1 ]
    then
        logger "Multiple package[$pkg_name] exist. Detail:\n$(ls -1 | grep "$pkg_name")"
        return $ERR101
    fi
    return 0
}

check_es3000_fw()
{
    local es3000_v3_fw=$(ls -1 | grep ES3000_V3_Firmware_*.zip)
    local es3000_v5_fw=$(ls -1 | grep ES3000_V5_Firmware_*.zip)
    if [ -f "$es3000_v3_fw" -a -f "$es3000_v5_fw" ]
    then
        logger "Find V3 and V5 package"
        check_package_combine "V5"
        check_package_combine "V3"

    elif [ -f "$es3000_v3_fw" -o -f "$es3000_v5_fw" ]
    then
        logger "Find V3 or V5 package"
        es3000_type=$(ls -1 | sed -n 's/ES3000_\(V[3,5]\)_Firmware_.*.zip/\1/p')
        check_package_combine "$es3000_type"
    else
        logger "Not found ES3000_V*_Firmware_*.zip package"
        return $ERR100
    fi
    return 0
}

check_package_combine()
{
    local type=$1
    local es3000_driver=$(ls -1 | sed -n 's/ES3000_\(V[3,5]\).*_Driver_\([0-9.]*\).zip/\1:\2/p')
    local driver_type=$(echo $es3000_driver | awk -F: '{print $1}')
    local driver_version=$(echo $es3000_driver | awk -F: '{print $2}')
    logger "Checking Driver type: $driver_type, Driver version: $driver_version"
    local es3000_tool=$(ls -1 | sed -n 's/ES3000_\(V[3,5]\)_Tool_\([0-9.]*\).zip/\1:\2/p')
    local tool_type=$(echo $es3000_tool | awk -F: '{print $1}')
    local tool_version=$(echo $es3000_tool | awk -F: '{print $2}')
    logger "Checking Tool type: $tool_type, Tool version: $tool_version"
    if [ x"$type" == x"V3" ]
    then
        if [ x"$driver_type" == x"V5" ]
        then
            #V5 5.0.3.9及之后的版本为收编版本，兼容V3
            vergion_compare "ES3000_*_NVMe_Driver_*.zip" "$driver_version" "5.0.3.9" || return 1
            if [ x"$tool_type" != x"V5" ]
            then
                logger "If the ES3000_*_NVMe_Driver_*.zip is V5, the ES3000_*_Tool_*.zip needs to be V5."
                return $ERR103
            fi
        elif [ x"$tool_type" == x"V5" ]
        then
            #V5 5.0.3.9及之后的版本为收编版本，兼容V3
            vergion_compare "ES3000_*_Tool_*.zip" "$tool_version" "5.0.3.9" || return 1
        fi
    elif [ x"$type" == x"V5" ]
    then
        if [ x"$driver_type" != x"V5" -o x"$tool_type" != x"V5" ]
        then
            logger "If the ES3000_V*_Firmware_*.zip is V5, the ES3000_*_NVMe_Driver_*.zip and ES3000_*_Tool_*.zip also needs to be V5."
            return $ERR103
        fi
    fi
    return 0
}

vergion_compare()
{
    local component=$1
    local current=$2
    local target=$3
    version_cmp=$(awk -v num1=$current -v num2=$target_version 'BEGIN{print(num1>=num2)?"0":"1"}')
    if [ $version_cmp -ne 0 ]
    then
        logger "The current version[$current] of $component is older than target version[$target]"
        return $ERR102
    fi
    return 0
}

install_es3000_nvme_driver()
{
    local package_name=$1
    local install_package=$2
    check_rpm_package "kmod-hiodriver"
    if [ $? -eq 0 ]
    then
        logger "The kmod-hiodriver package has been installed"
        return 0
    fi

    local pkg_es3000_driver=$(ls -1 | grep $package_name)
    logger "Installing driver[$pkg_es3000_driver]"

    logger "Start to install kmod-hiodriver"
    echo -e 'A' | unzip $pkg_es3000_driver 1>>${logFile} 2>&1
    logger "unzip $pkg_es3000_driver result:$?"
    path_es3000_driver=$(ls $install_package)
    install_rpm_package "kmod-hiodriver" "$path_es3000_driver" 1>>${logFile} 2>&1
    local result=$?
    logger "End to install kmod-hiodriver[$result]"
    return $result
}

install_es3000_tool()
{
    local package_name=$TOOL_PKG
    local install_package=$TOOL_RPM
    check_rpm_package "hioadm"
    if [ $? -eq 0 ]
    then
        logger "The hioadm package has been installed"
        return 0
    fi

    local pkg_es3000_tool=$(ls -1 | grep -wE $package_name)
    if [ ! -f "$pkg_es3000_tool" ]
    then
        logger "The ${package_name} package is not exist"
        return 0
    fi

    logger "Start to install hioadm tool"
    echo -e 'A' | unzip $pkg_es3000_tool 1>>${logFile} 2>&1
    logger "unzip $pkg_es3000_tool result:$?"
    path_es3000_tool=$(ls $install_package)
    install_rpm_package "hioadm" "$path_es3000_tool" 1>>${logFile} 2>&1
    local result=$?
    logger "End to install  hioadm tool[$result]"
    return $result
}

install_es3000_firmware()
{
    local package_name=$DRIVER_PKG
    local install_package=$FIRMWARE_RPM
    test -e /tmp/es3000_install_flag_file
    if [ $? -ne 0 ]
    then
        logger "Not found es3000 install flag, ES3000 firmware has beed installed. Skip.."
    fi

    local nvme_list=$(hioadm info | grep  "^|----" | grep nvme | awk '{print $2}')
    if [ -z "$nvme_list" ]
    then
        logger "Not found nvme device $nvme_list"
        logger "hioadm info detail:\n$(hioadm info)"
        return 0
    fi

    logger "Start to unzip ${package_name}"
    for fw_zip in $(ls -1 | grep -wE ${package_name})
    do
        echo -e 'A' | unzip $fw_zip>>${logFile} 2>&1
        if [ $? -ne 0 ]
        then
            logger "Failed to unzip $fw_zip result:$result"
            return $ERR105
        fi
    done

    logger "Start to install ${package_name}"
    local all_result=0
    for nvme in $nvme_list
    do
        package_dir=${package_name%.zip}
        local fw_dir=$(ls -1 | grep -v '.zip' | grep ${package_dir})
        if [ -n "$fw_dir" ]
        then
            cd $fw_dir
            logger "Enter ${package_dir} directory[$?]"
        else
            logger "Not found ${package_dir} directory, Detail:\n$(ls -1 | grep -v '.zip' | grep ES3000_V)"
            continue
        fi
        local package_file=$(ls ${install_package})
        if [ -z "$package_file" ]
        then
            logger "Failed to get ${install_package} file. Detail:\n$(ls -1)"
            cd -
            continue
        fi
        local package_name=${package_file%.bin}
        local target_version=${package_name/ES3000V[35]_FW_/}
        logger "package_file: $package_file, package_name: $package_name, target_version: $target_version"
        curr_version=$(hioadm updatefw -d ${nvme} | grep "current" | awk '{print $2}')
        logger "curr_version: $curr_version"
        vergion_compare "${nvme}" "$curr_version" "$target_version"
        if [ $? -eq 0 ]
        then
            logger "The version[${curr_version}] of $nvme device is greater than or equal to than target vergion[${target_version}]"
            cd -
            continue
        fi
        echo -e "y|n"|hioadm updatefw -d ${nvme} -f ${package_file} -a 1
        result=$?
        logger "update ${nvme} result:$result"
        all_result=$(($all_result + $result))
        cd -
    done
    logger "End to install ES3000[$all_result]"
    return $all_result
}

main()
{
  local software=$1
  case $software in
  driver)
    install_es3000_drivers
    result=$?
    if [ $result -ne 0 ]
    then
        echo "fails:${FAILLIST/,/}"
    fi
    ;;
  tool)
    install_es3000_tool
    result=$?
    if [ $result -ne 0 ]
    then
        echo "fails:${FAILLIST/,/}"
    fi
    ;;
  firmware)
    install_es3000_firmware
    result=$?
    if [ $result -ne 0 ]
    then
        echo "fails:${FAILLIST/,/}"
    fi
    ;;
  esac
  return $result
}

main "$@"
exit $?