#!/bin/bash
# -----------------------------------------------------------------------------
#

# Global Declarations
declare -r MACH_ARCH=`uname -m`
declare -r SCRIPT=${0##*/}
declare -r mkdir="/bin/mkdir"
declare -r echo="/bin/echo"
declare -r hostname="/bin/hostname"
declare -r readlink="/usr/bin/readlink" 
declare -i broken_symlinks=0
declare -i missing_file=0
declare -i host_elelement=0
declare -i accl_element=0
declare -i daemon_error=0
declare -r my_euid=`whoami`

# Sanity Checks
if test -z "$BASH" ;  then
    printf "$SCRIPT:$LINENO: Please runthis script with the BASH shell.\n"
    exit 192
fi
if test ! -x  "$mkdir" ;  then
    printf "$SCRIPT:$LINENO: the command $mkdir is not available - aborting.\n"
    exit 192
fi
if test ! -x  "$echo" ;  then
    printf "$SCRIPT:$LINENO: the command $echo is not available - aborting.\n"
    exit 192
fi
if test ! -x  "$hostname" ;  then
    printf "$SCRIPT:$LINENO: the command $hostname is not available - aborting.\n"
    exit 192
fi
if test ! -x  "$readlink" ;  then
    printf "$SCRIPT:$LINENO: the command $readlink is not available - aborting.\n"
    exit 192
fi

if [ ! "$DACS_HYBRID_TOOLS_ROOT" ] ; then
    export DACS_HYBRID_TOOLS_ROOT="/opt/cell/sdk/prototype"
fi

export PATH=$DACS_HYBRID_TOOLS_ROOT/usr/bin:/sbin:$PATH
export LD_LIBRARY_PATH=/usr/lib64:$LD_LIBRARY_PATH

###################################################################
# display the system info
###################################################################
System_info()
{
   CURRENT_DATE="`date`"	
   LINUX_HOST=`uname -n`
   LINUX_KERNEL_NAME=`uname -s`
   LINUX_KERNEL_RELEASE=`uname -r`
   LINUX_KERNEL_VERSION=`uname -v`
   KERNEL_CPU=`uname -p`
   KERNEL_CMD_LINE=`cat /proc/cmdline`	
   PAGE_SIZE=`getconf PAGE_SIZE`

   RTC_CLOCK=`hwclock`
   LINUX_DATE=`date`

   # for now use linux host name
   SYS_NAME=$LINUX_HOST

   if [ -f $MEMORY_file ];then
      boot=`cat $MEMORY_file | grep MemTotal`
      set -- $boot
      SYS_MEMORY=$2$3
   else
      SYS_MEMORY="File $MEMORY_file does not exist"	
   fi

if [ $KERNEL_CPU == ppc64 ]; then 
   if [ -f $CPU_file ];then
      boot=`cat $CPU_file | grep cpu`
      set -- $boot
      SYS_CPU=$3

      boot=`cat $CPU_file | grep clock`
      set -- $boot
      CPU_FREQ=$3
      
      boot=`cat $CPU_file | grep revision`
      set -- $boot
      CPU_REVISION=$3

      boot=`cat $CPU_file | grep timebase`
      set -- $boot
      OFW_TIMEBASE="$3 Hz"
   else
      SYS_CPU="File $CPU_file does not exist"
      CPU_FREQ="unknown"
      CPU_REVISION="unknown"
      OFW_TIMEBASE="unknown"
   fi
elif [ $KERNEL_CPU == x86_64 ]; then
      boot=`cat $CPU_file | grep "model name"`
      set -- $boot
      SYS_CPU="$4 $5 $6 $7 $8 $9"

      boot=`cat $CPU_file | grep "cpu MHz"`
      set -- $boot
      CPU_FREQ="$4 MHz"
      
      boot=`cat $CPU_file | grep stepping`
      set -- $boot
      CPU_REVISION=$3


fi

# Get the model name/number of the system
   if [ -f $OFW_MODEL_file ];then
      OFW_MODEL=`cat $OFW_MODEL_file`
   else
      OFW_MODEL="unknown"
   fi

}

###################################################################
# display the system info
###################################################################
Axon_driver_info()
{
    version=`modinfo axon | grep version`
    set -- $version
    AXON_DRIVER_VERSION=$2
    version=`modinfo apnet | grep version`
    set -- $version
    APNET_DRIVER_VERSION=$2
    printf -v AXON_DRIVER_PAGE_SIZE "%lu" `cat $AXON_PAGE_SIZE_FILE`
}

###################################################################
# display H8 info
###################################################################
H8_info()
{
    if [ -f $OFW_H8_VERSION_file ];then
        OFW_H8_VERSION=`cat $OFW_H8_VERSION_file`
    else
        OFW_H8_VERSION="unknown"
    fi
}

###################################################################
# display the current OFW version and date, side where booted from
###################################################################
Firmware_info()
{
   if [ -f $OFW_BOOT_DEVICE_file ];then
      OFW_BOOT_DEVICE=`cat $OFW_BOOT_DEVICE_file`
   else
      OFW_BOOT_DEVICE="File $OFW_BOOT_DEVICE_file does not exist !"
   fi
   
   if [ -f $OFW_VERSION_file ];then
      OFW_VERSION=`cat $OFW_VERSION_file`
   else
      OFW_VERSION="File $OFW_VERSION_file does not exist !"
   fi
   
   if [ -f $OFW_BOOT_SIDE_file ];then
      boot=`cat $OFW_BOOT_SIDE_file` 
      case $boot in 
         "T") OFW_BOOT_SIDE="Temporary (A-side)" ;;
         "P") OFW_BOOT_SIDE="Permanent (B-side)" ;;
           *) OFW_BOOT_SIDE="unknown ($boot-side)";;
      esac
   else 
      OFW_BOOT_SIDE="File $OFW_BOOT_SIDE_file does not exist !"
   fi
   
   if [ -f $OFW_CODE_A_file ];then
	OFW_CODE_A=`cat $OFW_CODE_A_file`
   else
	OFW_CODE_A="File $OFW_CODE_A_file does not exist !"
   fi

   if [ -f $OFW_CODE_B_file ];then
	OFW_CODE_B=`cat $OFW_CODE_B_file`
   else
	OFW_CODE_B="File $OFW_CODE_B_file does not exist !"
   fi
if [ $KERNEL_CPU == x86_64 ]; then
	BIOS_VERSION=`dmidecode -s bios-version`
	BIOS_VERSION=`echo $BIOS_VERSION | cut -c3-16`
	BIOS_RELEASE_DATE=`dmidecode -s bios-release-date`
	version=`dmidecode -t 11 | grep BaseBoard`
	set -- $version
	BMC_VERSION=$7
	BMC_VERSION=`echo $BMC_VERSION | cut -c3-`
	
fi

}                                               

###################################################################
# Board information
###################################################################
Board_info()
{

    if [ -f $BOARD_VERSION_file ];then
	BOARD_VERSION=`cat $BOARD_VERSION_file`
    else
	BOARD_VERSION="unknown"
    fi

}


###################################################################
# display the South Bridge information
###################################################################
SouthBridge_info()
{
   if [ -f $FPGA_OB1_file ];then
	# version=`cat $FPGA_OB1_file`
	version=`xxd  -g1 -s 3 -l 1 /proc/device-tree/openprom/ibm,ob1-vernum_encoded`
	set -- $version
	FPGA_OB1=$2
   else
	FPGA_OB1="unknown"
   fi

   if [ -f $FPGA_R2D2_file ];then
	# version=`cat $FPGA_R2D2_file`
	version=`xxd  -g1 -s 3 -l 1 /proc/device-tree/openprom/ibm,r2d2-vernum_encoded`
	set -- $version
	FPGA_R2D2=$2
   else
	FPGA_R2D2="unknown"
   fi

   if [ -f $AXON_VERSION_file ];then
	AXON_VERSION=`cat $AXON_VERSION_file`
	if [ "$AXON_VERSION" = "$AXON_VERSION_JTAG_ID_V1_1" ]; then
		AXON_VERSION=`echo -n "1.1 "; echo -n "("; cat $AXON_VERSION_file; echo ")"`
	elif [ "$AXON_VERSION" = "$AXON_VERSION_JTAG_ID_V2_x" ]; then
		AXON_VERSION=`echo -n "2.x "; echo -n "("; cat $AXON_VERSION_file; echo ")"`
	elif [ "$AXON_VERSION" = "$AXON_VERSION_JTAG_ID_V3_0" ]; then
		AXON_VERSION=`echo -n "3.0 "; echo -n "("; cat $AXON_VERSION_file; echo ")"`
	fi
   else
	AXON_VERSION="unknown"
   fi

}

###################################################################
# display the current Linux kernel and hostname
###################################################################
Linux-distribution_info()
{
    if [ -f $LINUX_DIST_file ];then
        boot=`cat $LINUX_DIST_file`
        set -- $boot
        LINUX_DISTRIBUTION="$1 $2 $3 $4 $5"
    else
        LINUX_DISTRIBUTION="unknown"
    fi
}

###################################################################
# Information for device driver
###################################################################
DD_info()
{
    SYS_NAME="unknown"

    OFW_MODEL_file="/proc/device-tree/model"
    OFW_VERSION="unknown"
    OFW_BOOT_SIDE="unknown"
    OFW_CODE_A="unknown"
    OFW_CODE_B="unknown"
    OFW_BOOT_DEVICE_file="/proc/device-tree/openprom/device_type"
    OFW_VERSION_file="/proc/device-tree/openprom/ibm,fw-vernum_encoded"
    OFW_BOOT_SIDE_file="/proc/device-tree/openprom/ibm,fw-bank"
    OFW_CODE_A_file="/proc/device-tree/openprom/ibm,fw-temp-bank"
    OFW_CODE_B_file="/proc/device-tree/openprom/ibm,fw-perm-bank"
    OFW_H8_VERSION_file="/proc/device-tree/openprom/ibm,sp-vernum_encoded"
    FPGA_OB1_file="/proc/device-tree/openprom/ibm,ob1-vernum_encoded"
    FPGA_R2D2_file="/proc/device-tree/openprom/ibm,r2d2-vernum_encoded"
    AXON_VERSION_file="/proc/device-tree/openprom/ibm,axon-vernum_encoded"
    AXON_VERSION_JTAG_ID_V1_1="0a502049"
    AXON_VERSION_JTAG_ID_V2_x="2a502049"
    AXON_VERSION_JTAG_ID_V3_0="3a502049"
    BOARD_VERSION_file="/proc/device-tree/openprom/ibm,board-revision_encoded"
    AXON_PAGE_SIZE_FILE="/sys/class/axon/axon0/dd_page_size"


    LINUX_KERNEL="unknown"
    LINUX_HOST="unknown"
    LINUX_BC_NAME="unknown"
    LINUX_BC_DRIVER="unknown"
    LINUX_BC_file="/proc/net/nicinfo/eth0.info"
    MEMORY_file="/proc/meminfo"
    CPU_file="/proc/cpuinfo"
    LINUX_DIST_file="/etc/issue"

    System_info			        # collect system information
    H8_info				# collect H8 information
    Firmware_info			# collect current firmware version
    Board_info			        # collect board version 
    SouthBridge_info                    # collect SouthBridhe version information
    Linux-distribution_info		# collect Linux information
    Axon_driver_info		        # collect axon and apnet driver version

    echo " "
    echo "The following data was collect at $CURRENT_DATE for the $LINUX_HOST System"
    echo " "
    echo "System Name:                  $SYS_NAME"
    echo "Model:                        $OFW_MODEL"
    echo "Installed Memory:             $SYS_MEMORY"
    echo "Page size:                    $PAGE_SIZE"
    echo "Installed CPU:                $SYS_CPU"
    echo "CPU Frequency:                $CPU_FREQ"
    echo "CPU Revision:                 $CPU_REVISION"
    echo "Time base:                    $OFW_TIMEBASE"

    echo " "

    if [ $KERNEL_CPU == ppc64 ]; then 
        echo "Board version:                $BOARD_VERSION" 
#  echo "FPGA OB1 version:             $FPGA_OB1"
#  echo "FPGA R2D2 version:            $FPGA_R2D2"
        echo "AXON version:                 $AXON_VERSION"
        echo "Axon driver page size:        $AXON_DRIVER_PAGE_SIZE"

        echo " "
        echo "H8 FW Version:                $OFW_H8_VERSION"
        echo "OFW boot device type:         $OFW_BOOT_DEVICE"
        echo "OFW version number:           $OFW_VERSION"
        echo "OFW boot side:                $OFW_BOOT_SIDE"
        echo "OFW boot code side A:         $OFW_CODE_A"
        echo "OFW boot code side B:         $OFW_CODE_B"
    fi

    if [ $KERNEL_CPU == x86_64 ]; then 
        echo "BIOS Version:                 $BIOS_VERSION"
        echo "BIOS Release Date:            $BIOS_RELEASE_DATE"
        echo "BMC Version:                  $BMC_VERSION"
    fi

    echo " "
    echo "RTC date:                     $RTC_CLOCK"
    echo "Linux system date:            $LINUX_DATE"
    echo "Linux Distribution            $LINUX_DISTRIBUTION"
    echo "Linux host:                   $LINUX_HOST"
    echo "Linux kernel name:            $LINUX_KERNEL_NAME"
    echo "Linux kernel release:         $LINUX_KERNEL_RELEASE"
    echo "Linux kernel version:         $LINUX_KERNEL_VERSION"
    echo "Kernel command line:          $KERNEL_CMD_LINE"

    echo " "

    echo "Axon driver version:          $AXON_DRIVER_VERSION"
    echo "Apnet driver version:         $APNET_DRIVER_VERSION"
    echo "Axon driver page size:        $AXON_DRIVER_PAGE_SIZE"
}


###################################################################
# list ident or symlink information about libraries
###################################################################
lib_info()
{
    if test -L $1; then 
        deref=`$readlink -nf $1`
        echo "$f:"
        echo "     Symbolic link to $deref"
        if ! test -e $deref; then
            printf "ERROR: Symbolic link is broken.\n"
            broken_symlinks=1
        fi
    else
        ident $1 
    fi 
}

###################################################################
# check for hdacsd and adacsd errors
###################################################################
daemon_checks()                 # arg is "hdacsd" or "adacsd"
{
    local -i error=0
    echo "Checking DaCS daemon $1"
    daemon_running=`ps -eo comm | grep $1` # is the specified daemon running?
    if [ "$daemon_running" != "$1" ]; then
        printf "ERROR: DaCS daemon $1 is not running.\n"
        while true ; do
            read -n 1 -p "  Start $1 now?  [y/n] " DSTART
            echo
            if [ "$DSTART" = "y" -o "$DSTART" = "Y" ] ; then
                printf "Attempting restart.\n"
                temp=`/sbin/service $1 start`
                `sleep 2`  # Wait for deamon process to go away if there is a failure
                daemon_running=`ps -eo comm | grep $1`
                if [ "$daemon_running" != "$1" ]; then
                    printf "ERROR: DaCS daemon $1 failed to start.\n"
                    error=1
                else
                    printf "Start of DaCS daemon $1 complete\n"
                fi
                break
            else
                if [ "$DSTART" = "n" -o "$DSTART" = "N" ] ; then
                    break
                else
                    printf "Valid entries are \"y\" or \"n\" \n"          
                fi
            fi
        done
    else
        echo "DaCS daemon $1 is running"
    fi
    
    if [ "$error" != "0" ]; then
        if test -e "/var/log/$1.log" ; then              # does daemon exist?
            printf "Listing recent daemon_error messeges from the log file /var/log/$1.log\n"
            printf "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
            grep -G \([WECAU]\) /var/log/$1.log | tail -20 
            printf "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
        else
            printf "Cannot find /var/log/$1.log to look for daemon_error messages!\n"
        fi
    fi
    let daemon_error=$daemon_error+$error
}


# -----------------------------------------------------------------------------
# Parse command line arguments to determine host or accl
# -----------------------------------------------------------------------------
if [ ! -n "$1" ]; then          # no arguments
    if [ "$MACH_ARCH" = "x86_64" ] ; then
        host_element=1
        accl_element=0
    elif [ "$MACH_ARCH" = "ppc64" ] ; then
        host_element=0
        accl_element=1
    else
        printf "ERROR: DACS Hybrid software is only supported on x86_64 or ppc64  Machine Architectures.\n"
        exit 1
    fi
else          
    while [ -n "$1" ]; do       # parse arguments
        if [ "$1" = "--host" ]; then
            host_element=1
        elif [ "$1" = "--accl" ]; then
            accl_element=1
        elif [ "$1" = "--help" -o "$1" = "-h" ]; then
            echo "usage: $0 [--host] [--accl] [--help|-h]"
            exit 1
        else
            echo "unrecognized argument: $1"
            echo "usage: $0 [--host] [--accl] [--help|-h]"
            exit 1
        fi
        shift
    done
fi

# -----------------------------------------------------------------------------
# Gather environment informantion:
# -----------------------------------------------------------------------------
dacsh=/usr/include/dacs.h
hdacsdlog=/var/log/hdacsd.log
adacsdlog=/var/log/adacsd.log
dacsconfig=/etc/dacsd.conf
dacstopology=/etc/dacs_topology.config
ipaddresses=`/sbin/ifconfig | grep "inet addr" | cut -f2 -d: | awk '{print $1}'`


printf "*************************************************************\n"
printf "Displaying initial system information:\n"
printf "*************************************************************\n"
DD_info 
echo "Apnet driver version:         $APNET_DRIVER_VERSION"
echo "Machine Architecture          $MACH_ARCH"
if test -e "$dacsh" ; then      #does dacs.h exist on hybrid?
    echo "dacs.h                        $dacsh"
else
    echo "dacs.h                        no"
fi

topology=""
if test -e "$dacsconfig" ; then #does the config file exist?
    echo "dacsd.conf                    $dacsconfig"
    topology=`cat /etc/dacsd.conf | grep dacs_topology_config=`
    topology="${topology#dacs_topology_config=}"
    dacstopology=$topology
else
    echo "dacsd.conf                    no"
    printf "======================================================= \n"
    printf "ERROR:  Cannot run without valid dacsd.conf file.       \n"
    printf "        Make sure you have a valid /etc/dacsd.conf file.\n"
    printf "======================================================= \n"
    missing_file=1
fi
if test -e "$topology"  ; then
    dacstopology=$topology
fi
if test -e "$dacstopology" ; then       #does the topology file exist?
    echo "dacs_topology.config          $dacstopology"
else
    echo "dacs_topology.config          no"
    printf "================================================================= \n"
    printf "ERROR:  Cannot run without valid dacs topology configuration file.\n"
    printf "        Make sure the dacs_topology_config variable in the        \n"
    printf "        /etc/dacsd.conf file points to a valid DaCs topology file.\n"
    printf "================================================================= \n"
    missing_file=1
fi
printf "LD_LIBRARY_PATH = $LD_LIBRARY_PATH\n"
printf "\n"

printf "*************************************************************\n"
printf "DaCS Hybrid Log Files:\n"
printf "*************************************************************\n"
ls -l /tmp/dlog_*.log 2>/dev/null
ls -l /var/log/hdacsd.log* 2>/dev/null
ls -l /var/log/adacsd.log* 2>/dev/null
printf "\n"
printf "*************************************************************\n"
printf "List of installed DaCS RPMs:\n"
printf "*************************************************************\n"
RPMS=`rpm -qa | grep dacs`
printf "$RPMS\n"
printf "*************************************************************\n"
printf "Running RPM verify against installed DaCS RPMs ...\n"
printf "To understand any output please read the Verifiy Option section of the rpm manpage\n"
rpm -V $RPMS
printf "*************************************************************\n"
printf "ident Information on DaCS libraries:                         \n"
printf "*************************************************************\n"
printf "ident information on DaCS libraries in: usr/lib64\n"
for f in `ls /usr/lib64/libdacs_*`; do lib_info $f; done
printf "=============================================================\n"
printf "ident information on DaCS libraries in: /usr/lib64/dacs/debug\n"
for f in `ls /usr/lib64/dacs/debug/*`; do lib_info $f; done
printf "=============================================================\n"
printf "ident information on DaCS libraries in: /usr/lib64/dacs/trace\n"
for f in `ls /usr/lib64/dacs/trace/*`; do lib_info $f; done
printf "=============================================================\n"
printf "ident information on DaCS libraries in: /usr/lib\n"
for f in `ls /usr/lib/libdacs_*`; do lib_info $f; done
printf "=============================================================\n"
printf "ident information on DaCS libraries in: /usr/lib/dacs/debug\n"
for f in `ls /usr/lib/dacs/debug/*`; do lib_info $f; done
printf "=============================================================\n"
printf "ident information on DaCS libraries in: /usr/lib/dacs/trace\n"
for f in `ls /usr/lib/dacs/trace/*`; do lib_info $f; done
printf "*************************************************************\n\n"

printf "*************************************************************\n"
printf "List of installed Datamover RPMs:\n"
printf "*************************************************************\n"
RPMS=`rpm -qa | grep datamover`
printf "$RPMS\n"
printf "*************************************************************\n"
printf "Running RPM verify against installed Datamover RPMs ...\n"
printf "To understand any output please read the Verifiy Option section of the rpm manpage\n"
rpm -V $RPMS
printf "*************************************************************\n"
printf "ident Information on Datamover libraries:                    \n"
printf "*************************************************************\n"
printf "ident information on Datamover libraries in: usr/lib64\n"
for f in `ls /usr/lib64/libdm_*`; do lib_info $f; done
printf "=============================================================\n"
printf "ident information on Datamover libraries in: /usr/lib64/datamover/debug\n"
for f in `ls /usr/lib64/datamover/debug/*`; do lib_info $f; done
printf "=============================================================\n"
printf "ident information on Datamover libraries in: /usr/lib\n"
for f in `ls /usr/lib/libdm_*`; do lib_info $f; done
printf "=============================================================\n"
printf "ident information on Datamover libraries in: /usr/lib/datamover/debug\n"
for f in `ls /usr/lib/datamover/debug/*`; do lib_info $f; done
printf "*************************************************************\n\n"

printf "*************************************************************\n"
printf " DaCS Daemon Checks:\n"
printf "*************************************************************\n"
if [ "$host_element" = "1" ]; then
    if test -e "$dacstopology" ; then
        printf "Validating topology file $dacstopology\n"
        dacs-hybrid-topology-validate $dacstopology
    fi
    daemon_checks "hdacsd"
    if [ "$daemon_error" = "0" ]; then
        printf "Checking the availability of the accelerators\n"
        dacs-hdacsd-check-availability
    fi
fi
if [ "$accl_element" = "1" ]; then
    daemon_checks "adacsd"
fi

if [ $my_euid != 'root' ]; then
    printf "*************************************************************\n"
    printf "WARNING:\tInformation may be incomplete\n"
    printf "\t\tRun this command as root or with sudo.\n"
    printf "*************************************************************\n"
fi

let error=$daemon_error+$broken_symlinks+$missing_file
if [[ $error -gt 0 ]]; then
    printf "Exiting with failures\n"
fi
exit $error
