#!/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}
}

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

check_raid_rpm_package()
{
    local pkg_name=$1
    rpm -qa | grep -qE "$pkg_name"
    return $?
}

unzip_pkg()
{
  local pkg_path=$1
  local pkg_name=$2
  pkg_full_name=$(ls "$pkg_path"/"$pkg_name")
  logger "Start to unzip $pkg_full_name"
  echo -e 'A' | unzip "$pkg_full_name" 1>>${logFile} 2>&1
  result=$?
  logger "unzip $pkg_full_name result:$result"
  if [ $result -ne 0 ]
  then
    FAILLIST=${FAILLIST}",unzip $pkg_full_name"
    return $ERR105
  fi
  return 0
}

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
}

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
}

install_hi1822_nic()
{
    logger "Start to install hi1822 nic drivers"
    check_package_num "IN500_solution_5.1.0.SPC602.zip" || return $?

    local cpu_arch=$(uname -p)
    if [ x"$cpu_arch" != x"aarch64" ]
    then
        logger "The current node is not the arm server."
        return $ERR104
    fi

    pkg_hi1822_nic=$(ls -1 | grep IN500_solution_5.1.0.SPC602.zip)
    echo -e 'A' | unzip $pkg_hi1822_nic 1>>${logFile} 2>&1
    logger "unzip $pkg_hi1822_nic result:$?"

    logger "Step1. install hinicadm"
    check_rpm_package "hinicadm"
    if [ $? -ne 0 ]
    then
        hinicadm_pkg_path=$(ls tools/linux_arm/nic/hinicadm-*.aarch64.rpm)
        install_rpm_package "hinicadm" "$hinicadm_pkg_path" 1>>${logFile} 2>&1
        result=$?
        if [ $result -ne 0 ]
        then
            FAILLIST=${FAILLIST}",hinicadm"
            return $result
        fi
    else
        logger "The hinicadm package has been installed"
    fi  

    logger "Step2. install hinic"
    check_rpm_package "hinic$"
    if [ $? -ne 0 ]
    then
        #如果找到老版本，建立标记文件，用于OFED、HI1822固件安装
        touch /tmp/hi1822_install_flag_file
        logger "Set install flag:\n$(ls -l /tmp/hi1822_install_flag_file)"

        uname -r | grep -q eulerosv2r9
        ret=$?
        if [ $ret -eq 0 ]; then
          hinic_pkg_path=$(ls driver/linux/nic/EULEROS_SERVER_V200R009*/hinic-*.aarch64.rpm)
        else
          hinic_pkg_path=$(ls driver/linux/nic/EULEROS_SERVER_V200R008C00SPC106B350/hinic-*.aarch64.rpm)
        fi
        install_rpm_package "hinic" "$hinic_pkg_path" 1>>${logFile} 2>&1
        result=$?
        if [ $result -ne 0 ]
        then
            FAILLIST=${FAILLIST}",hinic"
            return $result
        fi
    else
        logger "The hinic package has been installed"
    fi


    logger "Step3. install OFED"
    install_OFED_driver 1>>${logFile} 2>&1
    result=$?
    if [ $result -ne 0 ]
    then
        FAILLIST=${FAILLIST}",OFED"
        return $result
    fi

    logger "Step4. install hiroce"
    check_rpm_package "hiroce"
    if [ $? -ne 0 ]
    then
        uname -r | grep -q eulerosv2r9
        ret=$?
        if [ $ret -eq 0 ]; then
          hiroce_pkg=$(ls driver/linux/roce/EULEROS_SERVER_V200R009*/hiroce-*.aarch64.rpm | grep -v _PANGEA_)
        else
          hiroce_pkg=$(ls driver/linux/roce/EULEROS_SERVER_V200R008C00SPC106B350/hiroce-*.aarch64.rpm | grep -v _PANGEA_)
        fi
        install_rpm_package "hiroce" "$hiroce_pkg" 1>>${logFile} 2>&1
        result=$?
        if [ $result -ne 0 ]
        then
            FAILLIST=${FAILLIST}",OFED"
            return $result
        fi
    else
        logger "The hiroce package has been installed"
    fi

    logger "Step5. install hi1822 firmware"
    install_hi1822_firmware 1>>${logFile} 2>&1
    if [ $result -ne 0 ]
    then
        FAILLIST=${FAILLIST}",OFED"
        return $result
    fi
    return 0
}

install_OFED_driver()
{
    #有标记文件，新安装，无标记文件则已有老版本驱动
    test -e /tmp/hi1822_install_flag_file
    if [ $? -ne 0 ]
    then
        logger "Not found hi1822 install flag, OFED has beed installed. Skip.."
    fi

    uname -r | grep -q eulerosv2r9
    ret=$?
    if [ $ret -eq 0 ]; then
      local pkg_ofed=$(ls driver/linux/roce/EULEROS_SERVER_V200R009*/OFED-*-aarch64.tar.gz)
    else
      local pkg_ofed=$(ls driver/linux/roce/EULEROS_SERVER_V200R008C00SPC106B350/OFED-*-aarch64.tar.gz)
    fi
    if [ ! -f "${pkg_ofed}" ]
    then
        logger "Not found ${pkg_ofed} package"
        return 1
    fi
    
    lsmod | grep hiroce | awk '{print $1}' | grep '^hiroce$'
    if [ $? -eq 0 ]
    then
        logger "The OFED package has been installed"
        return 0
    fi
    
    logger "Start to install OFED"
    tar zxf $pkg_ofed
    cd OFED-*-aarch64
    echo y | sh ofed_install.sh
    local result=$?
    cd -
    logger "End to install OFED[$result]"
    return $result
}

install_hi1822_firmware()
{
    #有标记文件，新安装，无标记文件则已有老版本驱动
    test -e /tmp/hi1822_install_flag_file
    if [ $? -ne 0 ]
    then
        logger "Not found hi1822 install flag, HI1822 firmware has beed installed. Skip.."
    fi

    local path_hi1822_fw="firmware/update_bin/cfg_data_nic_prd_1h_4x25G"
    local pkg_hi1822_fw="Hi1822_nic_prd_1h_4x25G.bin"
    if [ ! -f "${path_hi1822_fw}/${pkg_hi1822_fw}" ]
    then
        logger "Not found ${path_hi1822_fw}/${pkg_hi1822_fw} package"
        return 1
    fi

    local hini_list=$(hinicadm info | sed -n 's/^|----\(.*\)(.*)/\1/p')
    if [ -z "$hini_list" ]
    then
        logger "Not found nvme device $hini_list"
        logger "hioadm info detail:\n$(hioadm info)"
        return 0
    fi
    
    logger "Start to install hi1822 firmware"
    cd $path_hi1822_fw
    local all_result=0
    for hini in $hini_list
    do
        hinicadm updatefw -i ${hini} -f ${pkg_hi1822_fw}
        result=$?
        logger "update ${hini} result:$result"
        all_result=$(($all_result + $result))
    done
    cd -
    logger "End to install hi1822 firmware[$all_result]"
    return $all_result
}

install_mlnx_nic_aarch64()
{
    logger "Start to install mlnx cx4 nic drivers"
    local pkg_name="OceanStor-Pacific_8.1.*_[D|d]*river[-|_]*RDMA_[aarch64|ARM]*.zip"


    logger "Step1. checking the pkg and cpu"
    check_package_num $pkg_name || return $?
    local cpu_arch=$(uname -p)
    if [ x"$cpu_arch" != x"aarch64" ]
    then
        logger "The current node is not the arm server."
        return $ERR104
    fi
    logger "Step2. decompress the installation package"
    if [ -d "OceanStor-Pacific_8.1.x_driver_RDMA_ARM" ]
    then
      rm -rf OceanStor-Pacific_8.1.x_driver_RDMA_ARM
    fi
    pkg_aarch64_nic=$(ls -1 | grep "OceanStor-Pacific_8.1.*_[D|d]*river[-|_]*RDMA_[aarch64|ARM]*.zip")
    mkdir OceanStor-Pacific_8.1.x_driver_RDMA_ARM
    chmod 750 OceanStor-Pacific_8.1.x_driver_RDMA_ARM
    mv "$pkg_aarch64_nic" OceanStor-Pacific_8.1.x_driver_RDMA_ARM/
    cd OceanStor-Pacific_8.1.x_driver_RDMA_ARM || return $?
    echo -e 'A' | unzip $pkg_aarch64_nic 1>>${logFile} 2>&1
    logger "unzip $pkg_aarch64_nic result:$?"

    logger "Step3. install hinicadm"
    cd action
    install_result=$(RDMA_HINIC_MODE_ENV="ROCE" sh appctl update)
    if [ "$install_result" != "success" ]; then
      logger "update arm nic driver failed"
      FAILLIST=${FAILLIST}",nic_aarch64"
      return $ERR106
    fi
    max_timeout=126
    local time=1
    for ((time=1; time<=$max_timeout; time++)); do
      progress_result=$(sh appctl get_progress)
      if [ "$progress_result" == "success" ]; then
        logger "update arm nic driver $pkg_aarch64_nic success"
        break
      fi
      if [ "$progress_result" == "failure" ]; then
        logger "update arm nic driver $pkg_aarch64_nic failed"
        FAILLIST=${FAILLIST}",nic_aarch64"
        return $ERR106
      fi
      if [[ "$progress_result" =~ "upgrading" ]]; then
        logger "nic arm driver $pkg_aarch64_nic is $progress_result"
      fi
      sleep 10
    done
    if [ $time -ge $max_timeout ]; then
        logger "update arm nic driver $pkg_aarch64_nic timeout $time"
        FAILLIST=${FAILLIST}",nic_aarch64"
        return $ERR107
    fi
    return 0
}

install_hg_3108_RAID_driver()
{
    logger "Start to install hg 3108 RAID driver"
    if ! ipmitool fru list 0 |grep 'Board Product'|grep -q 'H01_HG_2P';
    then
      logger "This is not a HG server"
      exit 0
    fi

    check_package_num "MR_LINUX_DRIVER_7.16-07.716.01.00-2.tgz" || return $?

    hg_3108_RAID_driver=$(ls MR_LINUX_DRIVER_7.16-07.716.01.00-2.tgz)
    echo -e 'A' | tar -zxf $hg_3108_RAID_driver -C rpm_install_temp 1>>${logFile} 2>&1
    logger "tar -zxf $hg_3108_RAID_driver result:$?"

    logger "Step1. install hg 3108 RAID driver"
    if ! check_raid_rpm_package "kmod-megaraid_sas-07.716.01.00_el8.1-2.x86_64";
    then
        RAID_driver_pkg_path=$(ls rpm_install_temp/rhel8_oel8_centos8/rpms-2/kmod-megaraid_sas-07.716.01.00_el8.1-2.x86_64.rpm)
        install_rpm_package "hg 3108 RAID driver" "$RAID_driver_pkg_path" 1>>${logFile} 2>&1
        result=$?
        if [ $result -ne 0 ]
        then
            FAILLIST=${FAILLIST}",hg 3108 RAID driver"
            return $result
        fi
    else
        logger "The hg 3108 RAID driver package has been installed"
    fi

    return 0
}

install_3908_RAID_driver()
{
    logger "Start to install 3908 RAID driver"
    check_package_num "OceanStor-Pacific_8.*_PANGEA-SmartPkg.zip" || return $?

    local temp_dir="OceanStor-Pacific_PANGEA-SmartPkg"
    pkg_3908_RAID_driver=$(ls OceanStor-Pacific_8.*_PANGEA-SmartPkg.zip)
    echo -e 'A' | unzip $pkg_3908_RAID_driver -d  $temp_dir 1>>${logFile} 2>&1
    logger "unzip $pkg_3908_RAID_driver result:$?"

    local cpu_arch=$(uname -p)
    logger "Step1. unzip 3908 RAID driver pkg"
    if [ "$cpu_arch" == "x86_64" ];then
        driver_name_prefix="PANGEA_V600R00*_RAID-Driver-Euler*-megaraid_sas-07.720.04.00.${cpu_arch}.zip"
    else
        driver_name_prefix="PANGEA_V600R00*_RAID-Driver-Euler*-megaraid_sas*.${cpu_arch}.zip"
    fi
    cd $temp_dir
    check_package_num $driver_name_prefix || return $?
    driver_pkg_name=$(ls | grep -wE $driver_name_prefix)
    echo -e 'A' | unzip -o $driver_pkg_name
    logger "unzip $driver_pkg_name result:$?"

    rpm_name_pattern="RAID-Driver-Euler*-megaraid_sas-*.${cpu_arch}.rpm"
    rpm_name=$(ls | grep -wE $rpm_name_pattern)
    logger "Step2. install 3908 RAID driver"
    rpm_name_prefix=${rpm_name: 0:-4}
    if ! check_raid_rpm_package $rpm_name_prefix;
    then
        install_rpm_package $rpm_name $rpm_name 1>>${logFile} 2>&1
        result=$?
        if [ $result -ne 0 ]
        then
            FAILLIST=${FAILLIST}",3908 RAID driver"
            return $result
        fi
    else
        logger "The 3908 RAID driver package has been installed"
    fi
    return 0
}


install_mlnx_nic_x86()
{
    local pkg_name
    pkg_name="OceanStor-Pacific_8.1.*_Driver-RDMA_x86-64.zip"
    logger "Step1. checking the pkg"
    check_package_num $pkg_name || return $?

    logger "Step2. decompress the installation package"
    if [ -d "OceanStor-Pacific_8.1.x_driver_RDMA_X86" ]
    then
      rm -rf OceanStor-Pacific_8.1.x_driver_RDMA_X86
    fi
    mkdir OceanStor-Pacific_8.1.x_driver_RDMA_X86
    chmod 750 OceanStor-Pacific_8.1.x_driver_RDMA_X86
    mv OceanStor-Pacific_8.1.*_Driver-RDMA_x86-64.zip OceanStor-Pacific_8.1.x_driver_RDMA_X86/
    cd OceanStor-Pacific_8.1.x_driver_RDMA_X86 || return $?
    local file_path
    file_path=$(pwd)
    unzip_pkg $file_path $pkg_name || return $?
    logger "Step3. install hinicadm"
    cd "$file_path/action" || return $?
    install_result=$(sh appctl update)
    if [ "$install_result" != "success" ]; then
      logger "update x86_64 nic driver failed"
      FAILLIST=${FAILLIST}",nic_x86_64"
      return $ERR106
    fi
    max_timeout=126
    local time=1
    for ((time=1; time<=$max_timeout; time++)); do
      progress_result=$(sh appctl get_progress)
      if [ "$progress_result" == "success" ]; then
        logger "update x86_64 nic driver $pkg_name success"
        break
      fi
      if [ "$progress_result" == "failure" ]; then
        logger "update x86_64 nic driver $pkg_name failed"
        FAILLIST=${FAILLIST}",nic_x86_64"
        return $ERR106
      fi
      if [[ "$progress_result" =~ "upgrading" ]]; then
        logger "nic x86_64 driver $pkg_name is $progress_result"
      fi
      sleep 10
    done
    if [ "$time" -ge $max_timeout ]; then
        logger "update x86_64 nic driver $pkg_name timeout $time"
        FAILLIST=${FAILLIST}",nic_x86_64"
        return $ERR107
    fi
    return 0
}

install_3152_RAID_driver()
{
    logger "Start to install 3152 RAID driver"
    check_package_num "OceanStor-Pacific_8.*_PANGEA-SmartPkg.zip" || return $?

    local temp_dir="OceanStor-Pacific_PANGEA-SmartPkg"
    local pkg_3152_RAID_driver=$(ls OceanStor-Pacific_8.*_PANGEA-SmartPkg.zip)
    echo -e 'A' | unzip $pkg_3152_RAID_driver -d  $temp_dir 1>>${logFile} 2>&1
    logger "unzip $pkg_3152_RAID_driver result:$?"

    local cpu_arch=$(uname -p)
    logger "Step1. unzip 3152 RAID driver pkg"
    local driver_name_prefix="PANGEA_V600R005C20_RAID-Driver-Euler*-smartpqi-*-${cpu_arch}.zip"
    cd $temp_dir || return 1
    check_package_num $driver_name_prefix || return $?
    local driver_pkg_name=$(ls | grep -wE $driver_name_prefix)
    echo -e 'A' | unzip -o $driver_pkg_name
    logger "unzip $driver_pkg_name result:$?"
    local rpm_name_pattern="smartpqi-*.${cpu_arch}.rpm"
    local rpm_name=$(ls | grep -wE $rpm_name_pattern)
    logger "Step2. install 3152 RAID driver"
    local rpm_name_prefix=${rpm_name: 0:-4}
    if ! check_raid_rpm_package $rpm_name_prefix;
    then
        install_rpm_package $rpm_name $rpm_name 1>>${logFile} 2>&1
        result=$?
        if [ $result -ne 0 ]
        then
            FAILLIST=${FAILLIST}",3152 RAID driver"
            return $result
        fi
    else
        logger "The 3152 RAID driver package has been installed"
    fi
    cd - || return 1
    return 0
}

install_hi1822_v120_nic()
{
    logger "Start to install 1822 V120 nic drivers"
    local pkg_name="OceanStor-Pacific_8.*_PANGEA-SmartPkg.zip"

    local temp_dir="OceanStor-Pacific_PANGEA-SmartPkg"
    local pkg_1822_V120_driver=$(ls OceanStor-Pacific_8.*_PANGEA-SmartPkg.zip)
    echo -e 'A' | unzip "${pkg_1822_V120_driver}" -d  $temp_dir 1>>${logFile} 2>&1
    logger "unzip "${pkg_1822_V120_driver}" result:$?"

    local cpu_arch=$(uname -p)
    local os_type=$(uname -r | grep -o "v2r[0-9]*")
    logger "Step1. unzip 3152 RAID driver pkg"
    local driver_name_prefix="PANGEA_V600R007C*_HINIC3_UNION-${cpu_arch}-${os_type}.zip"
    cd $temp_dir || return 1
    check_package_num $driver_name_prefix || return $?
    local driver_pkg_name=$(ls | grep -wE $driver_name_prefix)
    echo -e 'A' | unzip -o "${driver_pkg_name}"
    logger "unzip $driver_pkg_name result:$?"

    logger "Step3. install 1822 V120 nic driver."
    install_result=$(sh appctl update)
    if [ "$install_result" != "success" ]; then
      logger "update arm nic driver failed"
      FAILLIST=${FAILLIST}",nic_aarch64"
      return $ERR106
    fi
    max_timeout=246
    local time=1
    for ((time=1; time<=$max_timeout; time++)); do
      progress_result=$(sh appctl get_progress)
      if [ "$progress_result" == "success" ]; then
        logger "update arm nic driver $pkg_aarch64_nic success"
        break
      fi
      if [ "$progress_result" == "failure" ]; then
        logger "update arm nic driver $pkg_aarch64_nic failed"
        FAILLIST=${FAILLIST}",nic_aarch64"
        return $ERR106
      fi
      if [[ "$progress_result" =~ "upgrading" ]]; then
        logger "nic arm driver $pkg_aarch64_nic is $progress_result"
      fi
      sleep 10
    done
    if [ $time -ge $max_timeout ]; then
        logger "update arm nic driver $pkg_aarch64_nic timeout $time"
        FAILLIST=${FAILLIST}",nic_aarch64"
        return $ERR107
    fi
    return 0
}

main()
{
    if [ $# -ne 1 ]
    then
        logger "parameter error, pls select one operation."
        return $ERR99
    fi

    local operation=$1
    case "$operation" in
        1822_V120)
            install_hi1822_v120_nic
            result=$?
            if [ $result -ne 0 ]
            then
                echo "fails:${FAILLIST/,/}"
            fi
            ;;
        hi1822)
            install_hi1822_nic
            result=$?
            if [ $result -ne 0 ]
            then
                echo "fails:${FAILLIST/,/}"
            fi
            ;;
        mlnx_aarch64)
            install_mlnx_nic_aarch64
            result=$?
            if [ $result -ne 0 ]
            then
                echo "fails:${FAILLIST/,/}"
            fi
            ;;
        hg_3108_RAID_driver)
            install_hg_3108_RAID_driver
            result=$?
            if [ $result -ne 0 ]
            then
                echo "fails:${FAILLIST/,/}"
            fi
            ;;
        mlnx_x86)
            install_mlnx_nic_x86
            result=$?
            if [ $result -ne 0 ]
            then
                echo "fails:${FAILLIST/,/}"
            fi
            ;;
        3908_RAID_driver)
          install_3908_RAID_driver
          result=$?
          if [ $result -ne 0 ]
          then
            echo "fails:${FAILLIST/,/}"
          fi
          ;;
        3152_RAID_driver)
          install_3152_RAID_driver
          result=$?
          if [ $result -ne 0 ]
          then
            echo "fails:${FAILLIST/,/}"
          fi
          ;;
        *)
            logger "Operation error."
            result=-1
            ;;
    esac
    return $result
}

main "$@"
exit $?