#!/usr/bin/env bash
set -euo pipefail

POSTINST_PATH="omnibus/package-scripts/cinc-workstation/postinst"

extract_binaries() {
  sed -n 's/^binaries="\(.*\)"/\1/p' "${POSTINST_PATH}" | head -n 1
}

first_non_empty_line() {
  awk 'NF { print; exit }'
}

preferred_version_line() {
  awk 'NF && $0 !~ /^\[[^]]+\] WARN:/ && $0 !~ /^WARN:/ && $0 !~ /^ERROR:/ && $0 !~ /^Invalid mode:/ && $0 !~ /^Usage:/ && $0 !~ /^Docs:/ && $0 !~ /^Website:/ && $0 !~ /^Welcome to / && $0 !~ /^The Cinc command line tool/ { print; exit }'
}

print_version_output() {
  local binary="$1"
  local output=""
  local args=()

  case "${binary}" in
    mixlib-install)
      args=(version --version -v -V)
      ;;
    *)
      args=(--version version -v -V)
      ;;
  esac

  for arg in "${args[@]}"; do
    if output="$(${binary} "${arg}" 2>&1)"; then
      local line
      line="$(printf '%s\n' "${output}" | preferred_version_line)"
      if [[ -z "${line}" ]]; then
        line="$(printf '%s\n' "${output}" | first_non_empty_line)"
      fi
      if [[ -n "${line}" ]] \
        && [[ ! "${line}" =~ ^(ERROR:|Invalid\ mode:|Usage:|Docs:|Website:|Welcome\ to\ |The\ Cinc\ command\ line\ tool) ]] \
        && [[ "${line}" =~ ([Vv]ersion|[0-9]+\.[0-9]+) ]]; then
        printf '%s: %s\n' "${binary}" "${line}"
        return 0
      fi
    fi
  done

  # Some wrappers do not expose a direct version flag.
  printf '%s: no supported version flag found (skipped)\n' "${binary}"
  return 0
}

run_auditor_profile() {
  if [[ "${CINC_AUDITOR_USE_SUDO:-false}" == "true" ]]; then
    sudo /opt/cinc-workstation/bin/cinc-auditor exec test/integration/cinc-tests \
      --no-distinct-exit \
      --input="skip_known_failures=${SKIP_KNOWN_FAILURES}" \
      --reporter cli junit:junit.xml
  else
    /opt/cinc-workstation/bin/cinc-auditor exec test/integration/cinc-tests \
      --no-distinct-exit \
      --input="skip_known_failures=${SKIP_KNOWN_FAILURES}" \
      --reporter cli junit:junit.xml
  fi
}

main() {
  local binaries
  binaries="$(extract_binaries)"

  if [[ -z "${binaries}" ]]; then
    echo "Unable to read binaries list from ${POSTINST_PATH}" >&2
    exit 1
  fi

  local os arch
  os="$(uname -s)"
  arch="$(uname -m)"

  for binary in ${binaries}; do
    case "${binary}" in
      chef*|inspec*)
        continue
        ;;
      bio)
        # Biome only ships an x86_64 Linux binary
        [[ "${os}" == "Darwin" ]] && continue
        [[ "${os}" == "Linux" && "${arch}" == "aarch64" ]] && continue
        ;;
    esac

    if ! command -v "${binary}" >/dev/null 2>&1; then
      echo "${binary}: command not found" >&2
      exit 1
    fi

    print_version_output "${binary}"
  done

  cinc-auditor detect
  run_auditor_profile
}

main "$@"
