#!/bin/bash

#set -eu


# 依赖的 Kernel 的最低版本
MINIMUM_REQUIRED_KERNEL_VERSION="2.6.32"
MINIMUM_REQUIRED_KERNEL_VERSION_FOR_ARMV7="2.6.32"
MINIMUM_REQUIRED_KERNEL_VERSION_FOR_ARMV7_HF="2.6.32"
MINIMUM_REQUIRED_KERNEL_VERSION_FOR_ARMV8="3.7.0"
MINIMUM_REQUIRED_KERNEL_VERSION_FOR_X86_64="2.6.32"

# 依赖的Libc 的最低版本
MINIMUM_REQUIRED_LIBC_VERSION="2.14"

# 依赖的Python 版本
REQUIRED_PYTHON_VERSION="3"

# 依赖的NodeJS 版本
REQUIRED_NODEJS_VERSION="8.9.4"

# 依赖的OpenSSL 最低版本
MINIMUM_REQUIRED_OPENSSL_VERSION="1.0.1"

# 依赖的命令，根据需要添加到下面的数组中
COMMANDS_ARRAY=(wget realpath tar unzip readlink basename dirname pidof df grep ps kill dirname xargs umount awk mkdir)

C_LIBRARY=""
C_LIBRARY_VERSION=""

# ----------------------------util wrap---------------------------------------------------
NOTES=""
WARNINGS=""
ERRORS=""
DEPENDENCY_WARNINGS=""
DEPENDENCY_FAILURES=""

NOTES_COUNT=0
WARNINGS_COUNT=0
ERRORS_COUNT=0
DEPENDENCY_WARNINGS_COUNT=0
DEPENDENCY_FAILURES_COUNT=0

add_to_notes() {
    local message="$1"

    NOTES_COUNT=$(expr $NOTES_COUNT + 1)
    NOTES="$NOTES\n$NOTES_COUNT. $message\n"
}

add_to_errors() {
    local message="$1"

    SCRIPT_EXIT_CODE=1
    ERRORS_COUNT=$(expr $ERRORS_COUNT + 1)
    ERRORS="$ERRORS\n$ERRORS_COUNT. $message\n"
}

add_to_warnings() {
    local message="$1"

    WARNINGS_COUNT=$(expr $WARNINGS_COUNT + 1)
    WARNINGS="$WARNINGS\n$WARNINGS_COUNT. $message\n"
}

add_to_dependency_warnings() {
    local message="$1"

    DEPENDENCY_WARNINGS_COUNT=$(expr $DEPENDENCY_WARNINGS_COUNT + 1)
    DEPENDENCY_WARNINGS="$DEPENDENCY_WARNINGS\n$DEPENDENCY_WARNINGS_COUNT. $message\n"
}

add_to_dependency_failures() {
    local message="$1"

    SCRIPT_EXIT_CODE=1
    DEPENDENCY_FAILURES_COUNT=$(expr $DEPENDENCY_FAILURES_COUNT + 1)
    DEPENDENCY_FAILURES="$DEPENDENCY_FAILURES\n$DEPENDENCY_FAILURES_COUNT. $message\n"
}

warn() {
    local message="$1"
    log $WARN $YELLOW "$message" 1
}

print_good() {
    echo -e "$1: " "\033[1;32m $2\033[0m"
}

print_warn() {
    echo -e "$1: " "\033[1;33m $2\033[0m"
}

print_bad() {
    echo -e "$1: " "\033[1;31m $2\033[0m"
}

print_info() {
    echo -e "$1: " "\033[1;37m $2\033[0m"
}

print_underline() {
    echo -e  "\033[4;37m$1\033[0m" 
}

parse_version_string() {
    local major_version
    local minor_version
    local full_version="$1"

    ## Extract the major and minor version from the full version.
    ## Eg: 4.1.3+ is converted to 4.1
    major_version="${full_version%%.*}"
    minor_version="${full_version#$major_version.}"
    minor_version="${minor_version%%.*}"
    PARSED_VERSION_STRING="$major_version.$minor_version"
}

get_major_version() {
    local full_version="$1"

    MAJOR_VERSION="${full_version%%.*}"
}

get_minor_version() {
    local full_version="$1"

    minor_version="${full_version#*.}"
    MINOR_VERSION="${minor_version%%.*}"
}

get_patch() {
    local full_version="$1"

    PATCH=${full_version##*.*.}
    if [ "$full_version" = "$PATCH" ]
    then
        PATCH=0
    fi
}

compare_versions() {
    local left_version="$1"
    local right_version="$2"

    ## Compare major versions
    get_major_version "$left_version"
    local left_major="$MAJOR_VERSION"
    get_major_version "$right_version"
    local right_major="$MAJOR_VERSION"

    if [ "$left_major" -gt "$right_major" ]
    then
        GREATER_OR_EQUALS=1
        return
    elif [ "$left_major" -lt "$right_major" ]
    then
        GREATER_OR_EQUALS=0
        return
    fi

    ## Compare minor versions
    get_minor_version "$left_version"
    local left_minor="$MINOR_VERSION"
    get_minor_version "$right_version"
    local right_minor="$MINOR_VERSION"

    if [ "$left_minor" -gt "$right_minor" ]
    then
        GREATER_OR_EQUALS=1
        return
    elif [ "$left_minor" -lt "$right_minor" ]
    then
        GREATER_OR_EQUALS=0
        return
    fi

    ## Compare patch versions
    get_patch "$left_version"
    local left_patch="$PATCH"
    get_patch "$right_version"
    local right_patch="$PATCH"

    if [ "$left_patch" -gt "$right_patch" ]
    then
        GREATER_OR_EQUALS=1
        return
    elif [ "$left_patch" -lt "$right_patch" ]
    then
        GREATER_OR_EQUALS=0
        return
    fi

    GREATER_OR_EQUALS=1
}

remove_parantheses() {
    local message="$1"

    ## Remove the open parathesis from the beginning of the message
    message="${message#\(}"

    ## Remove the close parathesis from the end of the message
    message="${message%%)}"

    STRING_WITHOUT_PARATHESIS="$message"
}

# -----------------------------system configure----------------------------------------------
get_kernel_architecture() {
    local message

    local kernel_architecture="$(uname -m)"
    print_good "Kernel architecture" "$kernel_architecture"
}

check_if_systemd() {
    init_process="$1"

    {
        systemd_used="$(echo "$init_process" | grep -o systemd)"
    } && {
        message="It looks like the kernel uses 'systemd' as the init process."
        message="$message\nPlease using systemd to manage Link IoT Edge service."
        add_to_notes "$message"
    } || {
        message="It looks like the kernel does NOT use 'systemd' as the init process"
        message="$message.\nPlease add /linkedge/gateway/build/script/iot_gateway_start.sh to /etc/init.d/rc.local to start the service"

        add_to_notes "$message"
    }
}


get_init_process() {
    local init_process
    local systemd_used

    { 
        init_process="$(readlink /proc/1/exe 2>/dev/null)" && test -n "$init_process"
    } || { 
        add_to_errors "Failed to find the init process on the host"
        return
    }

    print_good "Init process" "$init_process"
    check_if_systemd "$init_process"
}

check_kernel_version() {

	## Get the cpu arch
    local cpu_arch="$(uname -p | tr 'A-Z' 'a-z')"
	case "$cpu_arch" in
		"x86_64") 
			MINIMUM_REQUIRED_KERNEL_VERSION=$MINIMUM_REQUIRED_KERNEL_VERSION_FOR_X86_64
			;;
		"armv7"*|"aarch32") 
			MINIMUM_REQUIRED_KERNEL_VERSION=$MINIMUM_REQUIRED_KERNEL_VERSION_FOR_ARMV7
			;;
		"aarch64") MINIMUM_REQUIRED_KERNEL_VERSION=$MINIMUM_REQUIRED_KERNEL_VERSION_FOR_ARMV8
			;;
		*) 
			MINIMUM_REQUIRED_KERNEL_VERSION=$MINIMUM_REQUIRED_KERNEL_VERSION
			;;
	esac
    ## Get the kernel version
    local kernel_version="$(uname -r)"

    ## Extract the major and minor version of the kernel from the output
    parse_version_string "$kernel_version"
    kernel_version="$PARSED_VERSION_STRING"

    compare_versions "$kernel_version" "$MINIMUM_REQUIRED_KERNEL_VERSION"
    if [ $GREATER_OR_EQUALS -ne 1 ]
    then
        local message="Link IoT Edge runs and is tested at $cpu_arch architecture with a Linux kernel"
        message="$message version $MINIMUM_REQUIRED_KERNEL_VERSION or greater."
        message="$message The Linux\nkernel version on the device is"
        message="$message $kernel_version."
        print_warn "Kernel version" "$kernel_version"
        add_to_dependency_failures "$message"
        return
    fi

    print_good "Kernel version" "$kernel_version"
}

parse_ldd_output() {
    local libc_info="$1"

    ## Extract the first line from the output
    local ldd_output="$(echo "$libc_info" | head -n 1)"

    ## Find the C library - find a string enclosed in parathesis
    {
        c_library="$(echo "$ldd_output" | grep -o '(.*)')"
    } && {
        remove_parantheses "$c_library"
        C_LIBRARY="$STRING_WITHOUT_PARATHESIS"
    } || {
        ## Do not log the error here. The error will be caught in the parent
        ## function by testing for an empty C_LIBRARY.
        return
    }

    ## Extract the C library version - find the string after the last space on
    ## line.
    {
        C_LIBRARY_VERSION="$(echo "$ldd_output" | grep -o '[^ ]*$')"
    } || {
        ## Do not log the error here. The error will be caught in the parent
        ## function by testing for an empty C_LIBRARY_VERSION.
        return
    }
}


parse_libc_output() {
    local libc_info="$1"
    local c_library

    ## Extract the first line from the output
    local libc_output="$(echo "$libc_info" | head -n 1)"

    ## Find the C library - find a string enclosed in parathesis
    {
        c_library="$(echo $libc_output | grep -o '(.*)')"
    } && {
        remove_parantheses "$c_library"
        C_LIBRARY="$STRING_WITHOUT_PARATHESIS"
    } || {
        ## Do not log the error here. The error will be caught in the parent
        ## function by testing for an empty C_LIBRARY.
        return
    }

    ## Extract the C library version - find a string of word characters and
    ## period, after the string 'version '.
    local pattern_to_remove="version "
    {
        C_LIBRARY_VERSION="$(echo $libc_output | grep -o "version [0-9\.]*")"
    } || {
        ## Do not log the error here. The error will be caught in the parent
        ## function by testing for an empty C_LIBRARY_VERSION.
        return
    }

    C_LIBRARY_VERSION="${C_LIBRARY_VERSION#$pattern_to_remove}"
}

get_libc_info_from_executable() {
    local message
    local libc_info

    ## Find the paths under /lib* where libc.so.6 could be present
    local libc_path="$(find /lib* -name 'libc.so.6' 2>/dev/null | head -n 1)"

    ## Execute libc.so.6
    {
        test -n "$libc_path"
    } && {
        libc_info="$($libc_path)"
    } || {
        message="Failed to find the version of C library running on the device."
        message="$message\nYou could be using a very old version of C library."
        add_to_errors "$message"
        return
    }

    ## Parse the output of libc.so.6
    parse_libc_output "$libc_info"
}


check_libc_version() {
    local message
    local libc_version="$1"

    parse_version_string "$libc_version"
    libc_version="$PARSED_VERSION_STRING"

    compare_versions "$libc_version" "$MINIMUM_REQUIRED_LIBC_VERSION"
    if [ $GREATER_OR_EQUALS -ne 1 ]
    then
        print_bad "C library version" "$libc_version"
        message="Link IoT Edge requires C library version"
        message="$message $MINIMUM_REQUIRED_LIBC_VERSION or greater to run"
        add_to_dependency_failures "$message"
        return
    fi

    print_good "C library version" "$libc_version"
}


get_libc_info() {
    local libc_info

    { ## Try getting the C library info from 'ldd --version'
        libc_info="$(ldd --version 2>/dev/null)" && parse_ldd_output "$libc_info"
    } || { ## Fallback - run the executable 'libc.so.6' to get the C library info
        get_libc_info_from_executable
    } || {
        add_to_errors "Could not find the version of C library running on the device"
        return
    }

    if [ "$C_LIBRARY" = "" -o "$C_LIBRARY_VERSION" = "" ]
    then
        add_to_errors "Failed to find information about the C library running on the device"
    else
        check_libc_version "$C_LIBRARY_VERSION"
        print_good "C library" "$C_LIBRARY"
    fi
}
get_avail_flash_space() {
	AVAIL_FLASH_SPACE=$(df -h / | sed -n '2p' | awk '{print $4}' | tr 'a-z' 'A-Z')
	print_good "Available disk space" "$AVAIL_FLASH_SPACE"	
}	

get_total_memory() {
	TOTAL_MEMORY=$(free -h | sed -n '2p' | awk '{print $2}' | tr 'a-z' 'A-Z')
	print_good "Total memory" "$TOTAL_MEMORY"
}
get_system_configs() {
    echo -e "\033[1;36mSystem Configurations:\033[0m "
    get_kernel_architecture
    check_kernel_version
	get_total_memory
	get_avail_flash_space
    #get_libc_info    
    get_init_process
}

#-------------------------------------------software check-------------------------------------------------
OPENSSL_VERSION=""

no_op() {
    :
}

check_python_version() {
    local python_version_info
    local python_version

    local message="Could not find the binary 'python $REQUIRED_PYTHON_VERSION'.\n"
    message="$message\nPython $REQUIRED_PYTHON_VERSION or later is required to execute Python FC on Link IoT Edge."
    message="$message\nPlease install Python $REQUIRED_PYTHON_VERSION or later on the device, or add its parent directory to"
    message="$message\nthe PATH environment variable, if a Python $REQUIRED_PYTHON_VERSION or later is already installed on the device."


    {
        python$REQUIRED_PYTHON_VERSION --version >/dev/null 2>&1
    } || {
        add_to_dependency_warnings "$message"
        return
    }

    python_version_info="$(python$REQUIRED_PYTHON_VERSION --version 2>&1)"
    python_version="$(echo $python_version_info | cut -d" " -f2)"
    if [ -n "$python_version_info" ]
    then
        print_good "Python version" "$python_version"
    else
        print_warn "Python $REQUIRED_NODEJS_VERSION" "Not found"
        message="Failed to extract the Python version from the string:"
        message="$message '$python_version_info'"
        add_to_warnings "$message"
    fi
}

check_nodejs_version() {
    local node_version_info
    local node_version
    local message="Could not find the binary 'nodejs $REQUIRED_NODEJS_VERSION'.\n"
    message="$message\nNodeJS $REQUIRED_NODEJS_VERSION or later is required to execute NodeJS FC and IFTTT on Link IoT Edge."
    message="$message\nPlease install NodeJS $REQUIRED_NODEJS_VERSION or later on the device, or add its parent directory to"
    message="$message\nthe PATH environment variable, if a NodeJS $REQUIRED_NODEJS_VERSION or later is already installed on the device."


    {
        node_version_info="$(nodejs $REQUIRED_NODEJS_VERSION --version 2>/dev/null)"
    } || {
        print_warn "NodeJS $REQUIRED_NODEJS_VERSION" "Not found"
        add_to_dependency_warnings "$message"
        return
    }

    node_version="$(echo ${node_version_info#v})"
    if [ -n "$node_version" ]
    then
        print_good "NodeJS version" "$node_version"
    else
        message="Failed to extract the NodeJS version from the string: '$node_version_info'"
        add_to_warnings "$message"
    fi
}


get_openssl_version() {
    local openssl_versions="$1"

    openssl_unique_versions="$(echo "$openssl_versions" | sort | uniq | cut -d" " -f2)"
    for version in $openssl_unique_versions
    do
        compare_versions "$version" "$MINIMUM_REQUIRED_OPENSSL_VERSION"
        if [ $GREATER_OR_EQUALS -eq 1 ]
        then
            OPENSSL_VERSION="$version"
            return
        fi
    done
}

################################################################################
## Finds the OpenSSL versions available on the device. The result may contain
## duplicates.
##
## For each file in the variable "cmd_output", prints the readable characters of
## the file using the "strings" command, greps the file contents for the pattern
## "OpenSSL <openssl_version>"
##
## alinux % echo "$cmd_output" | xargs strings | grep -Eo "## ## OpenSSL[0-9]+\.[0-9]+\.[0-9]*"
## OpenSSL 0.9.8
## OpenSSL 0.9.8
## OpenSSL 0.9.8
## OpenSSL 0.9.8
## OpenSSL 0.9.8
## OpenSSL 1.0.1
## OpenSSL 1.0.1
## OpenSSL 1.0.1
## OpenSSL 1.0.1
## OpenSSL 1.0.1
## OpenSSL 1.0.1
## OpenSSL 1.0.1
## OpenSSL 1.0.1
## OpenSSL 1.0.1
## OpenSSL 1.0.1
## OpenSSL 1.0.1
## OpenSSL 1.0.1
## OpenSSL 1.0.1
## OpenSSL 1.0.1
## OpenSSL 1.0.1
## OpenSSL 0.9.8
## OpenSSL 0.9.8
## OpenSSL 0.9.8
## OpenSSL 0.9.8
################################################################################
process_libssl_paths() {
    local cmd_output="$1"
    local openssl_versions

    {
        openssl_versions="$(echo "$cmd_output" | xargs strings | \
        grep -Eo "OpenSSL [0-9]+\.[0-9]+\.[0-9]*")"
    } && {
        get_openssl_version "$openssl_versions"
    } || {
        no_op
        ## Ignore the error. The error will be detected in the parent functions
        ## since the global variable OPENSSL_VERSION will be an empty string.
    }
}

################################################################################
## Rerieves the abolute paths of the candidate libssl .so files by searching
## recursively in /lib, /usr/lib and /usr/local/lib (the standard paths where
## shared object files are found).
##
## alinux % find /usr*/lib* /lib* -name "libssl*" | grep "\.so"
## /usr/lib/libssl.so.0.9.8e
## /usr/lib/libssl.so.10
## /usr/lib/libssl.so.1.0.1k
## /usr/lib/libssl.so.1.0.0
## /usr/lib/libssl3.so
## /usr/lib/libssl.so.6
## /usr/lib64/libssl.so.0.9.8e
## /usr/lib64/libssl.so.10
## /usr/lib64/libssl.so.1.0.1k
## /usr/lib64/libssl3.so
## /usr/lib64/libssl.so.6
################################################################################
get_openssl_version_using_find() {
    local find_output

    local search_paths="/usr/lib* /lib*"
    if [ -d "/usr/local/bin" ]
    then
        search_paths="$search_paths /usr/local/bin"
    fi

    {
        find_output="$(find $search_paths -name "libssl*" | grep "\.so")"
    } && {
        process_libssl_paths "$find_output"
    } || {
        no_op
        ## Ignore the error. The error will be detected in the calling function
        ## since the global variable OPENSSL_VERSION will be an empty string.
    }
}

################################################################################
## Retrieves the list of candidate libssl paths using the 'ldconfig' command.
##
## Prints the lists of libraries stored in the cache, filters the results by
## 'libssl' and retrieves the absolute paths of candidate libssl .so files by
## retrieving the fourth field delimited by space:
## 
## alinux % ldconfig -p | grep libssl
## libssl3.so (libc6,x86-64) => /usr/lib64/libssl3.so
## libssl3.so (libc6) => /usr/lib/libssl3.so
## libssl.so.10 (libc6,x86-64) => /usr/lib64/libssl.so.10
## libssl.so.10 (libc6) => /usr/lib/libssl.so.10
## libssl.so.6 (libc6,x86-64) => /usr/lib64/libssl.so.6
## libssl.so.6 (libc6) => /usr/lib/libssl.so.6
##
## alinux % ldconfig -p | grep libssl | cut -d" " -f 4
## /usr/lib64/libssl3.so
## /usr/lib/libssl3.so
## /usr/lib64/libssl.so.10
## /usr/lib/libssl.so.10
## /usr/lib64/libssl.so.6
## /usr/lib/libssl.so.6
################################################################################
get_openssl_version_using_ldconfig() {
    local ldconfig_output

    {
        ldconfig_output="$(ldconfig -p 2>/dev/null | grep libssl)"
    } && {
        ldconfig_output="$(echo "$ldconfig_output" | cut -d" " -f 4)"
        process_libssl_paths "$ldconfig_output"
    } || {
        no_op
        ## Ignore the error. The error will be detected in the calling function
        ## since the global variable OPENSSL_VERSION will be an empty string.
    }
}

################################################################################
## Checks if the version of OpenSSL on the device is at least the minimum
## required version for the Over The Air(OTA) agent.
################################################################################
check_openssl_version() {
    local message

    ## First, try to get the version of OpenSSL using the 'ldconfig' command.
    get_openssl_version_using_ldconfig

    ## If the global variable 'OPENSSL_VERSION' is an empty string, fall back to
    ## finding the OpenSSL version by searching through the shared libraries
    ## using the 'find' command.
    if [ "$OPENSSL_VERSION" = "" ]
    then
        get_openssl_version_using_find
    fi

    ## Warn, if the global variable is still an empty string.
    if [ "$OPENSSL_VERSION" = "" ]
    then
        print_warn "OpenSSL (>= $MINIMUM_REQUIRED_OPENSSL_VERSION)" "Not found"
        message="Could not find OpenSSL version >= $MINIMUM_REQUIRED_OPENSSL_VERSION"
        message="$message on the device after searching through the\nstandard paths"
        message="$message : /lib, /usr/lib and /usr/local/lib.\n"
        message="$message\nThe Link IoT Edge requires OpenSSL version"
        message="$message $MINIMUM_REQUIRED_OPENSSL_VERSION or later to run."
        add_to_dependency_warnings "$message"
        return
    fi

    print_good "OpenSSL version" "$OPENSSL_VERSION"
}

check_if_command_present() {
    local cmd="$1"
    local message="The command '$cmd' was not found on the device."

    {
        command -v $cmd 2>/dev/null 1>&2 && echo -e "[  \033[1;32myes\033[0m  ]  Checking for command" "$cmd" 
    } || {
        echo -e "[  \033[1;31mno\033[0m   ]  Checking for command" "$cmd" 
        #add_to_dependency_warnings "$message"
        add_to_dependency_failures "$message"
    }
}

check_commands_req() {
    echo -e "\033[1;36mCheck Depended Commands:\033[0m "
    for dep_commnad in ${COMMANDS_ARRAY[@]}
    do
        check_if_command_present "${dep_commnad}"
    done
    echo ""
}
readonly FATAL=1*9/
readonly ERROR=2
readonly INFO=3
readonly WARN=4
readonly DEBUG=5
SCRIPT_EXIT_CODE=0

print_results() {
    local message
    local missing_dependencies_count=0

    echo ""
    echo -e "\033[4;32mLink IoT Edge Run Environment Check Result\033[0m"
    if [ $NOTES_COUNT -ne 0 ]
    then
        print_underline "Suggestion:"
        printf "$NOTES"
        echo ""
    fi

    if [ $WARNINGS_COUNT -ne 0 ]
    then
        print_underline "Warnings:" $WARN
        printf "$WARNINGS"
        echo ""
    fi

    if [ $ERRORS_COUNT -ne 0 ]
    then
        print_underline "Errors:" $ERROR
        printf "$ERRORS"
        echo ""
    fi

    if [ $DEPENDENCY_WARNINGS_COUNT -ne 0 ]
    then
        print_underline "\033[1;33mMissing optional dependencies: \033[0m"
        printf "$DEPENDENCY_WARNINGS"
        echo ""
    fi

    if [ $DEPENDENCY_FAILURES_COUNT -ne 0 ]
    then
        print_underline "\033[1;31mMissing required dependencies: \033[0m" 
        printf "$DEPENDENCY_FAILURES"
        echo ""
    fi

    if [ $SCRIPT_EXIT_CODE -ne 0 ]
    then
        message="\033[1;31mSome dependencies are missing for Link IoT Edge version,"
        message="$message Please check and install them."
        message="$message\nRefer to the 'Missing optional dependencies' and 'Missing required dependencies'.\n\033[0m\n"
        printf "$message"
    else
        message="\033[1;32mYou can install the Link IoT Edge"
        message="$message software on the device.\033[0m\n"
        printf "$message"
    fi

    exit $SCRIPT_EXIT_CODE
}

check_lo_is_up() {
   if ifconfig -a lo|grep -q "UP"; then
      print_good "Loopback is" "up"     
   else
      print_bad "Loopback is" "down"
      message="The network interface lo is down, please enable it using:"
      message="${message}\nsudo ifconfig lo up"
      add_to_errors  "${message}"
   fi
}

check_sw_packages() {
    echo ""
    echo -e "\033[1;36mCheck Depended Software Version:\033[0m"
    check_openssl_version

    check_python_version
    check_nodejs_version
    echo ""
}


check_root_user() {
    if [ -z "$FC_NO_ISOLATION" ]; then
        local effective_uid=$("id" | grep -o "uid=[0-9]*" | cut -d= -f2)

        if [ $effective_uid -ne 0 ]
        then
            echo -e "\033[1;31mThe script needs to be run as root.\033[0m"
            exit 1;
        fi
    fi
}


check_flash_space() {
	local message
	local avail_space=$AVAIL_FLASH_SPACE
	local unit=${avail_space: -1}
	local num=${avail_space:0:-1}
	case $unit in
		'T' | 'G')
			;;
		'M')
			if [ $num -le 1000 ];then
				message="Available space of root directory $avail_space is too small for log with default total size 1000M.\nPlease set log total size using tool_config after Link IoT Edge is started"
				add_to_warnings "$message"
			fi
			;;
		*)
			message="Available space of root directory $avail_space is too small for log with default total size 1000M.\nPlease set log total size using tool_config after Link IoT Edge is started" 
			add_to_warnings "$message"
		;;
	esac
}

link_iot_edge_env_check() {
    echo -e "\033[4;32mLink IoT Edge Run Environment Check\033[0m"

    check_root_user
    check_commands_req
    get_system_configs
    check_lo_is_up
    check_flash_space 
    #check_sw_packages
    print_results
}


link_iot_edge_env_required() {
    echo -e "\033[4;32mLink IoT Edge Standard Run Environment required\033[0m"
	echo "Linux Kernel Version:"
	echo "for x86_64:    >= 2.6.32"
	echo "for ARMv7:     >= 2.6.32"
	echo "for ARMv8_64:  >= 3.7.0"
	echo ""
	echo "RAM:           >= 128MB"
	echo "Disk:          >= 128MB"
	echo "CPU Frequency: >= 1GHZ"
	echo "CPU Architecture: x86_64, ARMv7, ARMv7 VFPv3, ARMv8_64"
        echo ""
}

link_iot_edge_env_required
link_iot_edge_env_check
