#!/usr/bin/env bash
# =============================================================================
# Wild Dragon MAM — API Smoke Test
# =============================================================================
# Hits every major endpoint and reports pass/fail.
#
# Usage:
#   MAM_API_URL=http://10.0.0.25:47432 ./deploy/test-api.sh
#   MAM_API_URL=http://10.0.0.25:47432 NODE_TOKEN=wd_xxxx ./deploy/test-api.sh
# =============================================================================

set -euo pipefail

BASE="${MAM_API_URL:-http://localhost:47432}"
TOKEN="${NODE_TOKEN:-}"

PASS=0; FAIL=0; SKIP=0

GRN='\033[0;32m'; RED='\033[0;31m'; YEL='\033[1;33m'; CYN='\033[0;36m'; BLD='\033[1m'; NC='\033[0m'

pass()   { PASS=$((PASS+1));  echo -e "  ${GRN}PASS${NC}  $1"; }
fail()   { FAIL=$((FAIL+1));  echo -e "  ${RED}FAIL${NC}  $1  ${RED}← $2${NC}"; }
skip()   { SKIP=$((SKIP+1));  echo -e "  ${YEL}SKIP${NC}  $1  ${YEL}($2)${NC}"; }
header() { echo -e "\n${BLD}$1${NC}"; }

AUTH_ARGS=()
[[ -n "$TOKEN" ]] && AUTH_ARGS+=(-H "Authorization: Bearer $TOKEN")

# GET — check HTTP status code (no -f so 4xx/5xx are visible as their real code)
check_status() {
  local label="$1" path="$2" want="$3"
  local got
  got=$(curl -s -o /dev/null -w "%{http_code}" "${AUTH_ARGS[@]}" "$BASE$path" 2>/dev/null)
  [[ -z "$got" ]] && got="000"
  if [[ "$got" == "$want" ]]; then
    pass "$label  [HTTP $got]"
  else
    fail "$label  [HTTP $got]" "expected $want"
  fi
}

# GET — check response body contains literal string (fgrep avoids regex interpretation)
check_body() {
  local label="$1" path="$2" needle="$3"
  local body
  body=$(curl -s "${AUTH_ARGS[@]}" "$BASE$path" 2>/dev/null) || { fail "$label" "request failed"; return; }
  if echo "$body" | grep -qF "$needle"; then
    pass "$label"
  else
    fail "$label" "'$needle' not in response"
  fi
}

# POST — check HTTP status code
check_post() {
  local label="$1" path="$2" data="$3" want="$4"
  local got
  got=$(curl -s -o /dev/null -w "%{http_code}" \
    "${AUTH_ARGS[@]}" \
    -H "Content-Type: application/json" \
    -X POST -d "$data" \
    "$BASE$path" 2>/dev/null)
  [[ -z "$got" ]] && got="000"
  if [[ "$got" == "$want" ]]; then
    pass "$label  [HTTP $got]"
  else
    fail "$label  [HTTP $got]" "expected $want"
  fi
}

# ─────────────────────────────────────────────────────────────────────────────
echo ""
echo -e "${BLD}${CYN}Wild Dragon MAM — API Smoke Test${NC}"
echo -e "  Base URL : ${BLD}$BASE${NC}"
[[ -n "$TOKEN" ]] && echo -e "  Auth     : Bearer token" || echo -e "  Auth     : none"
echo ""

# ── Connectivity ─────────────────────────────────────────────────────────────
header "Connectivity"
CONNECT=$(curl -s -o /dev/null -w "%{http_code}" "$BASE/health" 2>/dev/null)
if [[ "$CONNECT" == "200" ]]; then
  pass "API server reachable  [/health → 200]"
else
  fail "API server reachable  [HTTP $CONNECT]" "cannot reach $BASE"
  echo -e "\n  ${RED}Cannot reach the server — aborting.${NC}"
  exit 1
fi

# ── Auth ─────────────────────────────────────────────────────────────────────
header "Auth"
check_status "GET /auth/me"                               "/api/v1/auth/me"            200
check_body   "GET /auth/me returns username"             "/api/v1/auth/me"            '"username"'
check_post   "POST /auth/login (missing body → 400)"     "/api/v1/auth/login"  '{}'   400

# ── Assets ───────────────────────────────────────────────────────────────────
header "Assets"
check_status "GET /assets"                               "/api/v1/assets"             200
check_body   "GET /assets returns assets key"           "/api/v1/assets"             '"assets"'
check_status "GET /assets bogus id → 404"               "/api/v1/assets/00000000-0000-0000-0000-000000000000" 404

# ── Projects ─────────────────────────────────────────────────────────────────
header "Projects"
check_status "GET /projects"                            "/api/v1/projects"           200
check_body   "GET /projects returns array"             "/api/v1/projects"           '['

# ── Jobs ─────────────────────────────────────────────────────────────────────
header "Jobs"
check_status "GET /jobs"                                "/api/v1/jobs"               200
check_body   "GET /jobs returns array"                 "/api/v1/jobs"               '['

# ── Recorders ────────────────────────────────────────────────────────────────
header "Recorders"
check_status "GET /recorders"                          "/api/v1/recorders"          200

# ── Sequences (requires project_id param) ────────────────────────────────────
header "Sequences"
check_status "GET /sequences (no project_id → 400)"   "/api/v1/sequences"          400
check_status "GET /sequences bogus project_id → 200"  "/api/v1/sequences?project_id=00000000-0000-0000-0000-000000000000" 200

# ── Settings ─────────────────────────────────────────────────────────────────
header "Settings"
check_status "GET /settings/ampp"                     "/api/v1/settings/ampp"      200

# ── Cluster ──────────────────────────────────────────────────────────────────
header "Cluster"
check_status "GET /cluster"                           "/api/v1/cluster"            200
check_body   "GET /cluster returns array"            "/api/v1/cluster"            '['

# Heartbeat: register a temporary smoke-test node, verify it appears, remove it
TEST_HOST="smoke-test-$(date +%s)"
check_post "POST /cluster/heartbeat" "/api/v1/cluster/heartbeat" \
  "{\"hostname\":\"$TEST_HOST\",\"role\":\"smoketest\",\"cpu_usage\":0,\"mem_used_mb\":512,\"mem_total_mb\":4096}" \
  200

NODE_ID=$(curl -s "${AUTH_ARGS[@]}" "$BASE/api/v1/cluster" 2>/dev/null \
  | grep -o '"id":"[^"]*"' | head -1 | grep -o '[0-9a-f-]\{36\}' || true)

if [[ -n "$NODE_ID" ]]; then
  pass "Cluster node visible in registry"
  DEL=$(curl -s -o /dev/null -w "%{http_code}" "${AUTH_ARGS[@]}" \
    -X DELETE "$BASE/api/v1/cluster/$NODE_ID" 2>/dev/null)
  [[ "$DEL" == "200" ]] && pass "DELETE /cluster/:id (cleanup)  [HTTP $DEL]" \
                         || fail "DELETE /cluster/:id (cleanup)" "HTTP $DEL"
else
  skip "Cluster node visible in registry" "could not parse node id from response"
fi

# ── System / Containers ───────────────────────────────────────────────────────
header "System"
check_status "GET /system/containers"                 "/api/v1/system/containers"  200
check_body   "Containers returns array"              "/api/v1/system/containers"  '['

# ── Capture (proxies to capture service) ─────────────────────────────────────
header "Capture"
# 200 = capture active and responding
# 404 = capture in sidecar/idle mode (no active recorder — expected in dev)
# 5xx = capture container unreachable
CAPTURE_CODE=$(curl -s -o /dev/null -w "%{http_code}" "${AUTH_ARGS[@]}" \
  "$BASE/api/v1/capture/status" 2>/dev/null)
if [[ "$CAPTURE_CODE" == "200" ]]; then
  pass "GET /capture/status  [HTTP 200 — capture active]"
elif [[ "$CAPTURE_CODE" == "404" ]]; then
  skip "GET /capture/status  [HTTP 404]" "capture in idle/sidecar mode (normal when not recording)"
elif [[ "$CAPTURE_CODE" =~ ^5 ]]; then
  skip "GET /capture/status  [HTTP $CAPTURE_CODE]" "capture container unreachable"
else
  fail "GET /capture/status  [HTTP $CAPTURE_CODE]" "unexpected status"
fi

# ── Users / Tokens ───────────────────────────────────────────────────────────
header "Users / Tokens"
check_status "GET /users"                             "/api/v1/users"              200
check_status "GET /tokens"                            "/api/v1/tokens"             200

# ── Summary ───────────────────────────────────────────────────────────────────
TOTAL=$((PASS + FAIL + SKIP))
echo ""
echo -e "${BLD}Results:${NC}  ${GRN}${PASS} passed${NC}  /  ${RED}${FAIL} failed${NC}  /  ${YEL}${SKIP} skipped${NC}  /  $TOTAL total"
echo ""

if [[ $FAIL -gt 0 ]]; then
  echo -e "${RED}Some tests failed — check output above.${NC}"
  exit 1
else
  echo -e "${GRN}All tests passed.${NC}"
fi
