#!/usr/bin/env bash
# Point an Azure AI Search alias at one index and confirm it (PB-RAG-01-03 step 14 and section 8).
# The same script swaps forward and rolls back: pass the index the alias must point to.
#
# Usage:   bash swap-alias.sh <target-index>
#          bash swap-alias.sh "${V2_INDEX}"     # cut over
#          bash swap-alias.sh "${V1_INDEX}"     # roll back
# Needs:   SEARCH_ENDPOINT, API_VERSION, ALIAS. TOKEN is optional (taken from az if unset).
#          PROPAGATION_WAIT is optional, in seconds (default 15; Microsoft documents up to 10).
# Tools:   curl, jq, az (only when TOKEN is unset).
# Exit:    0 alias confirmed on the target, 1 a check failed, 2 bad usage or settings.
set -euo pipefail

target="${1:-}"
if [ -z "${target}" ]; then
  echo "usage: swap-alias.sh <target-index>" >&2
  exit 2
fi
for var in SEARCH_ENDPOINT API_VERSION ALIAS; do
  if [ -z "${!var:-}" ]; then
    echo "error: set ${var} first" >&2
    exit 2
  fi
done
if [ -z "${TOKEN:-}" ]; then
  TOKEN="$(az account get-access-token --scope https://search.azure.com/.default --query accessToken --output tsv)"
fi
wait_seconds="${PROPAGATION_WAIT:-15}"
body="$(mktemp)"
trap 'rm -f "${body}"' EXIT

# call METHOD PATH [JSON]: writes the response body to ${body}, prints the HTTP status code.
# A network failure prints 000, so the checks below report it instead of set -e stopping silently.
call() {
  local method="$1" path="$2" data="${3:-}"
  local args=(-sS -o "${body}" -w "%{http_code}" -X "${method}"
    -H "Authorization: Bearer ${TOKEN}"
    "${SEARCH_ENDPOINT}${path}?api-version=${API_VERSION}")
  if [ -n "${data}" ]; then
    args+=(-H "Content-Type: application/json" -d "${data}")
  fi
  : > "${body}"
  curl "${args[@]}" || true
}

alias_indexes() {
  jq -r '.indexes // [] | join(",")' "${body}"
}

stamp() { date -u +%Y-%m-%dT%H:%M:%SZ; }

# 1. The target index must exist, or the alias would point at nothing.
code="$(call GET "/indexes('${target}')")"
if [ "${code}" != "200" ]; then
  echo "FAIL: index ${target} not found (HTTP ${code}). Alias not changed." >&2
  exit 1
fi

# 2. Record where the alias points now (this is the rollback target).
code="$(call GET "/aliases/${ALIAS}")"
if [ "${code}" != "200" ]; then
  echo "FAIL: alias ${ALIAS} not found (HTTP ${code}). Create it first (PB-RAG-09-01 step 3)." >&2
  exit 1
fi
before="$(alias_indexes)"
echo "$(stamp) alias ${ALIAS} before: [${before}]"
if [ "${before}" = "${target}" ]; then
  echo "$(stamp) alias already points to ${target}. Nothing to do."
  exit 0
fi

# 3. Repoint: one index in the array.
code="$(call PUT "/aliases/${ALIAS}" "{\"name\": \"${ALIAS}\", \"indexes\": [\"${target}\"]}")"
if [ "${code}" != "200" ] && [ "${code}" != "201" ]; then
  echo "FAIL: alias update returned HTTP ${code}: $(cat "${body}")" >&2
  exit 1
fi
echo "$(stamp) alias update sent (HTTP ${code}). Waiting ${wait_seconds} seconds to propagate."
sleep "${wait_seconds}"

# 4. Confirm.
code="$(call GET "/aliases/${ALIAS}")"
after="$(alias_indexes)"
echo "$(stamp) alias ${ALIAS} after: [${after}]"
if [ "${code}" != "200" ] || [ "${after}" != "${target}" ]; then
  echo "FAIL: alias does not point to ${target}. To go back, run: bash swap-alias.sh ${before}" >&2
  exit 1
fi
echo "$(stamp) OK: alias ${ALIAS} points to ${target}. Previous index: ${before}"
