#!/usr/bin/env bash
set -u

: "${HERMES_API_BASE_URL:?Set HERMES_API_BASE_URL}"
: "${HERMES_API_KEY:?Set HERMES_API_KEY}"

message_path="${1:-synthetic-safe.eml}"
idempotency_key="${HERMES_IDEMPOTENCY_KEY:-sample-$(date +%s)-$$}"
max_attempts=4

work_dir="$(mktemp -d)"
chmod 700 "${work_dir}"
trap 'rm -rf -- "${work_dir}"' EXIT
message_snapshot="${work_dir}/message.eml"
cp -- "${message_path}" "${message_snapshot}"

for ((attempt = 1; attempt <= max_attempts; attempt += 1)); do
  body_file="${work_dir}/body-${attempt}.json"
  header_file="${work_dir}/headers-${attempt}.txt"
  set +e
  status="$(curl --silent --show-error \
    --connect-timeout 10 \
    --max-time 130 \
    --request POST \
    "${HERMES_API_BASE_URL%/}/v1/email-analyses" \
    --header "X-API-Key: ${HERMES_API_KEY}" \
    --header "Idempotency-Key: ${idempotency_key}" \
    --header "Content-Type: message/rfc822" \
    --data-binary "@${message_snapshot}" \
    --dump-header "${header_file}" \
    --output "${body_file}" \
    --write-out '%{http_code}')"
  curl_exit=$?
  set -e

  if [[ ${curl_exit} -eq 0 && ${status} -ge 200 && ${status} -lt 300 ]]; then
    cat "${body_file}"
    exit 0
  fi

  if [[ ${curl_exit} -eq 0 && ! "${status}" =~ ^(408|429|500|503)$ ]]; then
    problem_code="$(sed -n 's/.*"code"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "${body_file}")"
    request_id="$(sed -n 's/.*"request_id"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "${body_file}")"
    printf 'Hermes %s: %s (request_id=%s)\n' \
      "${status}" "${problem_code:-unknown}" "${request_id:-unknown}" >&2
    exit 1
  fi
  if [[ ${attempt} -eq ${max_attempts} ]]; then
    printf 'Hermes request did not reach a terminal response; preserve the Idempotency-Key and contact support.\n' >&2
    exit 1
  fi

  retry_after="$(awk 'BEGIN{IGNORECASE=1} /^Retry-After:[[:space:]]*[0-9]+/{gsub("\r", ""); print $2; exit}' "${header_file}")"
  if [[ "${retry_after}" =~ ^[0-9]+$ ]]; then
    delay="$((retry_after > 30 ? 30 : retry_after))"
  else
    base_delay="$((2 ** (attempt - 1)))"
    jitter_ms="$((RANDOM % 250))"
    delay="${base_delay}.$(printf '%03d' "${jitter_ms}")"
  fi
  sleep "${delay}"
done
