#!/usr/bin/env bash

function array.join {
  local IFS="$1"
  shift
  echo "$*"
}

# Loops until duration (car) is exceeded or command (cdr) returns non-zero
function timeout {
  local seconds timeout
  timeout="${1:?Pass a timeout as arg[1]}"
  interval="${interval:-1}"
  seconds=0
  shift
  ln=' ' logger.debug "${*} : Waiting until non-zero (max ${timeout} sec.)"
  while (eval "$*" 2>/dev/null); do
    seconds=$(( seconds + interval ))
    echo -n '.'
    sleep "$interval"
    [[ $seconds -gt $timeout ]] && echo '' \
      && logger.error "Time out of ${timeout} exceeded" \
      && return 71
  done
  [[ $seconds -gt 0 ]] && echo -n ' '
  echo 'done'
  return 0
}

function wait_for_file {
  local file timeout waits
  file="${1:?Pass a filepath as arg[1]}"
  waits="${2:-300}"

  timeout "${waits}" "[[ ! -f '${file}' ]]"
}

function versions.le {
  local v1 v2 cmp
  v1="${1:?Pass a version to check as arg[1]}"
  v2="${2:?Pass a version to check against as arg[2]}"
  cmp="$(echo -e "${v1}\n${v2}" | sort -V | head -n 1)"

  [ "${v1}" = "${cmp}" ]
}

function versions.ge {
  local v1 v2 cmp
  v1="${1:?Pass a version to check as arg[1]}"
  v2="${2:?Pass a version to check against as arg[2]}"
  cmp="$(echo -e "${v1}\n${v2}" | sort -V | tail -n 1)"

  [ "${v1}" = "${cmp}" ]
}

function versions.lt {
  local v1 v2
  v1="${1:?Pass a version to check as arg[1]}"
  v2="${2:?Pass a version to check against as arg[2]}"

  if ! [ "${v1}" = "${v2}" ]; then
    return 1
  fi

  versions.le "${v1}" "${v2}"
}

# Returns the major and minor part of the whole version, joined with a dot.
function versions.major_minor {
  local version=${1:?Pass a full version as arg[1]}
  # shellcheck disable=SC2001
  # Ref: https://regex101.com/r/Po1HA3/1
  echo "${version}" | sed 's/^v\?\([[:digit:]]\+\)\.\([[:digit:]]\+\).*/\1.\2/'
}

# Returns the major part of the whole version.
function versions.major {
  local version=${1:?Pass a full version as arg[1]}
  # shellcheck disable=SC2001
  echo "${version}" | sed 's/^v\?\([[:digit:]]\+\).*/\1/'
}

# Returns the minor part of the whole version.
function versions.minor {
  local version=${1:?Pass a full version as arg[1]}
  # shellcheck disable=SC2001
  echo "${version}" | sed 's/^v\?\([[:digit:]]\+\)\.\([[:digit:]]\+\).*/\2/'
}

# Returns the micro part of the whole version.
function versions.micro {
  local version=${1:?Pass a full version as arg[1]}
  # shellcheck disable=SC2001
  echo "${version}" | sed 's/^v\?\([[:digit:]]\+\)\.\([[:digit:]]\+\)\.\([[:digit:]]\+\).*/\3/'
}

# Breaks all image references in the passed YAML file.
function yaml.break_image_references {
  sed -i "s,image: .*,image: TO_BE_REPLACED," "$1"
  sed -i "s,value: gcr.io/knative-releases.*,value: TO_BE_REPLACED," "$1"
}

function should_run {
  local ts
  ts=${1:?Specify test to check}

  if [ -n "$OPENSHIFT_CI" ]; then
    [ -f "${ARTIFACT_DIR}/tests.txt" ] || return 0
    grep -q -e "All" -e "$ts" "${ARTIFACT_DIR}/tests.txt" || return 1
  else
    return 0
  fi
}

function ensure_catalog_pods_running {
  # Ensure the catalog source pods are running correctly
  # to avoid https://issues.redhat.com/browse/OCPBUGS-31391.
  if oc -n "$OLM_NAMESPACE" get pods -l olm.catalogSource=certified-operators | grep CrashLoopBackOff &>/dev/null; then
    oc -n "$OLM_NAMESPACE" delete pods -l olm.catalogSource=certified-operators
    timeout 120 "[[ \$(oc -n $OLM_NAMESPACE get pods -l olm.catalogSource=certified-operators | grep Running | wc -l) != 1 ]]"
  fi
  if oc -n "$OLM_NAMESPACE" get pods -l olm.catalogSource=community-operators | grep CrashLoopBackOff &>/dev/null; then
    oc -n "$OLM_NAMESPACE" delete pods -l olm.catalogSource=community-operators
    timeout 120 "[[ \$(oc -n $OLM_NAMESPACE get pods -l olm.catalogSource=community-operators | grep Running | wc -l) != 1 ]]"
  fi
  if oc -n "$OLM_NAMESPACE" get pods -l olm.catalogSource=redhat-operators | grep CrashLoopBackOff &>/dev/null; then
    oc -n "$OLM_NAMESPACE" delete pods -l olm.catalogSource=redhat-operators
    timeout 120 "[[ \$(oc -n $OLM_NAMESPACE get pods -l olm.catalogSource=redhat-operators | grep Running | wc -l) != 1 ]]"
  fi
  if oc -n "$OLM_NAMESPACE" get pods -l olm.catalogSource=redhat-marketplace | grep CrashLoopBackOff &>/dev/null; then
    oc -n "$OLM_NAMESPACE" delete pods -l olm.catalogSource=redhat-marketplace
    timeout 120 "[[ \$(oc -n $OLM_NAMESPACE get pods -l olm.catalogSource=redhat-marketplace | grep Running | wc -l) != 1 ]]"
  fi
}

function array.reverse() {
  # First argument is the array to reverse. Second is the output array.
  declare -n arr="$1" rev="$2"
  for i in "${arr[@]}"
  do
    rev=("$i" "${rev[@]}")
  done
}
