#!/usr/bin/env bash
# m13b_w3_smoke.sh — End-to-end smoke for the M13b W3 telegram bot CRUD.
#
# Walks through:
#   1. authd /health
#   2. login (super_admin) → access + refresh
#   3. POST /v1/tenants (create a tenant to host a bot)
#   4. GET /v1/tenants/{id}/telegram/bots (initially empty)
#   5. POST /v1/tenants/{id}/telegram/bots (create with bot_token)
#   6. GET  /v1/tenants/{id}/telegram/bots/{bid} (verify bot_token_set=true)
#   7. GET /v1/tenants/{id}/telegram/bots (list has 1)
#   8. PATCH /v1/tenants/{id}/telegram/bots/{bid} (change welcome_message)
#   9. POST .../status (pause)
#   10. POST .../status (activate)
#   11. POST .../rotate-token (new token; bot_token_set still true)
#   12. POST (duplicate id) → 409
#   13. POST (bad id) → 400
#   14. POST (bad token) → 400
#   15. GET (no token field in response)
#   16. tenant_admin tries telegram endpoints → 403 (super_admin only)
#   17. Cleanup: archive the tenant
#
# Requires:
#   - authd running on $BA_AUTHD_HTTP (default http://127.0.0.1:8804)
#   - $BA_AUTHD_JWT_SECRET set
#   - super_admin user in Postgres (scripts/bootstrap-super-admin.sh)
#   - 012_telegram_bot_fields migration applied
#
# Run:
#   bash scripts/m13b_w3_smoke.sh
#
# Exits 0 if all steps pass.

set -euo pipefail
cd "$(dirname "$0")/.."

AUTHD="${BA_AUTHD_HTTP:-http://127.0.0.1:8804}"
SUPER_EMAIL="${BA_SMOKE_SUPER_EMAIL:-super@broad-announce.test}"
SUPER_PASSWORD="${BA_SMOKE_SUPER_PASSWORD:-test-password-123}"
DSN="${BA_POSTGRES_DSN:-${PG_DSN:-postgres://ba:ba@localhost:5432/ba?sslmode=disable}}"

PASS=0
FAIL=0
RESULTS=()
TENANT_SLUG="smoke-tg-$(date +%s)"
TENANT_EMAIL="ops-${TENANT_SLUG}@smoke.test"
TENANT_ADMIN_EMAIL="admin-${TENANT_SLUG}@smoke.test"
TENANT_ADMIN_PASSWORD="smoke-test-password-1234"
BOT_ID="primary"
BOT_TOKEN="12345678:$(python3 -c "import secrets; print(secrets.token_hex(18)[:35])")"
ROTATED_TOKEN="12345678:$(python3 -c "import secrets; print(secrets.token_hex(18)[:35])")"

check() {
  local name="$1"
  local actual="$2"
  local want="$3"
  if [[ "$actual" == "$want" ]]; then
    PASS=$((PASS+1))
    RESULTS+=("OK   $name")
  else
    FAIL=$((FAIL+1))
    RESULTS+=("FAIL $name (got $actual, want $want)")
  fi
}

# JSON helper: extract a top-level field as string.
json_field() {
  python3 -c "import json,sys; d=json.load(sys.stdin); k='$2'.split('.'); v=d
for kk in k:
  v=v[kk] if isinstance(v,dict) else v[int(kk)]
print(v if not isinstance(v,(list,dict,bool)) else json.dumps(v))" <<<"$1"
}

# -------------------------------------------------------------------
# 1. health
# -------------------------------------------------------------------
status=$(curl -s -o /dev/null -w "%{http_code}" "$AUTHD/health")
check "1. authd /health" "$status" "200"

# -------------------------------------------------------------------
# 2. login (super_admin)
# -------------------------------------------------------------------
login_body=$(curl -s -X POST "$AUTHD/v1/auth/login" \
  -H 'Content-Type: application/json' \
  -d "{\"email\":\"$SUPER_EMAIL\",\"password\":\"$SUPER_PASSWORD\"}")
SUPER_TOKEN=$(json_field "$login_body" access_token)
if [[ -z "$SUPER_TOKEN" ]]; then
  echo "FATAL: super_admin login failed: $login_body"
  exit 1
fi
check "2. super_admin login" "200" "200"

# -------------------------------------------------------------------
# 3. POST /v1/tenants (create a tenant to host a bot)
# -------------------------------------------------------------------
create=$(curl -s -w "\n%{http_code}" -X POST "$AUTHD/v1/tenants" \
  -H "Authorization: Bearer $SUPER_TOKEN" \
  -H 'Content-Type: application/json' \
  -d "{\"slug\":\"$TENANT_SLUG\",\"display_name\":\"Smoke Telegram Tenant\",\"contact_email\":\"$TENANT_EMAIL\",\"rate_limit_per_sec\":5000,\"fcm_shared\":true}")
create_code=$(echo "$create" | tail -1)
create_body=$(echo "$create" | head -n -1)
TENANT_ID=$(json_field "$create_body" id)
check "3. POST /v1/tenants" "$create_code" "201"
[[ -n "$TENANT_ID" ]] || { echo "FATAL: no tenant id"; exit 1; }
echo "    new tenant: $TENANT_ID"

# -------------------------------------------------------------------
# 4. GET /v1/tenants/{id}/telegram/bots (initially empty)
# -------------------------------------------------------------------
list=$(curl -s -H "Authorization: Bearer $SUPER_TOKEN" "$AUTHD/v1/tenants/$TENANT_ID/telegram/bots?limit=10")
total=$(json_field "$list" total)
check "4. GET /v1/tenants/{id}/telegram/bots (empty)" "$total" "0"

# -------------------------------------------------------------------
# 5. POST /v1/tenants/{id}/telegram/bots
# -------------------------------------------------------------------
create=$(curl -s -w "\n%{http_code}" -X POST "$AUTHD/v1/tenants/$TENANT_ID/telegram/bots" \
  -H "Authorization: Bearer $SUPER_TOKEN" \
  -H 'Content-Type: application/json' \
  -d "{\"id\":\"$BOT_ID\",\"name\":\"Acme Ops Bot\",\"bot_token\":\"$BOT_TOKEN\",\"welcome_message\":\"Welcome!\",\"description\":\"smoke test\"}")
create_code=$(echo "$create" | tail -1)
create_body=$(echo "$create" | head -n -1)
if [[ "$create_code" != "201" ]]; then
  echo "FATAL: create bot failed ($create_code): $create_body"
  exit 1
fi
BOT_ID_BACK=$(json_field "$create_body" id)
BOT_TOKEN_SET=$(json_field "$create_body" bot_token_set)
WELCOME=$(json_field "$create_body" welcome_message)
check "5. POST /v1/tenants/{id}/telegram/bots" "$create_code" "201"
check "5b. response id == $BOT_ID" "$BOT_ID_BACK" "$BOT_ID"
check "5c. response bot_token_set == true" "$BOT_TOKEN_SET" "true"
check "5d. response welcome_message" "$WELCOME" "Welcome!"

# 5e. response MUST NOT include the plaintext bot_token.
if echo "$create_body" | grep -q '"bot_token"'; then
  check "5e. response does NOT contain bot_token" "present" "absent"
else
  check "5e. response does NOT contain bot_token" "absent" "absent"
fi

# -------------------------------------------------------------------
# 6. GET /v1/tenants/{id}/telegram/bots/{bid}
# -------------------------------------------------------------------
detail=$(curl -s -H "Authorization: Bearer $SUPER_TOKEN" "$AUTHD/v1/tenants/$TENANT_ID/telegram/bots/$BOT_ID")
detail_id=$(json_field "$detail" id)
detail_status=$(json_field "$detail" status)
detail_token_set=$(json_field "$detail" bot_token_set)
check "6. GET bot id" "$detail_id" "$BOT_ID"
check "6b. status == active" "$detail_status" "active"
check "6c. bot_token_set == true" "$detail_token_set" "true"
# 6d. detail MUST NOT include bot_token.
if echo "$detail" | grep -q '"bot_token"'; then
  check "6d. detail does NOT contain bot_token" "present" "absent"
else
  check "6d. detail does NOT contain bot_token" "absent" "absent"
fi

# -------------------------------------------------------------------
# 7. GET /v1/tenants/{id}/telegram/bots (list has 1)
# -------------------------------------------------------------------
list=$(curl -s -H "Authorization: Bearer $SUPER_TOKEN" "$AUTHD/v1/tenants/$TENANT_ID/telegram/bots?limit=10")
total=$(json_field "$list" total)
check "7. GET telegram/bots (count)" "$total" "1"

# -------------------------------------------------------------------
# 8. PATCH /v1/tenants/{id}/telegram/bots/{bid}
# -------------------------------------------------------------------
patch=$(curl -s -o /dev/null -w "%{http_code}" -X PATCH "$AUTHD/v1/tenants/$TENANT_ID/telegram/bots/$BOT_ID" \
  -H "Authorization: Bearer $SUPER_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"welcome_message":"Welcome to Acme!","default_source_id":"primary"}')
check "8. PATCH telegram/bots/{bid}" "$patch" "200"
detail=$(curl -s -H "Authorization: Bearer $SUPER_TOKEN" "$AUTHD/v1/tenants/$TENANT_ID/telegram/bots/$BOT_ID")
detail_welcome=$(json_field "$detail" welcome_message)
detail_default=$(json_field "$detail" default_source_id)
check "8b. PATCH welcome_message persisted" "$detail_welcome" "Welcome to Acme!"
check "8c. PATCH default_source_id persisted" "$detail_default" "primary"

# -------------------------------------------------------------------
# 9. POST .../status pause
# -------------------------------------------------------------------
pause=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$AUTHD/v1/tenants/$TENANT_ID/telegram/bots/$BOT_ID/status" \
  -H "Authorization: Bearer $SUPER_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"status":"paused"}')
check "9. POST .../status pause" "$pause" "200"
detail=$(curl -s -H "Authorization: Bearer $SUPER_TOKEN" "$AUTHD/v1/tenants/$TENANT_ID/telegram/bots/$BOT_ID")
detail_status=$(json_field "$detail" status)
check "9b. status == paused" "$detail_status" "paused"

# -------------------------------------------------------------------
# 10. POST .../status activate
# -------------------------------------------------------------------
act=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$AUTHD/v1/tenants/$TENANT_ID/telegram/bots/$BOT_ID/status" \
  -H "Authorization: Bearer $SUPER_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"status":"active"}')
check "10. POST .../status activate" "$act" "200"

# -------------------------------------------------------------------
# 11. POST .../rotate-token
# -------------------------------------------------------------------
rot=$(curl -s -w "\n%{http_code}" -X POST "$AUTHD/v1/tenants/$TENANT_ID/telegram/bots/$BOT_ID/rotate-token" \
  -H "Authorization: Bearer $SUPER_TOKEN" \
  -H 'Content-Type: application/json' \
  -d "{\"bot_token\":\"$ROTATED_TOKEN\"}")
rot_code=$(echo "$rot" | tail -1)
rot_body=$(echo "$rot" | head -n -1)
check "11. POST .../rotate-token" "$rot_code" "200"
rot_token_set=$(json_field "$rot_body" bot_token_set)
rot_last=$(json_field "$rot_body" last_rotated_at)
check "11b. rotated bot_token_set == true" "$rot_token_set" "true"
if [[ -n "$rot_last" && "$rot_last" != "—" ]]; then
  check "11c. last_rotated_at populated" "yes" "yes"
else
  check "11c. last_rotated_at populated" "$rot_last" "yes"
fi
# 11d. rotated response MUST NOT contain the new bot_token.
if echo "$rot_body" | grep -q "$ROTATED_TOKEN"; then
  check "11d. rotate response does NOT echo the token" "present" "absent"
else
  check "11d. rotate response does NOT echo the token" "absent" "absent"
fi

# -------------------------------------------------------------------
# 12. POST duplicate id → 409
# -------------------------------------------------------------------
dup=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$AUTHD/v1/tenants/$TENANT_ID/telegram/bots" \
  -H "Authorization: Bearer $SUPER_TOKEN" \
  -H 'Content-Type: application/json' \
  -d "{\"id\":\"$BOT_ID\",\"name\":\"Dup\",\"bot_token\":\"$BOT_TOKEN\"}")
check "12. POST telegram/bots (dup id) \u2192 409" "$dup" "409"

# -------------------------------------------------------------------
# 13. POST bad id → 400
# -------------------------------------------------------------------
bad=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$AUTHD/v1/tenants/$TENANT_ID/telegram/bots" \
  -H "Authorization: Bearer $SUPER_TOKEN" \
  -H 'Content-Type: application/json' \
  -d "{\"id\":\"Bad ID!\",\"name\":\"x\",\"bot_token\":\"$BOT_TOKEN\"}")
check "13. POST telegram/bots (bad id) \u2192 400" "$bad" "400"

# -------------------------------------------------------------------
# 14. POST bad token → 400
# -------------------------------------------------------------------
bad=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$AUTHD/v1/tenants/$TENANT_ID/telegram/bots" \
  -H "Authorization: Bearer $SUPER_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"id":"secondary","name":"x","bot_token":"not-a-token"}')
check "14. POST telegram/bots (bad token) \u2192 400" "$bad" "400"

# -------------------------------------------------------------------
# 15. tenant_admin (created below) is FORBIDDEN on telegram endpoints
# -------------------------------------------------------------------
export PGPASSWORD="$(echo "$DSN" | sed -E 's|.*://[^:]+:([^@]+)@.*|\1|')"
HASH=$(python3 -c "
import bcrypt
print(bcrypt.hashpw(b'${TENANT_ADMIN_PASSWORD}', bcrypt.gensalt(rounds=10)).decode())
")
psql "$DSN" -v ON_ERROR_STOP=0 -X -q -c "
INSERT INTO auth.users (tenant_id, email, role, status, password_hash)
SELECT id, '${TENANT_ADMIN_EMAIL}', 'tenant_admin', 'active', '${HASH}'
FROM auth.tenants WHERE slug = '${TENANT_SLUG}'
ON CONFLICT (email, tenant_id) WHERE tenant_id IS NOT NULL DO UPDATE SET password_hash = EXCLUDED.password_hash, status = 'active';
" >/dev/null
ta_login=$(curl -s -X POST "$AUTHD/v1/auth/login" \
  -H 'Content-Type: application/json' \
  -d "{\"email\":\"$TENANT_ADMIN_EMAIL\",\"password\":\"$TENANT_ADMIN_PASSWORD\"}")
TA_TOKEN=$(json_field "$ta_login" access_token)
if [[ -z "$TA_TOKEN" ]]; then
  echo "FATAL: tenant_admin login failed: $ta_login"
  exit 1
fi
check "15. tenant_admin login" "200" "200"
ta_list=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $TA_TOKEN" "$AUTHD/v1/tenants/$TENANT_ID/telegram/bots")
check "15a. tenant_admin GET telegram/bots \u2192 403" "$ta_list" "403"
ta_post=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$AUTHD/v1/tenants/$TENANT_ID/telegram/bots" \
  -H "Authorization: Bearer $TA_TOKEN" \
  -H 'Content-Type: application/json' \
  -d "{\"id\":\"other\",\"name\":\"x\",\"bot_token\":\"$BOT_TOKEN\"}")
check "15b. tenant_admin POST telegram/bots \u2192 403" "$ta_post" "403"
ta_get=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $TA_TOKEN" "$AUTHD/v1/tenants/$TENANT_ID/telegram/bots/$BOT_ID")
check "15c. tenant_admin GET telegram/bots/{bid} \u2192 403" "$ta_get" "403"

# -------------------------------------------------------------------
# 16. Cleanup: archive the tenant
# -------------------------------------------------------------------
arc=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$AUTHD/v1/tenants/$TENANT_ID/status" \
  -H "Authorization: Bearer $SUPER_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"status":"archived"}')
check "16. cleanup: archive tenant" "$arc" "200"

# -------------------------------------------------------------------
# Summary
# -------------------------------------------------------------------
echo
for r in "${RESULTS[@]}"; do echo "  $r"; done
echo
echo "PASS=$PASS FAIL=$FAIL"
if [[ $FAIL -gt 0 ]]; then
  exit 1
fi
exit 0
