#!/usr/bin/env bash
# Place a call so that retries can never place it twice. Needs: curl 7.76+, jq.
#   LOGICAL_ID=renewal-L-1042-2026-11 AGENT_ID=agent_... ./create-call-reliably.sh
# Every request runs, so the script never resends blindly: after a timeout or a 5xx it lists the
# calls to that number and looks for its own LOGICAL_ID in metadata before sending again.
set -euo pipefail
BASE="${RELATIONSAI_API_BASE:-https://voice-api.relationsai.com/v1}"
: "${LOGICAL_ID:?Set LOGICAL_ID to your own id for this call (letters, digits, . _ -)}"
AGENT_ID="${AGENT_ID:-agent_1ZltiWzxrXmMprGD6q63}" # the test-mode Sample agent unless you set your own
TO="${TO:-+12025550100}"
OUTBOX_DIR="${OUTBOX_DIR:-./outbox}"
mkdir -p "$OUTBOX_DIR"
AUTH="Authorization: Bearer $RELATIONSAI_API_KEY"

# Save the time BEFORE the first attempt; a re-run with the same LOGICAL_ID reuses it.
since_file="$OUTBOX_DIR/$LOGICAL_ID.created"
[ -f "$since_file" ] || date -u -v-10M +%Y-%m-%dT%H:%M:%SZ >"$since_file" 2>/dev/null || date -u -d '10 minutes ago' +%Y-%m-%dT%H:%M:%SZ >"$since_file"
if [ -f "$OUTBOX_DIR/$LOGICAL_ID.call" ]; then
  echo "$(cat "$OUTBOX_DIR/$LOGICAL_ID.call"): already placed for $LOGICAL_ID (from the outbox), not calling again"
  exit 0
fi
body=$(jq -n --arg agent "$AGENT_ID" --arg to "$TO" --arg id "$LOGICAL_ID" '{agent_id: $agent, to: $to, metadata: {logical_id: $id}}')

find_existing() { # prints the id of the call with our LOGICAL_ID, if any
  curl -sS --fail-with-body -G "$BASE/calls" -H "$AUTH" --data-urlencode "to=$TO" \
    --data-urlencode "created_after=$(cat "$since_file")" --data-urlencode "limit=100" |
    jq -r --arg id "$LOGICAL_ID" '[.data[] | select(.metadata.logical_id == $id)][0].id // empty'
}

must_check=false
for attempt in 1 2 3 4 5; do
  if $must_check; then
    found=$(find_existing) || { echo "Could not read the call list; run again later with the same LOGICAL_ID." >&2; exit 1; }
    if [ -n "$found" ]; then echo "$found" >"$OUTBOX_DIR/$LOGICAL_ID.call"; echo "$found (found: the earlier attempt placed it)"; exit 0; fi
  fi
  out=$(mktemp) headers=$(mktemp)
  status=$(curl -sS --max-time 30 -o "$out" -D "$headers" -w '%{http_code}' -X POST "$BASE/calls" \
    -H "$AUTH" -H "Content-Type: application/json" -d "$body") || status=000
  case "$status" in
    2??) jq -r '.id' "$out" >"$OUTBOX_DIR/$LOGICAL_ID.call"; jq -r '"\(.id) status=\(.status)"' "$out"; exit 0 ;;
    000|500|502|504) must_check=true ;;  # may have been placed: check before sending again
    429|503) must_check=false ;;         # nothing was done: send again after the wait
    *) cat "$out" >&2; exit 1 ;;
  esac
  wait=$(tr -d '\r' <"$headers" | awk -F': ' 'tolower($1)=="retry-after" {print $2}')
  if [ "${wait:-0}" -gt 120 ]; then echo "Try again after ${wait}s with the same LOGICAL_ID: $(cat "$out")" >&2; exit 1; fi
  sleep "${wait:-$((attempt * 2))}"
done
echo "Still unconfirmed. Run again later with the same LOGICAL_ID; it checks before sending." >&2
exit 1
