#!/bin/sh
#
# USAGE: dependencies_cof_sh [OPTIONS]
#
# OPTIONS:
#    -h|--help      Show this help text
#    -c|--check     Check if required dependencies are installed
#    -i|--install   Install any missing required dependencies (Linux only)
#
# This script checks and optionally installs software packages that TRIPcof
# is depending on. Package installation via this script is only supported on 
# RedHat Enterprise Linux 8 and binary compatible distributions.
# 

PKGMGR=
OPMODE=c
FROM_INSTALLER=1
INSTALLED_PKGS_LIST=""


case "$1" in 
	-h|--help)
		head -13 $0 | tail -12 | cut -c3-
		exit 0
		;;
	-i|--install)
		OPMODE=i
		;;
	-c|--check|"")
		OPMODE=c
		;;
	*)
		echo "ERROR: Invalid argument: $1"
		echo ""
		head -10 $0 | tail -9 | cut -c3-
		exit 99
		;;
esac

if [ "$2" = "--from-installer" ]; then
  FROM_INSTALLER=0
fi

OSNAME=`uname`
if [ "$OSNAME" != "Linux" ] && [ "$OPMODE" = "i" ]; then
   echo "ERROR: Dependency installation is only supported on Linux."
   echo ""
   exit 99
fi

TDBS_LIB=`readlink -f /usr/local/trip/sys/lib 2>/dev/null`
TDBS_HOME=`dirname $TDBS_LIB 2>/dev/null`
if [ "$TDBS_HOME" = "" ] || [ ! -f "$TDBS_HOME/sbin/isinstalled" ]; then
   echo "ERROR: Unable to locate the TRIPsystem 'isinstalled' script."
   echo ""
   exit 99
fi
TDBS_SBIN=$TDBS_HOME/sbin

is_installed()
{
   pkgname=$1
   swname=$2
   altpkg=$3
   minver=$4
   minarg=

   if [ "$minver" != "" ]; then
      minarg="-m $minver"
   fi

   $TDBS_SBIN/isinstalled $minarg --alias "$altpkg" --print --version $pkgname
   isinst_rc=$?
   if [ $isinst_rc -eq 2 ]; then
      return 2
   fi
   if [ $isinst_rc -eq 0 ]; then
      return 0
   fi

   $TDBS_SBIN/isinstalled --file $pkgname --print
   if [ $? -eq 0 ]; then
      return 0
   fi

   if [ "$swname" != "" ]; then
      $TDBS_SBIN/isinstalled --file $swname --print
      if [ $? -eq 0 ]; then
         return 0
      fi
   fi

   return 1
}

is_lib_installed()
{
   pkgname=$1
   libname=$2
   altpkg=$3

   $TDBS_SBIN/isinstalled --alias "$altpkg" --print --version $pkgname
   if [ $? -eq 0 ]; then
      return 0
   fi

   if [ "$libname" != "" ]; then
      $TDBS_SBIN/isinstalled --lib --file $libname --print
      if [ $? -eq 0 ]; then
         return 0
      fi
   fi

   $TDBS_SBIN/isinstalled --lib --file $pkgname --print
   if [ $? -eq 0 ]; then
      return 0
   fi

   return 1
}


OSFAMILY=`$TDBS_SBIN/ostype --family`
if [ "$OSNAME" = "Linux" ]; then
   if [ "$OSFAMILY" = "rhel" ]; then
      if is_installed dnf >/dev/null 2>&1; then
         PKGMGR=dnf
      elif is_installed microdnf >/dev/null 2>&1; then
         PKGMGR=microdnf
      elif is_installed yum >/dev/null 2>&1; then
         PKGMGR=yum
      fi
   elif [ "$OSFAMILY" = "debian" ]; then
      if is_installed apt >/dev/null 2>&1; then
         PKGMGR=apt
         INFOCMD=show
      fi
   fi
   if [ "$PKGMGR" = "" ]; then
      echo "WARNING: No supported package manager found."
      echo ""
   fi
fi

OSVER_MAJOR=`$TDBS_SBIN/ostype --version`

IS_RHEL10=0
if [ "$OSFAMILY" = "rhel" ]; then
   if [ "$OSVER_MAJOR" != "" ]; then
      if [ $OSVER_MAJOR -ge 10 ]; then
         IS_RHEL10=1
      fi
   fi
fi


MISSING=0
PKGLIST=""

echo "Checking for presence of prerequisite software ..."
echo ""

if ! is_installed bash ; then
   MISSING=`expr $MISSING + 1`
   PKGLIST="$PKGLIST bash"
fi

if ! is_installed "sed" ; then
   MISSING=`expr $MISSING + 1`
   PKGLIST="$PKGLIST sed"
fi

if [ "$OSNAME" = "Darwin" ]; then
   if ! is_lib_installed libc++ libc++.1 "" ; then
      MISSING=`expr $MISSING + 1`
      PKGLIST="$PKGLIST libc++"
   fi
else
   if ! is_lib_installed libstdc++ "" libstdc++6 ; then
      MISSING=`expr $MISSING + 1`
      PKGLIST="$PKGLIST libstdc++"
   fi
fi

if ! is_installed gawk awk ; then
   MISSING=`expr $MISSING + 1`
   PKGLIST="$PKGLIST gawk"
fi

if ! is_installed binutils strings ; then
   MISSING=`expr $MISSING + 1`
   PKGLIST="$PKGLIST binutils"
fi

if ! is_installed procps ps procps-ng; then
   MISSING=`expr $MISSING + 1`
   PKGLIST="$PKGLIST procps"
fi

if ! is_installed file ; then
   MISSING=`expr $MISSING + 1`
   PKGLIST="$PKGLIST file"
fi

EXTRA_LIB_CHECK=0
if [ "$OSNAME" = "Linux" ]; then

   EXTRA_LIB_CHECK=1
   if [ "$OSFAMILY" = "rhel" ]; then
      if [ "$OSVER_MAJOR" != "" ]; then
         if [ $OSVER_MAJOR -lt 8 ]; then
            EXTRA_LIB_CHECK=0
         fi
      fi
   fi

fi

if [ $EXTRA_LIB_CHECK -eq 1 ]; then
   openssl_minver=
   if [ "$OSNAME" = "Linux" ]; then
      openssl_minver=3
   fi

   if ! is_installed openssl "" "" $openssl_minver ; then
      MISSING=`expr $MISSING + 1`
      PKGLIST="$PKGLIST openssl"
   fi

   if ! is_lib_installed libcurl libcurl libcurl4 ; then
      # Allow minmal package if present
      if ! is_lib_installed libcurl-minimal libcurl libcurl4 ; then
         MISSING=`expr $MISSING + 1`
         if [ "$PKGMGR" = "apt" ]; then
            PKGLIST="$PKGLIST libcurl4"
         else
            PKGLIST="$PKGLIST libcurl"
         fi
      fi
   fi

   if ! is_lib_installed zlib libz zlib1g ; then
      # RHEL 10 provides zlib-ng instead of the original one
      if ! is_lib_installed zlib-ng-compat ; then
         MISSING=`expr $MISSING + 1`
         if [ "$PKGMGR" = "apt" ]; then
            PKGLIST="$PKGLIST zlib1g"
         else
            if [ $IS_RHEL10 -eq 1 ]; then
               PKGLIST="$PKGLIST zlib-ng-compat"
            else
               PKGLIST="$PKGLIST zlib"
            fi
         fi
      fi
   fi
fi

# Java may be installed in a wide variety of ways. So instead of checking 
# for a specific package, check if a Java environment is available at all.
java -version > /dev/null 2>&1
if [ $? -eq 0 ]; then 
   echo "java: `java -version 2>&1 | head -n1`"
else
   MISSING=`expr $MISSING + 1`
   if [ "$PKGMGR" = "apt" ]; then
      PKGLIST="$PKGLIST openjdk-8-jre-headless"
   else
      PKGLIST="$PKGLIST java-17-openjdk-headless"
   fi
fi 

if [ $MISSING -eq 0 ]; then
   echo ""
   echo "Good news! All prerequisites are already installed."
   echo ""
else
   if [ "$OPMODE" != "i" ]; then
      echo ""
      if [ $MISSING -eq 1 ]; then
         echo "There is one missing package:"
      else
         echo "There are $MISSING missing packages:"
      fi
      echo $PKGLIST | tr ' ' '\n' | while read pkg; do echo "   $pkg"; done
      echo ""
      if [ $FROM_INSTALLER -eq 1 ]; then
         echo "Please install the missing dependencies and try again."
         echo ""
      fi
   fi
fi

if [ "$OPMODE" = "c" ]; then
   exit $MISSING
fi


if [ "$OPMODE" = "i" ] && [ $MISSING -gt 0 ]; then

   echo ""
   echo "Installing missing prerequisites:"
   echo $PKGLIST | tr ' ' '\n' | while read pkg; do echo "   $pkg"; done
   echo ""
   $PKGMGR install $PKGLIST
   RETVAL=$?

   echo ""
   if [ $RETVAL -eq 0 ]; then
      echo "Good news! Installation of prerequisite software succeeded."  
   else
      echo "ERROR: Dependency installation failed."
      RETVAL=99
   fi
   echo ""

   exit $RETVAL

fi

