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

# Manual end-to-end probe for the region-request endpoint's strict validation
# gate (AZ-808). Each failure call should return HTTP 400 with an
# `application/problem+json` body whose `errors` map names the offending field
# path. The happy path should return HTTP 200.
#
# Usage:
#   API_URL=https://localhost:8080 JWT="<bearer-token>" ./scripts/probe_region_validation.sh
#   (defaults to https://localhost:8080 with a JWT minted via PerfBootstrap --mint-only)

API_URL="${API_URL:-https://localhost:8080}"
JWT="${JWT:-}"
PATH_REGION="${API_URL%/}/api/satellite/request"

if [[ -z "${JWT}" ]]; then
    echo "ERROR: set JWT env var to a bearer token. Mint one via:"
    echo "  dotnet run --project SatelliteProvider.IntegrationTests -- --mint-only"
    exit 2
fi

curl_args=(-sS -k -H "Authorization: Bearer ${JWT}" -H "Content-Type: application/json" -X POST "${PATH_REGION}")

probe() {
    local label="$1"
    local body="$2"
    local expected_status="$3"

    echo "----- ${label} (expecting HTTP ${expected_status}) -----"
    local response
    response=$(curl "${curl_args[@]}" -d "${body}" -w "\nHTTP_STATUS=%{http_code}\n")
    echo "${response}"
    local actual_status
    actual_status=$(echo "${response}" | tail -n 1 | sed 's/HTTP_STATUS=//')
    if [[ "${actual_status}" != "${expected_status}" ]]; then
        echo "FAIL: expected HTTP ${expected_status}, got ${actual_status}"
        return 1
    fi
    echo "OK: HTTP ${expected_status}"
    echo
}

# Generate a unique guid for the happy path
HAPPY_ID="$(uuidgen)"

probe "happy-path"             "{\"id\":\"${HAPPY_ID}\",\"lat\":47.461747,\"lon\":37.647063,\"sizeMeters\":200,\"zoomLevel\":18,\"stitchTiles\":false}" 200
# Reproduces the 2026-05-22 probe that surfaced silent-Guid-coercion (pre-AZ-808)
probe "missing-id"             '{"lat":49.94,"lon":36.31,"sizeMeters":200,"zoomLevel":18,"stitchTiles":false}' 400
probe "zero-guid-id"           '{"id":"00000000-0000-0000-0000-000000000000","lat":47.461747,"lon":37.647063,"sizeMeters":200,"zoomLevel":18,"stitchTiles":false}' 400
probe "missing-lat"            "{\"id\":\"$(uuidgen)\",\"lon\":37.647063,\"sizeMeters\":200,\"zoomLevel\":18,\"stitchTiles\":false}" 400
probe "lat-out-of-range"       "{\"id\":\"$(uuidgen)\",\"lat\":91,\"lon\":37.647063,\"sizeMeters\":200,\"zoomLevel\":18,\"stitchTiles\":false}" 400
probe "missing-lon"            "{\"id\":\"$(uuidgen)\",\"lat\":47.461747,\"sizeMeters\":200,\"zoomLevel\":18,\"stitchTiles\":false}" 400
probe "lon-out-of-range"       "{\"id\":\"$(uuidgen)\",\"lat\":47.461747,\"lon\":181,\"sizeMeters\":200,\"zoomLevel\":18,\"stitchTiles\":false}" 400
probe "missing-sizeMeters"     "{\"id\":\"$(uuidgen)\",\"lat\":47.461747,\"lon\":37.647063,\"zoomLevel\":18,\"stitchTiles\":false}" 400
probe "sizeMeters-out-of-range" "{\"id\":\"$(uuidgen)\",\"lat\":47.461747,\"lon\":37.647063,\"sizeMeters\":1000000,\"zoomLevel\":18,\"stitchTiles\":false}" 400
probe "missing-zoomLevel"      "{\"id\":\"$(uuidgen)\",\"lat\":47.461747,\"lon\":37.647063,\"sizeMeters\":200,\"stitchTiles\":false}" 400
probe "zoomLevel-out-of-range" "{\"id\":\"$(uuidgen)\",\"lat\":47.461747,\"lon\":37.647063,\"sizeMeters\":200,\"zoomLevel\":30,\"stitchTiles\":false}" 400
probe "missing-stitchTiles"    "{\"id\":\"$(uuidgen)\",\"lat\":47.461747,\"lon\":37.647063,\"sizeMeters\":200,\"zoomLevel\":18}" 400
probe "lat-type-mismatch"      "{\"id\":\"$(uuidgen)\",\"lat\":\"fifty\",\"lon\":37.647063,\"sizeMeters\":200,\"zoomLevel\":18,\"stitchTiles\":false}" 400
# Unknown root field — confirms UnmappedMemberHandling.Disallow stays active
probe "unknown-root-field"     "{\"id\":\"$(uuidgen)\",\"lat\":47.461747,\"lon\":37.647063,\"sizeMeters\":200,\"zoomLevel\":18,\"stitchTiles\":false,\"unknownField\":1}" 400

echo "All probes passed."
