#!/usr/bin/bash
#
# DESCRIPTION
# -----------
# This script resolves dependencies of the given beakerlib libraries installed
# in BEAKER_LIBRARY_PATH. Dependencies are resolved from Makefiles which
# contains Requires and RhtsRequires fields specifying RPM dependencies.
#
# RhtsRequires are mandatory RPM requirements that need to be installed before
# running the test.
#
# Requires are optional RPM requirements that the harness should try to install
# on the system-under-test (SUT), but they are not mandatory.
#
# RETURNS
# -------
# After the script finishes, it prints two lines, with space delimited list of
# components from RhtsRequires and Requires.
#
# BEAKERLIB_LIBRARY_PATH - path with the libraries
#
# AUTHORS
# -------
#  Jakub Heger <jheger@redhat.com>
#  Martin Kyral <mkyral@redhat.com>
#  Miroslav Vadkerti <mvadkert@redhat.com>
#  Andrei Stepanov <astepano@redhat.com>
#

PROG="${PROG:-${0##*/}}"
[ -z "$BEAKERLIB_LIBRARY_PATH" ] && BEAKERLIB_LIBRARY_PATH="/mnt/libraries"

function print_info() {
    printf ":: %s\n" "$@"
}

function print_error() {
    printf "Error: %s\n" "$@"
}

function exit_error() {
    print_error "$@"
    exit 1
}

function help() {
cat <<EOF
    usage: $PROG [-ih] TEST_PATH

    Output 2 lines, each of them is list of RPMS:

        RhtsRequires -- hard requirements
        Requires -- soft requirements

    Options:
      -i         Install requirements.
      -h         Print this help.

    Notes:
      This script will fail if not able to install package from RhtsRequires.

EOF
}


# ENTER

OPTS="hi"
DO_INSTALL=
while getopts $OPTS OPTION
do
  case $OPTION in
    i)
       DO_INSTALL=yes
       shift
       ;;
    h)
       help
       exit
       ;;
  esac
done

TEST="$1"
[ -z "$TEST" ] && exit_error "No test specified"
[ -f "$TEST/Makefile" ] || exit 0

REQUIRES_DEPS=
RHTSREQUIRES_DEPS=
PROCESSED_LIBS=

#
# Process a beakerlib library and recursively resolve it's dependencies.
#
# Params:
# $1 - library name - e.g. httpd/http
#
function process_library() {
  # skip already processed beakerlib libraries
  grep -wq "$1" <<< "$PROCESSED_LIBS" && return
  PROCESSED_LIBS="$PROCESSED_LIBS $1"

  local COMPONENT=${1///*}
  local LIBRARY=${1##*/}

  # check if library exists
  libdir=
  if [ -d "${BEAKERLIB_LIBRARY_PATH}/$COMPONENT/Library/$LIBRARY" ]; then
    libdir="${BEAKERLIB_LIBRARY_PATH}/$COMPONENT/Library/$LIBRARY"
  elif [ -d "${BEAKERLIB_LIBRARY_PATH}/$COMPONENT/$LIBRARY" ]; then
    libdir="${BEAKERLIB_LIBRARY_PATH}/$COMPONENT/$LIBRARY"
  else
    print_error "Could not find library '$1' in '$BEAKERLIB_LIBRARY_PATH'"
    return
  fi

  resolve_deps "$libdir"
}

#
# Recursively resolves test dependencies of beakerlib test specified with a path.
#
# Params:
# $1 - path to a beakerlib test
#
function resolve_deps() {
  local REQUIRES=$(sed -n 's/^[^#]*\"Requires:[[:space:]]*\(.*\)".*/\1/Ip' "$1/Makefile")
  local RHTSREQUIRES=$(sed -n 's/^[^#]*RhtsRequires:[[:space:]]*\(.*\)".*/\1/Ip' "$1/Makefile")

  for REQ in $REQUIRES; do
    if egrep -qv '^\$\(' <<< "$REQ"; then
      REQUIRES_DEPS="$REQUIRES_DEPS $REQ"
    fi
  done

  for RHTSREQ in $RHTSREQUIRES; do
    if egrep -q "^library\(" <<< "$RHTSREQ"; then
      process_library $(sed 's/library(\(.*\))/\1/' <<< "$RHTSREQ")
    elif egrep -qv '^\$\(' <<< "$RHTSREQ"; then
      RHTSREQUIRES_DEPS="$RHTSREQUIRES_DEPS $RHTSREQ"
    fi
  done
}

resolve_deps "$TEST"

RHTSREQUIRES_DEPS="$(echo "$RHTSREQUIRES_DEPS" | xargs -n1 | sort | uniq | tr '\n' ' ')"
REQUIRES_DEPS="$(echo "$REQUIRES_DEPS" | xargs -n1 | sort | uniq | tr '\n' ' ')"

echo "$RHTSREQUIRES_DEPS"
echo "$REQUIRES_DEPS"

if [ -z "$DO_INSTALL" ]; then
  exit
fi

YUM=
if [ -x "/usr/bin/yum" ]; then
  YUM=yum
elif [ -x "/usr/bin/dnf" ]; then
  YUM=dnf
fi

if [ -n "$YUM" ]; then
  # Hard req
  if [ -n "${RHTSREQUIRES_DEPS## }" ]; then
    $YUM install -y $RHTSREQUIRES_DEPS || exit 1
  fi

  # Soft req
  if [ -n "${REQUIRES_DEPS## }" ]; then
    $YUM install -y --skip-broken $REQUIRES_DEPS || :
  fi
elif [ -x "/usr/bin/rpm-ostree" ]; then
  # Hard req
  if [ -n "${RHTSREQUIRES_DEPS## }" ]; then
    rpm-ostree install -y $RHTSREQUIRES_DEPS || exit 1
  fi

  # Soft req
  if [ -n "${REQUIRES_DEPS## }" ]; then
    rpm-ostree install -y $REQUIRES_DEPS || :
  fi

  # Apply changes
  if [ -n "${RHTSREQUIRES_DEPS## }${REQUIRES_DEPS## }" ]; then
    rpm-ostree ex livefs
  fi
else
  echo "Cannot guess package manager."
  exit 1
fi

# vim: ts=2 sw=2 sts=2 ft=sh et ai:
