
SYSTEM_RELEASE=""
DIRECTOR_FLAG="uninstall"
SYSTEM_DIST="$(uname -m)"
KERNEL_VERSION_ARCH="$(uname -r)"
RELEASE_CONTEXT=( "/etc/centos-release,CentOS Linux release 8.0.1905,CentOS8.0"
"/etc/redhat-release,Red Hat Enterprise Linux release 8.0,CentOS8.0"
"/etc/centos-release,CentOS Linux release 8.1.1911,CentOS8.1"
"/etc/redhat-release,Red Hat Enterprise Linux release 8.1,CentOS8.1"
"/etc/centos-release,CentOS Linux release 8.2.2004,CentOS8.2"
"/etc/redhat-release,Red Hat Enterprise Linux release 8.2,CentOS8.2"
"/etc/centos-release,CentOS Linux release 8.3.2011,CentOS8.3"
"/etc/redhat-release,Red Hat Enterprise Linux release 8.3,CentOS8.3"
"/etc/centos-release,CentOS Linux release 8.4.2105,CentOS8.4"
"/etc/redhat-release,Red Hat Enterprise Linux release 8.4,CentOS8.4"
"/etc/centos-release,CentOS Linux release 8.5.2111,CentOS8.5"
"/etc/redhat-release,Red Hat Enterprise Linux release 8.5,CentOS8.5"
"/etc/almalinux-release,AlmaLinux release 8.6 (Sky Tiger),Alma8.6"
"/etc/redhat-release,Red Hat Enterprise Linux release 8.6,Alma8.6"
"/etc/redhat-release,CentOS Linux release 7.6.1810 (Core),CentOS7.6"
"/etc/redhat-release,Red Hat Enterprise Linux Server release 7.6,CentOS7.6"
"/etc/rocky-release,Rocky Linux release 8.5 (Green Obsidian),CentOS8.5"
)

function basic_trace_msg()
{
    local module="${0##*/}"
    module="${module%%_*}"
    if [ "$1" = "ERROR" ]; then
        echo -e -n "\033[31m[ERROR]\033[0m "
    elif [ "$1" = "WARN" ] || [ "$1" = "WARNING" ]; then
        echo -e -n "\033[35m[WARNING]\033[0m "
    fi
    echo -e "$2"
}

function check_system()
{
    local context=""
    local file=""
    local release=""
    local str=""

    for str in "${RELEASE_CONTEXT[@]}"
    do
        file=$(echo "${str}" | awk -F "," '{print $1}')
        context=$(echo "${str}" | awk -F "," '{print $2}')
        release=$(echo "${str}" | awk -F "," '{print $3}')
        if [ -f "${file}" ] && [ $(cat "${file}" | grep -c "${context}") -ne 0 ]; then
            if [ $(echo "${KERNEL_VERSION_ARCH}" | grep -c "lustre") -ne 0 ]; then
                SYSTEM_RELEASE="${release}_lustre"
            else
                SYSTEM_RELEASE="${release}"
            fi
            break
        fi
        if [ -n "${SYSTEM_RELEASE}" ]; then
            break
        fi
    done
    if [ -z "${SYSTEM_RELEASE}" ]; then
        return 1
    fi
    return 0
}

function check_nof_director_rpm_packages()
{
    if [ ! -d "packages/OceanStor NOF Director" ]; then
        basic_trace_msg "ERROR" "OceanStor NOF Director, the installation directory of NOF Director, does not exist."
        return 1  
    fi
    if [ $(ls -l packages/OceanStor*Director | grep nvme-snsd | grep -c ${SYSTEM_DIST}) -ne 1 ]; then
        basic_trace_msg "ERROR" "nvme-snsd-***.rpm, the installation package of NOF Director, does not exist."
        return 1  
    fi  
    return 0
}

function check_nof_ini_rpm_packages()
{
    if [ ! -d "packages/OceanStor NOF INI" ]; then
        basic_trace_msg "ERROR" "OceanStor NOF INI, the installation directory of NOF INI, does not exist."
        return 1  
    fi
    if [ $(ls -l packages/OceanStor*INI | grep nvme-ini | grep -c ${SYSTEM_RELEASE}.${SYSTEM_DIST}.rpm) -ne 1 ]; then
        basic_trace_msg "ERROR" "nvme-ini-***.rpm, the installation package of NOF INI, does not exist."
        return 1  
    fi
    return 0    
}

function check_nvme_disk()
{
    if [ "$(which nvme 2>/dev/null)" == "" ]; then
        basic_trace_msg "ERROR" "The nvme command does not exist. Please install the nvme-cli package and try again."
        return 1
    fi
    if [ $(nvme list 2>&1 | grep -c -E "fail|Fail") -ne 0 ]; then
        basic_trace_msg "ERROR" "A faulty NVMe device exists in the system. Ensure that the NVMe device is restored before installing the NOF INI software.(Run the nvme list command to check the faulty NVMe device)"
        return 1
    fi
    return 0
}

function install_nof_director_rpm()
{
    check_nof_director_rpm_packages
    if [ $? -ne 0 ]; then
        return 1
    fi 
    if [ ! -f "/etc/nvme/snsd.conf" ]; then
        basic_trace_msg "ERROR" "/etc/nvme/snsd.conf, the configuration file required by the NOF Director software, does not exist."
        return 1  
    fi
    if [ $(rpm -qa | grep -c nvme-snsd) -ne 0 ]; then
        basic_trace_msg "WARN" "The NOF Director software has been installed."
        return 0
    fi
    cd "packages/OceanStor NOF Director"
    rpm -ivh nvme-snsd-*-linux.${SYSTEM_DIST}.rpm
    if [ $? -ne 0 ]; then
        basic_trace_msg "ERROR" "The NOF Director software fails to be installed."
        return 1
    fi
    cd ../../
    return 0
}

function install_nof_ini_rpm()
{
    local tmp_file="/tmp/rpm.${RANDOM}_$$.tmp"
    
    check_system
    if [ $? -ne 0 ]; then
        return 2
    fi
    check_nvme_disk
    if [ $? -ne 0 ]; then
        return 1
    fi  
    if [ $(rpm -qa | grep mlnx | grep -c -E "nvme|ofa") -ne 0 ]; then
        basic_trace_msg "ERROR" "The NOF INI software conflicts with the installed mlnx-nvme driver. Please try again after uninstall mlnx-nvme."
        return 1
    fi
    check_nof_ini_rpm_packages
    if [ $? -ne 0 ]; then
        return 1
    fi      
    if [ $(rpm -qa | grep -c nvme-ini) -ne 0 ]; then
        basic_trace_msg "WARN" "The NOF INI software has been installed."
        return 0
    fi
    cd "packages/OceanStor NOF INI"
    rpm -ivh nvme-ini-*-${SYSTEM_RELEASE}.${SYSTEM_DIST}.rpm 2>${tmp_file}
    if [ -f "${tmp_file}" ] && [ $(cat ${tmp_file} | grep -c "post") -ne 0 ]; then
        basic_trace_msg "ERROR" "Failed to install the NOF INI software. Rolling back..."
        rpm -e nvme-ini 2>/dev/null 1>/dev/null
        rm -rf "${tmp_file}"
        return 1
    fi
    rm -rf "${tmp_file}"
    cd ../../
    return 0
}

function uninstall_nof_director_rpm()
{
    if [ $(rpm -qa | grep -c nvme-snsd) -ne 0 ]; then
        rpm -e nvme-snsd
    fi
}

function install_all_packages
{
    install_nof_director_rpm
    if [ $? -ne 0 ]; then
        return 1
    fi
    install_nof_ini_rpm
    if [ $? -eq 1 ]; then
        if [ "${DIRECTOR_FLAG}" == "uninstall" ]; then
            uninstall_nof_director_rpm
        fi
        return 1
    fi
    return 0
}

function handle_parameter()
{
    if [ ! -z "$1" ]; then
        case "$1" in
        -ini|-i)
            install_nof_ini_rpm
            if [ $? -eq 2 ]; then
                basic_trace_msg "WARN" "The NOF INI software does not support the current operating system."
                return 1
            fi
            return $?
            ;;
        -director|-d)
            install_nof_director_rpm
            return $?
            ;;
        -all|-a)
            install_all_packages
            return $?
            ;;
        *)
            basic_trace_msg "ERROR" "Invalid parameter. \"$1\""
            echo "usage: sh install.sh [parameter]

parameter:
    [-ini, -i]        Install only the NOF INI software package.
    [-director, -d]   Install only the NOF Director software package.
    [-all, -a]        Install all software packages (default installation item).
    "
            return 1
            ;;
        esac
    fi
}

if [ "${SYSTEM_DIST}" != "x86_64" ] && [ "${SYSTEM_DIST}" != "aarch64" ]; then
    basic_trace_msg "ERROR" "The NOF Enabler software does not support the current operating system."
    exit 1
fi
if [ $(rpm -qa | grep -c nvme-snsd) -ne 0 ]; then
    DIRECTOR_FLAG="installed"
fi
if [ ! -z "$@" ]; then
    handle_parameter "$@"
    exit $?
fi
install_all_packages
exit $?