#!/usr/bin/env sh
set +o noclobber

KERNEL="$(uname -s)"
case $KERNEL in
    Darwin)
        PLATFORM="darwin"
        ;;
    Linux)
        PLATFORM="linux"
        ;;
    FreeBSD)
        PLATFORM="freebsd"
        ;;
    DragonFly)
        PLATFORM="dragonfly"
        ;;
    *)
        echo "Error platform not supported: $KERNEL"
        exit 1
        ;;
esac

ARCH="$(uname -m)"
case $ARCH in
    x86_64 | amd64)
        SERVER_ARCH="x64"
        ;;
    armv7l | armv8l)
        SERVER_ARCH="armhf"
        ;;
    arm64 | aarch64)
        SERVER_ARCH="arm64"
        ;;
    ppc64le)
        SERVER_ARCH="ppc64le"
        ;;
    riscv64)
        SERVER_ARCH="riscv64"
        ;;
    loongarch64)
        SERVER_ARCH="loong64"
        ;;
    s390x)
        SERVER_ARCH="s390x"
        ;;
    *)
        echo "Error architecture not supported: $ARCH"
        exit 1
        ;;
esac

OS_RELEASE_ID="$(grep -i '^ID=' /etc/os-release 2>/dev/null | sed 's/^ID=//gi' | sed 's/"//g')"
if [ -z "$OS_RELEASE_ID" ]; then
    OS_RELEASE_ID="$(grep -i '^ID=' /usr/lib/os-release 2>/dev/null | sed 's/^ID=//gi' | sed 's/"//g')"
    if [ -z "$OS_RELEASE_ID" ]; then
        OS_RELEASE_ID="unknown"
    fi
fi

OS_VERSION_ID="$(grep -i '^VERSION_ID=' /etc/os-release 2>/dev/null | sed 's/^VERSION_ID=//gi' | sed 's/"//g')"
if [ -z "$OS_VERSION_ID" ]; then
    OS_VERSION_ID="$(grep -i '^VERSION_ID=' /usr/lib/os-release 2>/dev/null | sed 's/^VERSION_ID=//gi' | sed 's/"//g')"
    if [ -z "$OS_VERSION_ID" ]; then
        OS_VERSION_ID="unknown"
    fi
fi

GLIBC_VERSION=""
if [ "$OS_ID" = "alpine" ]; then
    echo "Warning: alpine distro detected, skipping GLIBC check"
    GLIBC_VERSION="musl"
elif [ -z "$(ldd --version 2>&1 | grep 'musl libc')" ]; then
    if [ -f /sbin/ldconfig ]; then
        # Look up path
        libc_paths=$(/sbin/ldconfig -p | grep 'libc.so.6')

        if [ "$(echo "$libc_paths" | wc -l)" -gt 1 ]; then
            case $ARCH in
                x86_64) LDCONFIG_ARCH="x86-64";;
                armv7l | armv8l) LDCONFIG_ARCH="hard-float";;
                arm64 | aarch64)
                    BITNESS=$(getconf LONG_BIT)
                    if [ "$BITNESS" = "32" ]; then
                        # Can have 32-bit userland on 64-bit kernel
                        LDCONFIG_ARCH="hard-float"
                    else
                        LDCONFIG_ARCH="AArch64"
                    fi
                    ;;
            esac
            libc_path=$(echo "$libc_paths" | grep "$LDCONFIG_ARCH" | awk '{print $NF}')
        else
            libc_path=$(echo "$libc_paths" | awk '{print $NF}')
        fi
    elif [ -f /usr/lib/libc.so.6 ]; then
        # Typical path
        libc_path='/usr/lib/libc.so.6'
    elif [ -f /lib64/libc.so.6 ]; then
        # Typical path (OpenSUSE)
        libc_path='/lib64/libc.so.6'
    elif [ -f /usr/lib64/libc.so.6 ]; then
        # Typical path
        libc_path='/usr/lib64/libc.so.6'
    else
        echo "Warning: Can't find libc.so or ldconfig, can't verify libc version"
    fi

    while [ -n "$libc_path" ]; do
        # Rather than trusting the output of ldd --version (which is not always accurate)
        # we instead use the version of the cached libc.so.6 file itself.
        libc_path_line=$(echo "$libc_path" | head -n1)
        libc_real_path=$(readlink -f "$libc_path_line" 2>/dev/null || echo "$libc_path_line")
        libc_version=$(cat "$libc_real_path" 2>/dev/null | sed -n 's/.*release version \([0-9]\+\.[0-9]\+\).*/\1/p')
        if [ -n "$libc_version" ]; then
            GLIBC_VERSION="$libc_version"
            break
        fi
        libc_path=$(echo "$libc_path" | tail -n +2)    # remove first line
    done

    if [ -z "$GLIBC_VERSION" ]; then
        if command -v ldd >/dev/null 2>&1; then
            GLIBC_VERSION=$(ldd --version 2>&1 | grep -i "GLIBC|GNU C" | head -n1 | grep -oE '[0-9]+\.[0-9]+' | head -n1)
        fi
    fi

    if [ -z "$GLIBC_VERSION" ]; then
        GLIBC_VERSION="unknown"
    fi
else
    echo "Warning: musl detected, skipping GLIBC check"
    GLIBC_VERSION="musl"
fi

GLIBCXX_VERSION=""
if [ "$OS_ID" != "alpine" ] && [ -z "$(ldd --version 2>&1 | grep 'musl libc')" ]; then
    if [ -f /sbin/ldconfig ]; then
        # Look up path
        case $ARCH in
            x86_64) LDCONFIG_ARCH="x86-64";;
            armv7l | armv8l) LDCONFIG_ARCH="hard-float";;
            arm64 | aarch64)
                BITNESS=$(getconf LONG_BIT)
                if [ "$BITNESS" = "32" ]; then
                    LDCONFIG_ARCH="hard-float"
                else
                    LDCONFIG_ARCH="AArch64"
                fi
                ;;
        esac

        libstdcpp_paths=$(/sbin/ldconfig -p | grep 'libstdc++.so.6')

        if [ "$(echo "$libstdcpp_paths" | wc -l)" -gt 1 ]; then
            libstdcpp_path=$(echo "$libstdcpp_paths" | grep "$LDCONFIG_ARCH" | awk '{print $NF}')
        else
            libstdcpp_path=$(echo "$libstdcpp_paths" | awk '{print $NF}')
        fi
    elif [ -f /usr/lib/libstdc++.so.6 ]; then
        # Typical path
        libstdcpp_path='/usr/lib/libstdc++.so.6'
    elif [ -f /usr/lib64/libstdc++.so.6 ]; then
        # Typical path
        libstdcpp_path='/usr/lib64/libstdc++.so.6'
    else
        echo "Warning: Can't find libstdc++.so or ldconfig, can't verify libstdc++ version"
    fi

    while [ -n "$libstdcpp_path" ]; do
        libstdcpp_path_line=$(echo "$libstdcpp_path" | head -n1)
        libstdcpp_real_path=$(readlink -f "$libstdcpp_path_line" 2>/dev/null || echo "$libstdcpp_path_line")
        libstdcpp_version=$(grep -ao 'GLIBCXX_[0-9]*\.[0-9]*\.[0-9]*' "$libstdcpp_real_path" 2>/dev/null | sort -V | tail -1)
        if [ -n "$libstdcpp_version" ]; then
            GLIBCXX_VERSION=$(echo "$libstdcpp_version" | sed 's/GLIBCXX_//')
            break
        fi
        libstdcpp_path=$(echo "$libstdcpp_path" | tail -n +2)    # remove first line
    done

    if [ -z "$GLIBCXX_VERSION" ]; then
        GLIBCXX_VERSION="unknown"
    fi
fi

OS_ID="$(grep -i '^ID=' /etc/os-release 2>/dev/null | sed 's/^ID=//gi' | sed 's/"//g')"
if [ -z "$OS_ID" ]; then
    OS_ID="$(grep -i '^ID=' /usr/lib/os-release 2>/dev/null | sed 's/^ID=//gi' | sed 's/"//g')"
    if [ -z "$OS_ID" ]; then
        OS_ID="unknown"
    fi
fi

DOWNLOAD_TOOL=""
if [ -n "$(which curl)" ]; then
    DOWNLOAD_TOOL="curl"
elif [ -n "$(which wget)" ]; then
    DOWNLOAD_TOOL="wget"
fi

DECOMPRESS_TOOL=""
TAR_GZIP_SUPPORT=""
TAR_XZ_SUPPORT=""
if [ -n "$(which tar)" ]; then
    DECOMPRESS_TOOL="tar"
    if tar -czf /dev/null /dev/null 2>/dev/null; then
        TAR_GZIP_SUPPORT="yes"
    fi

    if tar -cJf /dev/null /dev/null 2>/dev/null; then
        TAR_XZ_SUPPORT="yes"
    fi
fi

check_region() {
    local region=""
    local retry_count=0
    local max_retries=50

    if [ "$DOWNLOAD_TOOL" != "curl" ] && [ "$DOWNLOAD_TOOL" != "wget" ]; then
        echo ""
        return 1
    fi

    local endpoints_env="${TRAE_LOGIN_GUIDANCE_ENDPOINTS}"
    if [ -z "$endpoints_env" ]; then
        echo ""
        return 1
    fi

    local endpoints
    endpoints=$(echo "$endpoints_env" | tr ',' ' ')

    local pids=""
    local files=""
    for ep in $endpoints; do
        tf=$(mktemp)
        files="$files $tf"
        if [ "$DOWNLOAD_TOOL" = "curl" ]; then
            curl -s -X POST "$ep" > "$tf" & pids="$pids $!"
        elif [ "$DOWNLOAD_TOOL" = "wget" ]; then
            wget -q -O "$tf" --post-data="" "$ep" & pids="$pids $!"
        fi
    done

    while [ $retry_count -lt $max_retries ]; do
        for f in $files; do
            if [ -s "$f" ]; then
                for pid in $pids; do kill "$pid" 2>/dev/null; done
                region=$(cat "$f" | grep -o '"Region":"[^"]*"' | sed 's/"Region":"\([^\"]*\)"/\1/')
                break 2
            fi
        done
        all_done=true
        for pid in $pids; do
            if kill -0 "$pid" 2>/dev/null; then all_done=false; break; fi
        done
        if [ "$all_done" = "true" ]; then
            break
        fi
        sleep 0.1
        retry_count=$((retry_count + 1))
    done

    for f in $files; do rm -f "$f"; done
    echo "$region" | tr -d '[:space:]'
}
REGION=$(check_region)

CONSUL_DATACENTER=""
if [ -f "/opt/tmp/consul_agent/datacenter" ]; then
    CONSUL_DATACENTER=$(cat "/opt/tmp/consul_agent/datacenter" | tr -d '[:space:]')
fi

NO_PROXY_BYTED="false"
if [ -n "$no_proxy" ] && echo "$no_proxy" | grep -q "byted.org" && ! echo "$no_proxy" | grep -q "bytedance.net"; then
    NO_PROXY_BYTED="true"
fi

TRAE_TMP="${XDG_RUNTIME_DIR:-/tmp}"

# Print a few newlines to clear potential garbage from previous command outputs,
# then print system information using a here document for better readability and performance.
printf "\n\n"
cat <<EOF
PLATFORM=$PLATFORM
ARCH=$ARCH
TEMPDIR=$TRAE_TMP
SERVER_ARCH=$SERVER_ARCH
OS_RELEASE_ID=$OS_RELEASE_ID
OS_VERSION_ID=$OS_VERSION_ID
OS_ID=$OS_ID
GLIBC_VERSION=$GLIBC_VERSION
GLIBCXX_VERSION=$GLIBCXX_VERSION
DOWNLOAD_TOOL=$DOWNLOAD_TOOL
DECOMPRESS_TOOL=$DECOMPRESS_TOOL
TAR_GZIP_SUPPORT=$TAR_GZIP_SUPPORT
TAR_XZ_SUPPORT=$TAR_XZ_SUPPORT
REGION=$REGION
RUNTIME_IDC_NAME=$RUNTIME_IDC_NAME
CONSUL_DATACENTER=$CONSUL_DATACENTER
BYTED_HOST_IP=$BYTED_HOST_IP
BYTED_HOST_IPV6=$BYTED_HOST_IPV6
NO_PROXY_BYTED=$NO_PROXY_BYTED
HTTPS_PROXY=${HTTPS_PROXY:-${http_proxy:-${ALL_PROXY}}}
CLOUDIDE_WORKSPACE_ID=$CLOUDIDE_WORKSPACE_ID
==check-remote-system.sh=finish==
EOF
