#!/usr/bin/env bash
set -euo pipefail
BASE="http://127.0.0.1:48090"
HOST_HEADER="sub-lb.tap365.org"
EVDIR="$1"
: "${ADMIN_KEY:?ADMIN_KEY required}"
: "${PUBLIC_KEY:?PUBLIC_KEY required}"
mkdir -p "$EVDIR"
cd "$EVDIR"
CURL=(curl -sS --max-time 240 -H "Host: ${HOST_HEADER}")
JQ=jq

write_json_payload() { local f="$1"; shift; printf '%s' "$*" > "$f"; }
request_json() {
  local name="$1" method="$2" url="$3" auth_header="$4" payload="$5"
  local body="${name}.raw.json" meta="${name}.http"
  if [[ -n "$payload" ]]; then
    "${CURL[@]}" -X "$method" "$url" -H 'Content-Type: application/json' ${auth_header:+-H "$auth_header"} --data-binary "@$payload" -w '\n%{http_code}' -o "$body.tmp" > "$meta.tmp" || true
  else
    "${CURL[@]}" -X "$method" "$url" ${auth_header:+-H "$auth_header"} -w '\n%{http_code}' -o "$body.tmp" > "$meta.tmp" || true
  fi
  tr -d '\n' < "$meta.tmp" > "$meta"
  mv "$body.tmp" "$body"
  rm -f "$meta.tmp"
}
request_multipart() {
  local name="$1" url="$2" auth_header="$3"; shift 3
  local body="${name}.raw.json" meta="${name}.http"
  "${CURL[@]}" -X POST "$url" -H "$auth_header" "$@" -w '\n%{http_code}' -o "$body.tmp" > "$meta.tmp" || true
  tr -d '\n' < "$meta.tmp" > "$meta"
  mv "$body.tmp" "$body"
  rm -f "$meta.tmp"
}
sanitize_json() {
  local in="$1" out="$2"
  jq 'walk(if type=="string" and (length>160) then (.[0:80] + "..." + .[-20:]) else . end)' "$in" > "$out" 2>/dev/null || cp "$in" "$out"
}
summary_one() {
  local name="$1" body="${name}.raw.json" http="$(cat ${name}.http 2>/dev/null || echo 000)"
  jq -n --arg name "$name" --arg http "$http" --slurpfile b "$body" '
    ($b[0] // {}) as $x | {
      name:$name,
      http:$http,
      id:($x.id//null),
      object:($x.object//null),
      status:($x.status//null),
      choices_len:(($x.choices//[])|length),
      data_len:(($x.data//[])|length),
      output_types:(($x.output//[])|map(.type)),
      has_b64:((($x.data//[])|map(has("b64_json"))|any) or (($x.output//[])|map((.result//"")|length>100)|any)),
      error:($x.error//null)
    }'
}
# tiny png
python3 - <<'PY'
import base64
png='iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII='
open('one_px.png','wb').write(base64.b64decode(png))
PY
# Admin: turnstile off, create/login, restore early
request_json settings_before GET "$BASE/api/v1/admin/settings" "x-api-key: $ADMIN_KEY" ""
jq '.data // .' settings_before.raw.json > settings_restore_payload.json
jq '(.data // .) | .turnstile_enabled=false' settings_before.raw.json > settings_turnstile_off_payload.json
request_json settings_off PUT "$BASE/api/v1/admin/settings" "x-api-key: $ADMIN_KEY" settings_turnstile_off_payload.json
EMAIL="codex-image-studio-final-$(date +%Y%m%d_%H%M%S)@gmail.com"
PASS="CodexImageStudio2026!"
jq -n --arg email "$EMAIL" --arg password "$PASS" '{email:$email,password:$password,username:"codex-image-studio-final",notes:"codex automated image-studio backend acceptance",balance:0,concurrency:5,allowed_groups:[]}' > create_user_payload.json
request_json create_user POST "$BASE/api/v1/admin/users" "x-api-key: $ADMIN_KEY" create_user_payload.json
USER_ID=$(jq -r '.data.id // .id // empty' create_user.raw.json)
printf '%s\n' "$USER_ID" > temp_user_id.txt
jq -n --arg email "$EMAIL" --arg password "$PASS" '{email:$email,password:$password}' > login_payload.json
request_json login POST "$BASE/api/v1/auth/login" "" login_payload.json
JWT=$(jq -r '.data.access_token // .access_token // empty' login.raw.json)
printf '%s\n' "${JWT:0:12}...masked" > jwt_masked.txt
request_json settings_restore PUT "$BASE/api/v1/admin/settings" "x-api-key: $ADMIN_KEY" settings_restore_payload.json
# Public OpenAI-compatible via 80 loopback
AUTH="Authorization: Bearer $PUBLIC_KEY"
write_json_payload payload_public_responses_text.json '{"model":"gpt-5.4-mini","input":"sublb backend final 80 text responses smoke. Reply OK only."}'
request_json public_responses_text POST "$BASE/v1/responses" "$AUTH" payload_public_responses_text.json
write_json_payload payload_public_chat_text.json '{"model":"gpt-5.4-mini","messages":[{"role":"user","content":"sublb backend final 80 chat smoke. Reply OK only."}]}'
request_json public_chat_text POST "$BASE/v1/chat/completions" "$AUTH" payload_public_chat_text.json
write_json_payload payload_public_responses_image_tool.json '{"model":"gpt-5.4-mini","input":"生成一张极简蓝色圆点图，白色背景。","tools":[{"type":"image_generation","model":"gpt-image-2","size":"1024x1024","quality":"low","output_format":"png"}],"tool_choice":{"type":"image_generation"}}'
request_json public_responses_image_tool POST "$BASE/v1/responses" "$AUTH" payload_public_responses_image_tool.json
write_json_payload payload_public_chat_image_tool.json '{"model":"gpt-image-2","messages":[{"role":"user","content":"生成一张极简绿色圆点图，白色背景。"}],"tools":[{"type":"image_generation","model":"gpt-image-2","size":"1024x1024","quality":"low","output_format":"png"}],"tool_choice":{"type":"image_generation"},"response_format":"b64_json"}'
request_json public_chat_image_tool POST "$BASE/v1/chat/completions" "$AUTH" payload_public_chat_image_tool.json
write_json_payload payload_public_images_generations.json '{"model":"gpt-image-2","prompt":"生成一张极简红色圆点图，白色背景。","n":1,"size":"1024x1024","quality":"low","response_format":"b64_json"}'
request_json public_images_generations POST "$BASE/v1/images/generations" "$AUTH" payload_public_images_generations.json
request_multipart public_images_edits "$BASE/v1/images/edits" "$AUTH" -F model=gpt-image-2 -F 'prompt=把图片改成蓝色圆点，白色背景。' -F n=1 -F size=1024x1024 -F quality=low -F response_format=b64_json -F image=@one_px.png;type=image/png
# Login-state image-studio wrappers
UAUTH="Authorization: Bearer $JWT"
write_json_payload payload_studio_generations.json '{"model":"gpt-image-2","prompt":"生成一张极简黄色圆点图，白色背景。","n":1,"size":"1024x1024","quality":"low","response_format":"b64_json"}'
request_json studio_generations POST "$BASE/api/v1/image-studio/images/generations" "$UAUTH" payload_studio_generations.json
write_json_payload payload_studio_responses.json '{"model":"gpt-5.4-mini","input":"生成一张极简紫色圆点图，白色背景。","tools":[{"type":"image_generation","model":"gpt-image-2","size":"1024x1024","quality":"low","output_format":"png"}],"tool_choice":{"type":"image_generation"},"response_format":"b64_json"}'
request_json studio_responses POST "$BASE/api/v1/image-studio/v1/responses" "$UAUTH" payload_studio_responses.json
write_json_payload payload_studio_chat.json '{"model":"gpt-image-2","messages":[{"role":"user","content":"生成一张极简橙色圆点图，白色背景。"}],"tools":[{"type":"image_generation","model":"gpt-image-2","size":"1024x1024","quality":"low","output_format":"png"}],"tool_choice":{"type":"image_generation"},"response_format":"b64_json"}'
request_json studio_chat POST "$BASE/api/v1/image-studio/v1/chat/completions" "$UAUTH" payload_studio_chat.json
request_multipart studio_edits "$BASE/api/v1/image-studio/images/edits" "$UAUTH" -F model=gpt-image-2 -F 'prompt=把图片改成紫色圆点，白色背景。' -F n=1 -F size=1024x1024 -F quality=low -F response_format=b64_json -F image=@one_px.png;type=image/png
# final cleanup and state
if [[ -n "$USER_ID" ]]; then request_json delete_user DELETE "$BASE/api/v1/admin/users/$USER_ID" "x-api-key: $ADMIN_KEY" ""; fi
request_json settings_final GET "$BASE/api/v1/admin/settings" "x-api-key: $ADMIN_KEY" ""
# sanitize huge responses
for f in *.raw.json; do sanitize_json "$f" "${f%.raw.json}.json"; done
# summary
jq -s '{evidence_dir: env.EVDIR, key_mask:"sk-908d...d5", node:"80 loopback 127.0.0.1:48090", http: map({(.name): .http})|add, details: map({key:.name, value:.})|from_entries, turnstile_final: (input.turnstile_enabled // input.data.turnstile_enabled // null)}' \
  <(summary_one public_responses_text) \
  <(summary_one public_chat_text) \
  <(summary_one public_responses_image_tool) \
  <(summary_one public_chat_image_tool) \
  <(summary_one public_images_generations) \
  <(summary_one public_images_edits) \
  <(summary_one studio_generations) \
  <(summary_one studio_responses) \
  <(summary_one studio_chat) \
  <(summary_one studio_edits) \
  settings_final.raw.json > summary.json
cat summary.json
