#!/bin/bash
# ******************************************************************************
# ******************************************************************************
# sysname
#
# Script to print a string describing the type of operating system being run.
#
# Linux platform names (x86_64):
#   linux_rhel60, linux_rhel70_gcc93x, linux_rhel80, linux_rhel90, linux_rhel100
#   linux_ubuntu2204, linux_ubuntu2404, linux_ubuntu2604, ...
#   x64 (Windows)
#
# A user may set OA_UNSUPPORTED_PLAT to force an unsupported platform name.
# OA_SYSNAME overrides detection when set (no options).
#
# ******************************************************************************
# Except as specified in the OpenAccess terms of use of Cadence or Silicon
# Integration Initiative, this material may not be copied, modified,
# re-published, uploaded, executed, or distributed in any way, in any medium,
# in whole or in part, without prior written permission from Cadence.
#
#                 Copyright 2002 Cadence Design Systems, Inc.
#                        All Rights Reserved Worldwide.
#
# *****************************************************************************
# *****************************************************************************

PATH=/usr/bin:/bin:$PATH

usage() {
  echo "Usage: sysname [ -h | -m | -b | -v | -V ]"
}

# Map Ubuntu VERSION_ID (e.g. 22.04) -> linux_ubuntu2204
set_ubuntu_sysname() {
    local vid="${VERSION_ID:-unknown}"
    local vid_compact="${vid//./}"
    sysname="linux_ubuntu${vid_compact}"
    longVersion=${PRETTY_NAME:-Ubuntu}
    shortVersion="ubuntu${vid}"
    version="${vid}"
    sysnames="$sysname $sysnames"
}

# Map RHEL-family major version -> linux_rhel80 / linux_rhel90 / ...
set_rhel_sysname() {
    local major="${VERSION_ID%%.*}"
    if [[ -z "$major" ]]; then
        major="${VERSION_ID:-0}"
    fi

    case "$major" in
        10) sysname="linux_rhel100" ;;
        9)  sysname="linux_rhel90" ;;
        8)  sysname="linux_rhel80" ;;
        7)  sysname="linux_rhel70_gcc93x" ;;
        6)  sysname="linux_rhel60" ;;
        *)  sysname="linux_rhel${major}0" ;;
    esac

    longVersion=${PRETTY_NAME:-Red Hat Enterprise Linux}
    shortVersion="rhel${major}"
    version="${VERSION_ID:-$major}"
    sysnames="$sysname $sysnames"
}

# Legacy awk-based detection for os-release variants without ID= (no quotes).
detect_from_os_release_awk() {
    id_name=$(/bin/awk -F \" '
        $1 ~ /^ID=$/ { id = $2 }
        $1 ~ /^ID=/ && id == "" { sub(/^ID=/, "", $0); id = $0 }
        $1 ~ /^VERSION_ID=$/ { ver = $2 }
        $1 ~ /^VERSION_ID=/ && ver == "" { sub(/^VERSION_ID=/, "", $0); gsub(/"/, "", $0); ver = $0 }
        $1 ~ /^PRETTY_NAME=$/ { name = $2 }
        END { print id " " ver " " name }
        ' /etc/os-release)

    local id ver name
    read -r id ver name <<< "$id_name"
    longVersion=${name:-Linux}
    shortVersion="${id}${ver}"
    version="${ver:-unknown}"

    case "$id" in
        ubuntu)
            VERSION_ID="${ver}"
            PRETTY_NAME="${name}"
            set_ubuntu_sysname
            return 0
            ;;
        rhel)
            VERSION_ID="${ver}"
            PRETTY_NAME="${name}"
            set_rhel_sysname
            return 0
            ;;
        centos)
            if [[ "$ver" == 7* ]]; then
                sysname="linux_rhel70_gcc93x"
                sysnames="$sysname $sysnames"
                return 0
            fi
            VERSION_ID="${ver}"
            set_rhel_sysname
            return 0
            ;;
        rocky|almalinux|slmicro)
            VERSION_ID="${ver}"
            PRETTY_NAME="${name}"
            set_rhel_sysname
            return 0
            ;;
        sles)
            if [[ "$ver" == 15* ]]; then
                sysname="linux_rhel80"
                sysnames="$sysname $sysnames"
                return 0
            fi
            if [[ "$ver" == 12* ]]; then
                sysname="linux_rhel70_gcc93x"
                sysnames="$sysname $sysnames"
                return 0
            fi
            ;;
    esac
    return 1
}

# *****************************************************************************
# check_linux
# *****************************************************************************
check_linux() {
    sysnames=$sysname

    version=${system_release_machine[1]}
    machine=${system_release_machine[2]}

    case $machine in
        x86_64 )
            if [[ -f "/etc/os-release" ]]; then
                # shellcheck disable=SC1091
                . /etc/os-release

                case "${ID:-}" in
                    ubuntu)
                        set_ubuntu_sysname
                        ;;
                    rhel)
                        set_rhel_sysname
                        ;;
                    centos)
                        if [[ "${VERSION_ID:-}" == 7* ]]; then
                            sysname="linux_rhel70_gcc93x"
                            longVersion=${PRETTY_NAME:-CentOS Linux 7}
                            shortVersion="centos7"
                            version="${VERSION_ID:-7}"
                            sysnames="$sysname $sysnames"
                        else
                            set_rhel_sysname
                        fi
                        ;;
                    rocky|almalinux|slmicro|centos_stream)
                        set_rhel_sysname
                        ;;
                    sles)
                        if [[ "${VERSION_ID:-}" == 15* ]]; then
                            sysname="linux_rhel80"
                            longVersion=${PRETTY_NAME:-SLES 15}
                            shortVersion="sles${VERSION_ID:-15}"
                            version="${VERSION_ID:-15}"
                            sysnames="$sysname $sysnames"
                        elif [[ "${VERSION_ID:-}" == 12* ]]; then
                            sysname="linux_rhel70_gcc93x"
                            longVersion=${PRETTY_NAME:-SLES 12}
                            shortVersion="sles${VERSION_ID:-12}"
                            version="${VERSION_ID:-12}"
                            sysnames="$sysname $sysnames"
                        fi
                        ;;
                    *)
                        if ! detect_from_os_release_awk; then
                            # Match legacy rhel8/9/10 strings from awk-only detection
                            id_name=$(/bin/awk -F \" '
                                $1 ~ /^ID=$/ { id = $2 }
                                $1 ~ /^VERSION_ID=$/ { ver = $2 }
                                END { print id ver }
                                ' /etc/os-release)
                            shortVersion=${id_name// /}
                            longVersion=${PRETTY_NAME:-Linux}

                            if [[ -z ${shortVersion#rhel10*} ]]; then
                                sysname="linux_rhel100"
                                sysnames="$sysname $sysnames"
                            elif [[ -z ${shortVersion#rhel9*} ]]; then
                                sysname="linux_rhel90"
                                sysnames="$sysname $sysnames"
                            elif [[ -z ${shortVersion#rhel8*} ||
                                    -z ${shortVersion#sles15*} ]]; then
                                sysname="linux_rhel80"
                                sysnames="$sysname $sysnames"
                            elif [[ -z ${shortVersion#rhel7*} ||
                                    -z ${shortVersion#sles12*} ||
                                    -z ${shortVersion#centos7} ]]; then
                                sysname="linux_rhel70_gcc93x"
                                sysnames="$sysname $sysnames"
                            fi
                        fi
                        ;;
                esac
            elif [[ -f "/etc/redhat-release" ]]; then
                longVersion=$(< /etc/redhat-release)

                if [[ -z ${longVersion%Red Hat Enterprise Linux release 10*} ||
                      -z ${longVersion%Red Hat Enterprise Linux 10*} ]]; then
                    sysname="linux_rhel100"
                    shortVersion="rhel10"
                    version="10"
                    sysnames="$sysname $sysnames"
                elif [[ -z ${longVersion%Red Hat Enterprise Linux release 9*} ||
                        -z ${longVersion%Red Hat Enterprise Linux 9*} ]]; then
                    sysname="linux_rhel90"
                    shortVersion="rhel9"
                    version="9"
                    sysnames="$sysname $sysnames"
                elif [[ -z ${longVersion%Red Hat Enterprise Linux release 8*} ||
                        -z ${longVersion%Red Hat Enterprise Linux 8*} ]]; then
                    sysname="linux_rhel80"
                    shortVersion="rhel8"
                    version="8"
                    sysnames="$sysname $sysnames"
                elif [[ -z ${longVersion%Red Hat Enterprise Linux * 6.[0-9]*} ||
                      -z ${longVersion%CentOS release 6.[0-9]*} ]]; then
                    sysname="linux_rhel60"
                    sysnames="$sysname $sysnames"
                fi
            elif [[ -f "/etc/SuSE-release" ]]; then
                longVersion=$(< /etc/SuSE-release)

                if [[ -z ${longVersion%SUSE Linux Enterprise Server 11 *} ]]; then
                    sysname="linux_rhel60"
                    sysnames="$sysname $sysnames"
                fi
            fi
            ;;

        * )
            OA_SYSNAME_PATH=${0%/*}

            if [[ -f "$OA_SYSNAME_PATH/sysname.linux.local" ]]; then
                # shellcheck disable=SC1091
                . "$OA_SYSNAME_PATH/sysname.linux.local"
            fi
    esac

    if [[ $sysname = "linux" ]]; then
        check_global
    fi
}

# *****************************************************************************
# check_win
# *****************************************************************************
check_win() {
    sysname="x64"
    sysnames=$sysname
    version="x64"
    longVersion="Windows 64bit"
}

# *****************************************************************************
# check_global
# *****************************************************************************
check_global() {
    if [[ -n "$OA_UNSUPPORTED_PLAT" ]]; then
        sysname=${OA_UNSUPPORTED_PLAT}
        sysnames=$sysname
        version="Unknown"
        longVersion="Unknown"
    else
        echo "unknown"
        exit 1
    fi
}

# ******************************************************************************
# Start of the script
# ******************************************************************************

if [[ $# -gt 1 ]]; then
    usage
    exit 1
fi

matching_sysnames=0
base_sysname=0
get_version=0
get_longVersion=0
if [[ $# -eq 1 ]]; then
    case $1 in
        -h) usage; exit 0 ;;
        -m) matching_sysnames=1 ;;
        -b) base_sysname=1 ;;
        -v) get_version=1 ;;
        -V) get_longVersion=1 ;;
        *) usage; exit 1 ;;
    esac
else
    if [[ -n "$OA_SYSNAME" ]]; then
        echo "$OA_SYSNAME"
        exit 0
    fi
fi

declare -a system_release_machine
system_release_machine=( $(uname -srm) )

sysname=${system_release_machine[0]}
sysname=$(echo "$sysname" | LC_ALL=C tr -s '[:upper:]' '[:lower:]')
basesysname="$sysname"

case $basesysname in
    linux) check_linux ;;
    windows*|cygwin_nt*) check_win ;;
    *) check_global ;;
esac

if [[ $get_version -eq 1 ]]; then
    echo "$version"
elif [[ $get_longVersion -eq 1 ]]; then
    echo "$longVersion"
elif [[ $matching_sysnames -eq 1 ]]; then
    echo "$sysnames"
elif [[ $base_sysname -eq 1 ]]; then
    echo "$sysnames" | awk '{print $NF}'
else
    echo "$sysname"
fi

exit 0
