#!/bin/sh
# Consume test requests from AMQP queue and feed them to debci-test
set -eu

short_options='t:'
long_options='tag:,do-request'

usage() {
  cat <<EOF
usage: debci-worker [OPTIONS]

Options:
  -t TAG, --tag TAG         listen to queues which require this platform tag
                            (can be specified multiple times)

$@
EOF
}

debci_base_dir=$(readlink -f $(dirname $(readlink -f $0))/..)
. $debci_base_dir/lib/environment.sh
. $debci_base_dir/lib/functions.sh

tags=''

# Process one request. Read the AMQP message from stdin.
do_request() {
  local request
  local pkg
  local suite
  local opts

  read request || true  # we expect EOF and thus read to fail
  set -- $request
  if [ $# -eq 0 ]; then
    return
  fi
  pkg="$1"
  suite="${2:-}"
  if [ -n "$suite" ]; then
    shift 2
  else
    suite="$debci_suite"
    shift 1
  fi

  releases=""
  opts=""
  for param in $@; do
    case "$param" in
      trigger:*)
        opts="$opts --trigger=${param#trigger:}"
        ;;
      pin-packages:*)
        arg=${param#pin-packages:}
        opts="$opts --pin-packages=$arg"
        ;;
      run-id:*)
        arg=${param#run-id:}
        opts="$opts --run-id=$arg"
        ;;
      *)
        echo "Unknown test parameter: $param" >&2
        ;;
    esac
  done

  if ! (echo "$pkg" | grep -q '^[a-z0-9.+-]\+$'); then
    log "W: invalid package name: $pkg, ignoring"
    return
  fi

  log "$pkg $suite/$debci_arch started"

  local tmp_dir=$(mktemp -d)

  # run the test
  local result_dir="$(
    debci-test \
      --quiet \
      --data-dir "$tmp_dir" \
      --suite "$suite" \
      --print-output \
      $opts \
      "$pkg"
  )"

  if [ ! -s "$result_dir/exitcode" ]; then
    log "E: Test for package $pkg produced no exit code, aborting"
    exit 2
  fi

  # debci_suite has to passed in to report_status because the worker is running
  # using the "default" suite which is usually unstable, which might be
  # different from the suite in which the test has actually just been executed.
  case $(cat "$result_dir/exitcode") in
      0|2)
          debci_suite="$suite" report_status $pkg pass
          ;;
      4|6|12|14)
          debci_suite="$suite" report_status $pkg fail
          ;;
      8)
          debci_suite="$suite" report_status $pkg neutral
          ;;
      *)
          debci_suite="$suite" report_status $pkg tmpfail
          ;;
  esac

  # publish results
  result_dir=${result_dir##$tmp_dir/}

  ( cd $tmp_dir && tar czf - "$result_dir" ) | amqp-publish \
    --url="${debci_amqp_server}" \
    --persistent \
    --routing-key="${debci_amqp_results_queue}"

  rm -rf "$tmp_dir"
}

# parse CLI arguments
while true; do
  case "$1" in
    -t|--tag)
      tags="${tags}_$2"
      shift 2
      ;;
    --do-request)
      do_request
      exit 0
      ;;
    *)
      break
      ;;
  esac
done

amqp-declare-queue \
  --url="$debci_amqp_server" \
  --durable \
  --queue="$debci_amqp_results_queue" > /dev/null

# if the user calls this, we run forever with consuming messages;
# amqp-consume calls ourselves with the (hidden) --do-request option
amqp_queue="${debci_amqp_queue}${tags}"
log "I: Connecting to AMQP queue $amqp_queue on ${debci_amqp_server}"
debci job declare-queue
exec amqp-consume --url ${debci_amqp_server} -q $amqp_queue --prefetch-count 1 -- $0 --do-request
