#!/bin/bash

# Copyright 2023, 2024 Stuart Winter, Earth, Milky Way, ""
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#########################################################################
# Script : /sbin/slk-hwm-discover
# Purpose: Report information about the Hardware Model on which this
#          script is being run.  This is consumed by the OS InitRD
#          and the Slackware Installer by '/load_kernel_modules',
#          and various other tools within the Slackware Installer and
#          OS tools, including (but not limited to) Boot Loader management
#          tools.
# Status : ARM LOCAL
# Author : Stuart Winter <mozes@slackware.com>
# Date...: 01-Oct-2023
# Version: 1.00
#########################################################################
#
# Developers take note: /sys must be mounted for /proc/device-tree/model
# to be accessible.
# This information may also be obtained from /sys/devices/soc0/machine
# but the /proc entry point is the 'industry standard'.  Additionally,
# with some devices this author has supported in the past, the /sys
# entries were absent where as the /proc entry was always present.

# This tool will probably be enhanced over time, with options for
# various things.  However, its default action will remain as outputting
# the hardware model name, defaulting to a null string if undetected.

# Program information:
PROG=slk-hwm-discover
VERSION=1.00

# Device tree Hardware Model API endpoint:
DEVICETREE=/proc/device-tree/model

# Collapse all 32bit ARM & x86 variants of 'i?86' into a single
# platform: 'x86' and 'arm' respectively.
ARCH=$( uname -m | sed -e 's%i[0-9]86%x86%g' -e 's?arm.*?arm?g' )

# Display help and options text:
function display_help () {
cat <<EOF
${PROG}, version ${VERSION}
Hardware Model discovery tool.

 -a,   --print-arch  Display the architecture
 -h,   --help        Display this help text
EOF
}

# Determine the Hardware Model name:
function discover_hwm() {
   local hwm hwm_sysver
   [ -f ${DEVICETREE} ] && {
      hwm=$( strings ${DEVICETREE} 2>/dev/null ) ;} || \
      { # If /proc/device-tree/model is unavailable (e.g. on QEMU) then
        # fall back to dmidecode:
        # For systems that don't support this, dmidecode returns null so this will
        # still enable the caller to handle a lack of detection.
        hwm="$( dmidecode -s system-product-name )"
        # Note: on qemu and other Hardware Models, should we be required to make a distinction
        # between revisions/versions:
        # $ dmidecode -s system-version
        #   virt-7.2
        hwm_sysver="$( dmidecode -s system-version | sed 's?Not Specified??g' )"
        [ ! -z "${hwm_sysver}" ] && hwm+=" ${hwm_sysver}"
     }
   # Handle special cases, convert into a useful string:
   case "${hwm}" in
   # Cloud-based virtualised ARM - just make it match with the Kernel Module Loader and other
   # scripts, since we just need it to load the correct modules & setup correct behaviours for
   # a virtualised environment.
     linux,dummy-virt*) hwm="QEMU Virtual" ;;
     # VMWare Fusion running on Apple Silicon (e.g. Macbook with Apple Silicon):
     VMware20,1*) hwm=$( printf "$( dmidecode -s system-family ) $( dmidecode -s processor-version )" ) ;;
   esac
   echo "${hwm}"
}

PARAMS="$( getopt -qn "$( basename $0 )" -o ha -l help,print-arch -- "$@" )"
# If params are incorrect then
if [ $? -gt 0 ]; then display_help ; exit 2 ; fi
eval set -- "${PARAMS}"
for param in $*; do
  case "$param" in
     -a|--print-arch)
        echo "${ARCH}"
        shift 1
        exit;;
     -h|--help)
        display_help
        shift 1
        exit;;
     --)
        shift
        break;;
  esac
done

# Without any command line parameters, we output the Hardware Model name:
HWM=$( discover_hwm )
echo "${HWM}"
# If we didn't detect anything, exit with a non-zero code.
if [ -z "${HWM}" ]; then exit 3 ; fi
