#!/bin/sh
#
# USAGE: isinstalled [OPTIONS] package-name
#
# OPTIONS:
#   -h|--help              Show this help text
#   -l|--lib               The specified software is a dynamic library
#   -a|--alias    name     Alternative package name search for
#   -f|--file     name     Unqualified file name to look for 
#   -p|--print             Print the path to the found software file
#   -v|--version           With -p|--print, also print package version
#   -m|--min      version  Minimum required version
#   -M|--max      version  Maxium required version
#
# This utility is a wrapper around the package manager and various tools
# such as 'which'. Its purpose is to determine if a specified software is
# installed, and optionally to display the fully qualified path to the
# corresponding file.
#

TDBS_SBIN=`dirname $0 2>/dev/null`
if [ "$TDBS_SBIN" = "" ]; then
   if [ "$TDBS_HOME" = "" ]; then
      TDBS_LIB=`readlink /usr/local/trip/sys/lib 2>/dev/null`
      if [ "$TDBS_LIB" != "" ]; then
         TDBS_HOME=`dirname $TDBS_LIB 2>/dev/null`
         unset TDBS_LIB
      fi
   fi
   TDBS_SBIN=$TDBS_HOME/sbin
fi

OSNAME=`$TDBS_SBIN/ostype`
OSFAMILY=`$TDBS_SBIN/ostype --family`

if [ "$OSNAME" = "darwin" ]; then
   SOEXT=dylib
else
   SOEXT=so
fi

OPT_FIND_LIB=1
OPT_ALIAS=
OPT_FILE=
OPT_PRINT=1
OPT_PACKAGE=
OPT_VERSION=1
OPT_MINVER=
OPT_MAXVER=


while [ "$1" != "" ]; do
case "$1" in
        -h|--help)
                head -19 $0 | tail -18 | cut -c3-
                exit 0
                ;;
        -l|--lib)
                OPT_FIND_LIB=0
		;;
        -p|--print)
                OPT_PRINT=0
                ;;
        -a|--alias)
		shift
                OPT_ALIAS=$1
                ;;
        -f|--file)
		shift
                OPT_FILE=$1
                ;;
        -m|--min)
		shift
                OPT_MINVER=$1
                ;;
        -M|--max)
		shift
                OPT_MAXVER=$1
                ;;
        -v|--version)
                OPT_VERSION=0
                ;;
        *)
		if [ `echo $1|cut -c1` = "-" ]; then
                   echo "ERROR: Invalid argument: $1"
                   echo ""
                   head -17 $0 | tail -16 | cut -c3-
                   exit 99
                else
                   OPT_PACKAGE=$1
		fi
                ;;
esac
shift
if [ "$OPT_PACKAGE" != "" ]; then
   break
fi
done

if [ "$OPT_PACKAGE" = "" ] && [ "$OPT_FILE" = "" ]; then
   echo "ERROR: No package or file name specified"
   exit 1
fi

WHICH_CMD=`which which 2>/dev/null`
if [ "$WHICH_CMD" != "" ] && [ ! -f "$WHICH_CMD" ]; then
   # Handle case where "which" is wrapped in a system defined alias
   WHICH_CMD=which
fi

test_var()
{
   return $1
}

find_program()
{
   FINDPATH=
   if [ "$WHICH_CMD" != "" ]; then
      FINDPATH=`$WHICH_CMD $1 2> /dev/null`
   else
      if [ "$FINDPATH" = "" ] && [ -f /bin/$1 ]; then
         FINDPATH=/bin/$1
      fi
      if [ "$FINDPATH" = "" ] && [ -f /sbin/$1 ]; then
         FINDPATH=/sbin/$1
      fi
      if [ "$FINDPATH" = "" ] && [ -f /usr/local/bin/$1 ]; then
         FINDPATH=/usr/local/bin/$1
      fi
   fi
   if [ "$FINDPATH" != "" ]; then
      if test_var $OPT_PRINT ; then
         echo $FINDPATH
      fi
      return 0
   else
      return 1
   fi
}

find_library()
{
   FINDPATH=`find /usr/lib -type f -name "$1.$SOEXT*" 2>/dev/null`
   if [ "$FINDPATH" = "" ]; then
      FINDPATH=`find /usr/local/lib -type f -name "$1.$SOEXT*" 2>/dev/null`
   fi
   if [ "$FINDPATH" = "" ] && [ "$OSNAME" = "darwin" ]; then
      FINDPATH=`dyld_info -platform "/usr/lib/$1.$SOEXT" 2>/dev/null | head -n1 | cut -d" " -f1`
   fi
   if [ "$FINDPATH" != "" ]; then
      if test_var $OPT_PRINT ; then
         if test_var $OPT_VERSION ; then
            echo "$1: $FINDPATH"
         else
            echo $1
         fi
      fi
      return 0
   else
      return 1
   fi
}

RPM_CMD=

if [ "$OSNAME" = "linux" ]; then
   OPT_PRINT_SAV=$OPT_PRINT
   OPT_PRINT=0
   RPM_CMD=`find_program rpm`
   OPT_PRINT=$OPT_PRINT_SAV
fi


is_pkg_installed()
{
   pkgname=$1
   altpkg=$2
   pkgver=""
   foundpkg=$1

   # Use RPM to query installed packages (RHEL systems only)
   #
   if [ "$OSFAMILY" = "rhel" ] && [ "$RPM_CMD" != "" ]; then
      pkgver=`rpm --query --queryformat "%{VERSION}\n" $pkgname 2>/dev/null`
      if [ $? -ne 0 ]; then
         unset pkgver
         if [ "$altpkg" != "" ]; then
            pkgver=`rpm --query --queryformat "%{VERSION}\n" $altpkg 2>/dev/null`
            if [ $? -eq 0 ] && [ "$pkgver" != "" ]; then
               foundpkg=$altpkg
            else
               unset pkgver
            fi
         fi
      fi
   fi

   if [ "$OSNAME" = "linux" ]; then

      # Experimental and highly unofficial fallback for non-RHEL systems
      # 
      if [ "$pkgver" = "" ] && [ "$RPM_CMD" = "" ]; then

         find_program apt > /dev/null 2>&1
         if [ $? -eq 0 ]; then
            pkgfound=`apt list --installed $pkgname 2> /dev/null | grep ^$pkgname | grep -v ^Listing`
            if [ "$pkgfound" != "" ]; then
               pkgver=`apt show $pkgname 2>/dev/null | grep ^Version |cut -d: -f2-|awk '{print $1}'`
            else
               if [ "$altpkg" != "" ]; then
                  pkgfound=`apt list --installed $altpkg 2>/dev/null | grep ^$altpkg | grep -v ^Listing`
                  if [ "$pkgfound" != "" ]; then
                     pkgver=`apt show $altpkg 2>/dev/null | grep ^Version |cut -d: -f2-|awk '{print $1}'`
                     foundpkg=$altpkg
                  fi
               fi
            fi     
         fi

      fi

   fi

   if [ "$pkgver" != "" ]; then

      version_msg=""
      version_ok=0
      if [ "$OPT_MINVER" != "" ]; then
         if [[ "$pkgver" < "$OPT_MINVER" ]]; then
            version_msg="minimum version $OPT_MINVER"
            version_ok=1
         fi
      fi
      if [ "$OPT_MAXVER" != "" ]; then
         if [[ "$pkgver" > "$OPT_MAXVER" ]]; then
            if test_var $version_ok ; then
               version_msg="maximum version $OPT_MAXVER"
            fi
            version_ok=1
         fi
      fi

      if test_var $OPT_PRINT ; then
         if test_var $OPT_VERSION ; then
            if test_var $version_ok ; then
               echo "$foundpkg: $pkgver"
            else
               echo "$foundpkg: $pkgver (FAIL: requires $version_msg)"
            fi 
         else
            if test_var $version_ok ; then
               echo "$foundpkg"
            fi
         fi
      fi

      if test_var $version_ok ; then
         return 0
      else
         return 2
      fi
   else
      return 1
   fi
}

PKG_FOUND=1

if [ "$OPT_PACKAGE" != "" ]; then
   is_pkg_installed $OPT_PACKAGE "$OPT_ALIAS"
   PKG_FOUND=$?
   if test_var $PKG_FOUND ; then
      exit 0
   fi
fi

if [ "$OPT_FILE" != "" ]; then
   if test_var $OPT_FIND_LIB ; then
      find_library $OPT_FILE
      PKG_FOUND=$?
   else
      find_program $OPT_FILE
      PKG_FOUND=$?
   fi 
fi

exit $PKG_FOUND
