#!/usr/bin/env bash
umask 0027
set -u # treat unset variables as an error

#------------------------------------------------------------------
# Library - Linux distribution / Linux release Functions
#------------------------------------------------------------------
# Script name: "lib_linux_release"
#
#------------------------------------------------------------------

# return if library is already loaded
[[ -n "${LIB_LINUX_RELEASE:-}" ]] && return 0

LIB_LINUX_RELEASE='2112-1.gcd051766'
#LIB_RELEASE_DATE='2021-Dec-03'


##################################################
# Global functions - to be used in other scripts
##################################################

# Returns 0 on SLES4SAP, 1 on other
function LIB_FUNC_IS_SLES4SAP {

    local -i _retval=1

    logTrace "<${BASH_SOURCE[0]}:${FUNCNAME[*]}>"

    ${lib_release_sles4sap} && _retval=0

    logDebug "<${BASH_SOURCE[0]}:${FUNCNAME[0]}> # RC=${_retval}"
    return ${_retval}
}

# Returns 0 on RHEL4SAP, 1 on other
function LIB_FUNC_IS_RHEL4SAP {

    local -i _retval=1

    logTrace "<${BASH_SOURCE[0]}:${FUNCNAME[*]}>"

    ${lib_release_rhel4sap} && _retval=0

    logDebug "<${BASH_SOURCE[0]}:${FUNCNAME[0]}> # RC=${_retval}"
    return ${_retval}
}

# Returns 0 on SLES, 1 on other
function LIB_FUNC_IS_SLES {

    local -i _retval=1

    logTrace "<${BASH_SOURCE[0]}:${FUNCNAME[*]}>"

    [[ "${OS_NAME}" == "${lib_release_sles}" ]] && _retval=0

    logDebug "<${BASH_SOURCE[0]}:${FUNCNAME[0]}> # RC=${_retval}"
    return ${_retval}
}

# Returns 0 on RHEL, 1 on other
function LIB_FUNC_IS_RHEL {

    local -i _retval=1

    logTrace "<${BASH_SOURCE[0]}:${FUNCNAME[*]}>"

    [[ "${OS_NAME}" == "${lib_release_rhel}" ]] && _retval=0

    logDebug "<${BASH_SOURCE[0]}:${FUNCNAME[0]}> # RC=${_retval}"
    return ${_retval}
}

# Returns 0 on OLS, 1 on other
function LIB_FUNC_IS_OLS {

    local -i _retval=1

    logTrace "<${BASH_SOURCE[0]}:${FUNCNAME[*]}>"

    [[ "${OS_NAME}" == "${lib_release_ols}" ]] && _retval=0

    logDebug "<${BASH_SOURCE[0]}:${FUNCNAME[0]}> # RC=${_retval}"
    return ${_retval}
}

##########################################################
# Non-global functions - not to be used in other scripts
##########################################################

function __lib_func_get_linux_distrib {

    # a local variable declared in a function is also visible to
    # functions called by the parent function.
    local -r osfile='/etc/os-release'
    local -r susefile='/etc/SuSE-release'
    local -r redhatfile='/etc/redhat-release'
    local -r oraclefile='/etc/oracle-release'

    local _os_name
    local _os_version

    logTrace "<${BASH_SOURCE[0]}:${FUNCNAME[*]}>"

    if [ -f ${osfile} ] ; then
        #newer releases contain this file
        __linux_distrib_os_release "${osfile}"

    elif [ -f ${susefile} ] ; then
        __linux_distrib_suse_release "${susefile}"

    elif [ -f ${oraclefile} ] ; then
        #oracle is based on RedHat-redhatfile also exist, but check oracle first
        __linux_distrib_oracle_release "${oraclefile}"

    elif [ -f ${redhatfile} ] ; then
        __linux_distrib_redhat_release "${redhatfile}"

    else
        _os_name='Linux UNKNOWN'
    fi

    OS_NAME="${_os_name}"
    OS_VERSION="${_os_version}"
    OS_LEVEL=$(</proc/sys/kernel/osrelease)

    logDebug "<${BASH_SOURCE[0]}:${FUNCNAME[0]}> # ${OS_NAME} ; ${OS_VERSION} ; ${OS_LEVEL}"

}

function __linux_distrib_os_release {

    local _os_release_file="$1"
    shift 1

    local _osname
    local _osvers

    logTrace "<${BASH_SOURCE[0]}:${FUNCNAME[*]}>"

    while read -r line; do

        logTrace "<${FUNCNAME[0]}> # ${_os_release_file}:${line}"

        case ${line} in

            'ID='*)
                    [[ "${line}" =~ \"(.*)\" ]] && _osname=${BASH_REMATCH[1]}
            ;;

            'VERSION_ID='*)
                    #match 12.1 | 12.0.1 | 12.1.0.1 | 7.0 | 15
                    [[ "${line}" =~ ([0-9]+)(\.([0-9]+))* ]] && _osvers=${BASH_REMATCH[0]}

                    [[ -n "${_osvers##*.*}" ]] && _osvers="${_osvers}.0"  #15 --> 15.0
            ;;

            'CPE_NAME='*)
                break
            ;;

        esac

    done < "${_os_release_file}"

    _os_version="${_osvers:-}"

    case ${_osname:-} in
        'sles')
                _os_name="${lib_release_sles}"
                ;;

        'sles_sap')
                _os_name="${lib_release_sles}"
                ;;

        'rhel')
                _os_name="${lib_release_rhel}"
                ;;

        'ol')
                _os_name="${lib_release_ols}"
                ;;

        *)
            _os_name='Linux UNKNOWN'
            ;;
    esac
}

function __linux_distrib_suse_release {

    local _suse_release_file="$1"
    shift 1

    local _osname
    local _osvers
    local _susepatchl

    logTrace "<${BASH_SOURCE[0]}:${FUNCNAME[*]}>"

    while read -r line; do

        logTrace "<${FUNCNAME[0]}> # ${_suse_release_file}:${line}"

        case ${line} in

            'SUSE Linux Enterprise'*)
                    _osname="${lib_release_sles}"
            ;;

            'VERSION = '*)
                    [[ "${line}" =~ ([0-9]+) ]] && _osvers=${BASH_REMATCH[0]}
            ;;

            'PATCHLEVEL = '*)
                    if [[ "${line}" =~ ([0-9]+) ]] ; then
                        _susepatchl=${BASH_REMATCH[0]}
                    else
                        _susepatchl=0
                    fi
            break
            ;;

        esac

    done < "${_suse_release_file}"

    _os_version="${_osvers:-}.${_susepatchl:-}"

    if [ -n "${_osname:-}" ] ; then
        _os_name="${_osname}"
    else
        _os_name='Linux Suse UNKNOWN'
    fi
}

function __linux_distrib_redhat_release {

    local _redhat_release_file="$1"
    shift 1

    local _rhname
    local _rhversion

    logTrace "<${BASH_SOURCE[0]}:${FUNCNAME[*]}>"

    read -r line < "${_redhat_release_file}"

        logTrace "<${FUNCNAME[0]}> # ${_redhat_release_file}:${line}"

        case ${line} in

            'Red Hat Enterprise Linux'*)
                    _rhname="${lib_release_rhel}"
            ;;

        esac

        #match 6.4
        [[ "${line}" =~ ([0-9]+)(\.([0-9]+))* ]] && _rhversion=${BASH_REMATCH[0]}

    _os_version=${_rhversion:-}

    if [ -n "${_rhname:-}" ] ; then
        _os_name="${lib_release_rhel}"
    else
        _os_name='Linux Redhat UNKNOWN'
    fi

}

function __linux_distrib_oracle_release {

    local _oracle_release_file="$1"
    shift 1

    local _oltmp
    local _olname
    local _olversion

    logTrace "<${BASH_SOURCE[0]}:${FUNCNAME[*]}>"

    #oracle is based on RedHat - redhatfile also exist, but check oracle first
    while read -r line; do

        logTrace "<${FUNCNAME[0]}> # ${_oracle_release_file}:${line}"

        #Server within string - match any number
        _oltmp=$(awk '/^Oracle Linux Server/ {match($0, /([0-9]+)/);
                            print substr($0,RSTART,RLENGTH) }' <<< "${line}")
        _olname=${_olname:=$_oltmp}

        #match 6.4
        _oltmp=$(awk '/^Oracle Linux/ {match($0, /([0-9]+)\.([0-9]+)/);
                            print substr($0,RSTART,RLENGTH) }' <<< "${line}")
        _olversion=${_olversion:=$_oltmp}

    done < "${_oracle_release_file}"

    _os_version=${_olversion}

    if [ -n "${_olname}" ] ; then
        _os_name="${lib_release_ols}"
    else
        _os_name='Linux Oracle UNKNOWN'
    fi
}

function __lib_func_get_sles4sap {

    local _baseproduct

    logTrace "<${BASH_SOURCE[0]}:${FUNCNAME[*]}>"

    if LIB_FUNC_IS_SLES; then

        _baseproduct=$(readlink /etc/products.d/baseproduct)

        [[ ${_baseproduct} == 'SLES_SAP.prod' ]] && lib_release_sles4sap=true

    fi

    logDebug "<${BASH_SOURCE[0]}:${FUNCNAME[0]}> # ${lib_release_sles4sap}"

}

function __lib_func_get_rhel4sap {

    logTrace "<${BASH_SOURCE[0]}:${FUNCNAME[*]}>"

    if LIB_FUNC_IS_RHEL; then

        # as advised by Red Hat
        grep -s -q -m1 -E -e 'for SAP \(|SAP HANA \(|- SAP' /etc/yum.repos.d/redhat.repo && lib_release_rhel4sap=true

    fi

    logDebug "<${BASH_SOURCE[0]}:${FUNCNAME[0]}> # ${lib_release_rhel4sap}"

}
#============================================================
# LIB MAIN - initialization
#============================================================
function _lib_linux_release_main {

    logTrace "<${BASH_SOURCE[0]}:${FUNCNAME[*]}>"

    __lib_func_get_linux_distrib

    readonly OS_NAME
    readonly OS_VERSION
    readonly OS_LEVEL

    __lib_func_get_sles4sap
    __lib_func_get_rhel4sap

    readonly lib_release_sles4sap
    readonly lib_release_rhel4sap
}

#Import libraries
#shellcheck source=./saphana-logger
source "$( cd "${BASH_SOURCE[0]%/*}" && pwd )/saphana-logger" ||
                { echo 'unable to load saphana-logger library' >&2; exit 1; }

#LIB LOCAL
declare -r lib_release_rhel='Linux RHEL'
declare -r lib_release_sles='Linux SLES'
declare -r lib_release_ols='Linux OLS'

declare lib_release_sles4sap=false
declare lib_release_rhel4sap=false

#GLOBAL
declare OS_NAME
declare OS_VERSION
declare OS_LEVEL

_lib_linux_release_main
