#!/bin/bash

installInfo="/etc/ascend_install.info"
ASCEND_SECLOG="/var/log/ascend_seclog"
logFile="${ASCEND_SECLOG}/ascend_install.log"
SHELL_DIR=$(cd "$(dirname "$0")" || exit; pwd)

OPERATION_LOGDIR="${ASCEND_SECLOG}"
OPERATION_LOGPATH="${OPERATION_LOGDIR}/operation.log"
LOG_OPERATION_INSTALL="Install"
LOG_OPERATION_UPGRADE="Upgrade"
LOG_OPERATION_UNINSTALL="Uninstall"
LOG_LEVEL_SUGGESTION="SUGGESTION"
LOG_LEVEL_MINOR="MINOR"
LOG_LEVEL_MAJOR="MAJOR"
LOG_LEVEL_UNKNOWN="UNKNOWN"
LOG_RESULT_SUCCESS="success"
LOG_RESULT_FAILED="failed"

export feature_nvcnt_check=n
export reset_passwd=n
export feature_ver_compatible_check=n
export feature_running_on_device_check=n

export global_pci_num

get_feature_config() {
    local config

    config=$(cat "$sourcedir"/script/feature.conf | grep FEATURE_NVCNT_CHECK)
    log "[INFO]FEATURE_NVCNT_CHECK is : $config"
    if [ "$config"x = "FEATURE_NVCNT_CHECK=y"x ];then
        feature_nvcnt_check=y
        log "[INFO]set feature_nvcnt_check=${feature_nvcnt_check}"
    fi

    config=$(cat "$sourcedir"/script/feature.conf | grep FEATURE_PASSWD_RESET)
    log "[INFO]FEATURE_PASSWD_RESET is : $config"
    if [ "$config"x = "FEATURE_PASSWD_RESET=y"x ];then
        reset_passwd=y
        log "[INFO]reset_passwd=${reset_passwd}"
    fi

    config=$(cat "$sourcedir"/script/feature.conf | grep FEATURE_VER_COMPATIBLE_CHECK)
    log "[INFO]FEATURE_VER_COMPATIBLE_CHECK is : $config"
    if [ "$config"x = "FEATURE_VER_COMPATIBLE_CHECK=y"x ];then
        feature_ver_compatible_check=y
        log "[INFO]feature_ver_compatible_check=${feature_ver_compatible_check}"
    fi

    config=$(cat "$sourcedir"/script/feature.conf | grep FEATURE_RUNNING_ON_DEVICE)
    log "[INFO]FEATURE_RUNNING_ON_DEVICE is : $config"
    if [ "$config"x = "FEATURE_RUNNING_ON_DEVICE=y"x ];then
        feature_running_on_device_check=y
        log "[INFO]feature_running_on_device_check=${feature_running_on_device_check}"
    fi

    return 0
}

log() {
    cur_date=`date +"%Y-%m-%d %H:%M:%S"`
    echo "[Firmware] [$cur_date] $1" >> $logFile
}
fwEcho() {
    cur_date=`date +"%Y-%m-%d %H:%M:%S"`
    echo "[Firmware] [$cur_date] $1"
}
fwColorEcho() {
    cur_date=`date +"%Y-%m-%d %H:%M:%S"`
    echo -e "[Firmware] [$cur_date] $1"
}

exitLog() {
    cur_date=`date +"%Y-%m-%d %H:%M:%S"`
    fwEcho "[INFO]End time: ${cur_date}"
    fwEcho "[INFO]End time: ${cur_date}" >> $logFile
    exit $1
}

install_info_key_array=("Driver_Install_Type" "UserName" "UserGroup" "Driver_Install_Path_Param" "Firmware_Install_Path_Param" "Firmware_Install_Type")
getInstallParam() {
    local _key="$1"
    local _file="$2"
    local _param

    if [ ! -f "${_file}" ];then
        exit 1
    fi

    for key_param in "${install_info_key_array[@]}"; do
        if [ ${key_param} == ${_key} ]; then
            _param=`grep -r "${_key}=" "${_file}" | cut -d"=" -f2-`
            break;
        fi
    done
    echo "${_param}"
}

check_Device() {
    . $Firmware_Install_Path_Param/firmware/script/feature.conf
    version_control=`cat $Firmware_Install_Path_Param/firmware/script/feature.conf | grep FEATURE_FIRMWIRE_INTERCEPT`
    temp=${version_control#*=}
    if [ "$temp" = "y" ]; then
        return 1;
    else
        return 0;
    fi
}

get_board_feature() {
    local board_config

    . $Firmware_Install_Path_Param/firmware/script/feature.conf
    board_config=`cat $Firmware_Install_Path_Param/firmware/script/feature.conf | grep FEATURE_BOARDID`

    temp=${board_config#*=}
    board_id=(${temp//,/ })
}

logOperation() {
    local operation="$1"
    local start_time="$2"
    local runfilename="$3"
    local result="$4"
    local install_type="$5"
    local cmdlist="$6"
    local level

    if [ "${operation}" = "${LOG_OPERATION_INSTALL}" ]; then
        level="${LOG_LEVEL_SUGGESTION}"
    elif [ "${operation}" = "${LOG_OPERATION_UPGRADE}" ]; then
        level="${LOG_LEVEL_MINOR}"
    elif [ "${operation}" = "${LOG_OPERATION_UNINSTALL}" ]; then
        level="${LOG_LEVEL_MAJOR}"
    else
        level="${LOG_LEVEL_UNKNOWN}"
    fi

    if [ ! -d "${OPERATION_LOGDIR}" ]; then
        mkdir -p ${OPERATION_LOGDIR}
        chmod 750 ${OPERATION_LOGDIR}
    fi

    if [ ! -f "${OPERATION_LOGPATH}" ]; then
        touch ${OPERATION_LOGPATH}
        chmod 640 ${OPERATION_LOGPATH}
    fi

    if [ $upgrade = y ] || [ $uninstall = y ]; then
        echo "${operation} ${level} root ${start_time} 127.0.0.1 ${runfilename} ${result}"\
            "cmdlist=${cmdlist}." >> ${OPERATION_LOGPATH}
    else
        echo "${operation} ${level} root ${start_time} 127.0.0.1 ${runfilename} ${result}"\
            "install_type=${install_type}; cmdlist=${cmdlist}." >> ${OPERATION_LOGPATH}
    fi
}

checkDriverProduct() {
    local bdfs=($(lspci -nn | grep -o '19e5:d[0-9]0[0-9]\|20c6:d[0-9]0[0-9]\|20e9:d[0-9]0[0-9]'))
    first_bdf=$(echo "$device_bdf" | cut -d'|' -f1)
    log "[INFO] Driver  expected bdfs (${first_bdf//0x/}), device actual bdfs is (${bdfs[*]})"
    if [ -n "$device_bdf" ] && [ ${#bdfs[@]} -ne 0 ] && [[ ! ${bdfs[*]} =~ ${device_bdf//0x/} ]]; then
        # It is a 910|910B|910_93 device,
        # and does not match the device_bdf configured in the driver package.
        fwColorEcho "[ERROR]The current installation package and environment is not match, please check."
        exit 1
    fi
}

get_pci_info() {
    local bdf="" i=0

    g_dev_nums=0
    g_bdfs=()

    for bdf in $(ls /sys/bus/pci/devices/)
    do
        cat /sys/bus/pci/devices/${bdf}/vendor 2>/dev/null | grep -Ewq "${vendor_bdf}" || continue
        cat /sys/bus/pci/devices/${bdf}/device 2>/dev/null | grep -Ewq "${device_bdf}" || continue
        # 0x0110: it means that the chip is recognized as 1 on the OS PCI bus but 2 on the device management driver.
        cat /sys/bus/pci/devices/${bdf}/subsystem_device 2>/dev/null | grep -wq "0x0110" && g_dev_nums=$(expr ${g_dev_nums} + 1)
        g_dev_nums=$(expr ${g_dev_nums} + 1)
        # to get all bdfs
        g_bdfs[${i}]="${bdf}"
        i=$(expr ${i} + 1)
    done
    log "[INFO]g_dev_nums=[${g_dev_nums}] and g_bdfs=[${g_bdfs[*]}]"

    return 0
}

installRun() {
    local run_install_type="$1"
    # Convert it to lowercase.
    run_install_type="${run_install_type,,}"
    # delete 'e' from install type.
    run_install_type="${run_install_type/e/}ed"

    INSTALL_ADDRESS="Driver_Install_Path_Param"
    INSTALL_ADDRESS_DRIVER="/driver/version.info"
    ATLAS_DRIVER_VERSION_NAME="Interversion"
    ASCENDHAL_VERSION="ascendhal_version"

    get_board_feature
    check_Device
    if [ $? -eq 1 ]; then
        if [ ! -f "/etc/ascend_install.info" ]; then
            fwColorEcho "[ERROR]firmware failed,Please make sure that the Run package is installed properly"
            exitLog 1
        fi

        while read line
        do
            temp=${line%%=*}
            if [ "$temp" = "$INSTALL_ADDRESS" ]; then
                    temp=${line#*=}
                    INSTALL_ADDRESS_DRIVER="$temp$INSTALL_ADDRESS_DRIVER"
                    while read driver_name
                    do
                        temp=${driver_name%%=*}
                        if [ "$temp" = "$ATLAS_DRIVER_VERSION_NAME" -o "$temp" = "$ASCENDHAL_VERSION" ]; then
                            rm -rf /etc/version.cfg
                            for board_info in ${board_id[@]};
                            do
                                echo  $board_info >> /etc/version.cfg
                                chmod 640 /etc/version.cfg
                            done
                        fi
                    done < $INSTALL_ADDRESS_DRIVER

            fi
        done < /etc/ascend_install.info


        if [ ! -f "/etc/version.cfg" ]; then
            if [ ! -d "/usr/local/" ]; then
                mkdir /usr/local --mode 755
            fi
            if [ ! -d "/usr/local/Ascend/" ]; then
                mkdir /usr/local/Ascend  --mode 755
            fi
            rm -rf /usr/local/Ascend/version.cfg

            for board_info in ${board_id[@]};
            do
                echo  $board_info >> /usr/local/Ascend/version.cfg
                chmod 640 /usr/local/Ascend/version.cfg
            done
        fi
    fi
    $Firmware_Install_Path_Param/firmware/script/run_firmware_install.sh "$Install_Path_Param" $reset_passwd_flag "$installType"
    firmware_install_status=$?
    if [ ${firmware_install_status} -eq 0 ]; then
        if [ ${feature_running_on_device_check} = y ];then
            fwColorEcho "[INFO]\033[32mFirmware package ${run_install_type} successfully! \033[0m\033[31mReboot now to take effect.\033[0m"
        else
            fwColorEcho "[INFO]\033[32mFirmware package ${run_install_type} successfully! \033[0m\033[31mReboot now or after driver installation for the installation/upgrade to take effect.\033[0m"
        fi
    else
        fwColorEcho "[INFO]Failed to ${1,,} firmware package, please retry after uninstall and reboot!"
    fi
}

Firmware_Install_Path_Param=$(getInstallParam "Firmware_Install_Path_Param" "${installInfo}")
Driver_Install_Path_Param=$(getInstallParam "Driver_Install_Path_Param" "${installInfo}")
Install_Path_Param="${Driver_Install_Path_Param}"
reset_passwd_flag=n
Firmware_Install_Type=$(getInstallParam "Firmware_Install_Type" "${installInfo}")
installType="$Firmware_Install_Type"
sourcedir=$Firmware_Install_Path_Param/firmware
firmware_install_status=0
upgrade=n
uninstall=n

source "${sourcedir}"/script/specific_func.inc
start_time=$(date +"%Y-%m-%d %H:%M:%S")

checkDriverProduct

get_pci_info
global_pci_num=${g_dev_nums}
# to check whether there is a chip at least.
if [ ${global_pci_num} -eq 0 ];then
    log "[ERROR]pcie device is missing, cold reset may fix it."
    fwColorEcho "[ERROR]\033[31mPcie device is missing, cold reset may fix it.\033[0m"
    exitLog 1
fi
log "[INFO][${global_pci_num}] mini pcie devices are scanned."

if [ $1 -eq 1 ]; then
    installRun "Install"
else
    installRun "Upgrade"
fi

operation="${LOG_OPERATION_INSTALL}"
installed_version=`cat "$Firmware_Install_Path_Param"/firmware/version.info | awk -F '=' '$1=="Version" {print $2}'`
runfilename="Ascend-firmware-"$installed_version
all_parma=none
if [ ${firmware_install_status} -eq 0 ];then
    logOperation "${operation}" "${start_time}" "${runfilename}" "${LOG_RESULT_SUCCESS}" "${installType}" "${all_parma}"
    exitLog 0
else
    logOperation "${operation}" "${start_time}" "${runfilename}" "${LOG_RESULT_FAILED}" "${installType}" "${all_parma}"
    exitLog 1
fi
