#!/bin/bash

# Smoke Test Script for dd0c Docker Compose Stack
# Tests health endpoints, tenant creation, and key API endpoints for all services

set -euo pipefail

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

# Configuration
BASE_URL="${BASE_URL:-localhost}"
PROTOCOL="${PROTOCOL:-http}"
TS=$(date +%s)

# Port mapping (matches docker-compose.yml)
PORT_DRIFT=3002
PORT_ALERT=3003
PORT_PORTAL=3004
PORT_RUN=3006
PORT_COST=3007
PORT_ROUTE_API=3001
PORT_ROUTE_PROXY=8080
PORT_PG=5433
PORT_REDIS=6379

# Counters
TOTAL=0
PASSED=0

show_help() {
  cat << EOF
dd0c Smoke Test

Usage: $0 [OPTIONS]

Options:
  --help              Show this help
  --base-url URL      Set base URL (default: localhost)
  --protocol PROTO    Set protocol (default: http)
  --skip-rust         Skip Rust service checks (P1 route)

Examples:
  $0 --base-url 192.168.86.11
  BASE_URL=192.168.86.11 $0 --skip-rust
EOF
}

SKIP_RUST=false
while [[ $# -gt 0 ]]; do
  case $1 in
    --help) show_help; exit 0 ;;
    --base-url) BASE_URL="$2"; shift 2 ;;
    --protocol) PROTOCOL="$2"; shift 2 ;;
    --skip-rust) SKIP_RUST=true; shift ;;
    *) echo "Unknown: $1"; show_help; exit 1 ;;
  esac
done

check() {
  local name=$1 status=$2
  ((TOTAL++)) || true
  if [ "$status" = "pass" ]; then
    echo -e "  ${GREEN}✓${NC} $name" >&2
    ((PASSED++)) || true
  else
    echo -e "  ${RED}✗${NC} $name" >&2
  fi
}

url() { echo "${PROTOCOL}://${BASE_URL}:$1$2"; }

signup() {
  local port=$1 name=$2
  local resp
  resp=$(curl -s -X POST "$(url "$port" /api/v1/auth/signup)" \
    -H "Content-Type: application/json" \
    -d "{\"email\":\"smoke-${TS}@dd0c.dev\",\"password\":\"smoketest123!\",\"tenant_name\":\"Smoke ${TS}\"}" 2>/dev/null || echo "")
  local token
  token=$(echo "$resp" | grep -o '"token":"[^"]*' | cut -d'"' -f4 || echo "")
  if [ -n "$token" ]; then
    check "Signup: $name (:$port)" "pass"
    echo "$token"
  else
    check "Signup: $name (:$port) — $(echo "$resp" | head -c 80)" "fail"
    echo ""
  fi
}

login() {
  local port=$1 name=$2
  local resp
  resp=$(curl -s -X POST "$(url "$port" /api/v1/auth/login)" \
    -H "Content-Type: application/json" \
    -d "{\"email\":\"smoke-${TS}@dd0c.dev\",\"password\":\"smoketest123!\"}" 2>/dev/null || echo "")
  local token
  token=$(echo "$resp" | grep -o '"token":"[^"]*' | cut -d'"' -f4 || echo "")
  if [ -n "$token" ]; then
    check "Login: $name (:$port)" "pass"
  else
    check "Login: $name (:$port)" "fail"
  fi
}

hit() {
  local port=$1 name=$2 endpoint=$3 token=$4
  if [ -z "$token" ]; then
    check "API: $name $endpoint (no token)" "fail"
    return
  fi
  local code
  code=$(curl -s -o /dev/null -w "%{http_code}" \
    -H "Authorization: Bearer $token" \
    "$(url "$port" "$endpoint")" 2>/dev/null || echo "000")
  if [ "$code" = "200" ] || [ "$code" = "201" ]; then
    check "API: $name $endpoint" "pass"
  else
    check "API: $name $endpoint (HTTP $code)" "fail"
  fi
}

# ─── Run ───

echo -e "${YELLOW}dd0c Smoke Test — $(date -u '+%Y-%m-%d %H:%M UTC')${NC}"
echo -e "Target: ${PROTOCOL}://${BASE_URL}\n"

# 1. Infrastructure health
echo -e "${YELLOW}Infrastructure${NC}"
for pair in "drift:$PORT_DRIFT" "alert:$PORT_ALERT" "portal:$PORT_PORTAL" "run:$PORT_RUN" "cost:$PORT_COST"; do
  name=${pair%%:*}; port=${pair##*:}
  code=$(curl -s -o /dev/null -w "%{http_code}" "$(url "$port" /health)" 2>/dev/null || echo "000")
  [ "$code" = "200" ] && check "Health: $name (:$port)" "pass" || check "Health: $name (:$port) (HTTP $code)" "fail"
done

if [ "$SKIP_RUST" = false ]; then
  for pair in "route-api:$PORT_ROUTE_API" "route-proxy:$PORT_ROUTE_PROXY"; do
    name=${pair%%:*}; port=${pair##*:}
    code=$(curl -s -o /dev/null -w "%{http_code}" "$(url "$port" /health)" 2>/dev/null || echo "000")
    [ "$code" = "200" ] && check "Health: $name (:$port)" "pass" || check "Health: $name (:$port) (HTTP $code)" "fail"
  done
fi

# 2. Auth flow
echo -e "\n${YELLOW}Auth (signup → login → /me)${NC}"

ALERT_TOKEN=$(signup $PORT_ALERT "alert")
PORTAL_TOKEN=$(signup $PORT_PORTAL "portal")
COST_TOKEN=$(signup $PORT_COST "cost")
RUN_TOKEN=$(signup $PORT_RUN "run")
DRIFT_TOKEN=$(signup $PORT_DRIFT "drift")

login $PORT_ALERT "alert"

if [ -n "$ALERT_TOKEN" ]; then
  me_code=$(curl -s -o /dev/null -w "%{http_code}" \
    -H "Authorization: Bearer $ALERT_TOKEN" \
    "$(url $PORT_ALERT /api/v1/auth/me)" 2>/dev/null || echo "000")
  [ "$me_code" = "200" ] && check "Auth /me: alert" "pass" || check "Auth /me: alert (HTTP $me_code)" "fail"
fi

# 3. Product API endpoints
echo -e "\n${YELLOW}Product APIs${NC}"

hit $PORT_ALERT "alert" "/api/v1/incidents" "$ALERT_TOKEN"
hit $PORT_PORTAL "portal" "/api/v1/services" "$PORTAL_TOKEN"
hit $PORT_COST "cost" "/api/v1/baselines" "$COST_TOKEN"
hit $PORT_COST "cost" "/api/v1/anomalies" "$COST_TOKEN"
hit $PORT_RUN "run" "/api/v1/runbooks" "$RUN_TOKEN"
hit $PORT_DRIFT "drift" "/api/v1/stacks" "$DRIFT_TOKEN"

# 4. Webhook endpoints (should be accessible without auth)
echo -e "\n${YELLOW}Webhook endpoints (no auth)${NC}"
for pair in "$PORT_ALERT:alert"; do
  port=${pair%%:*}; name=${pair##*:}
  code=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
    -H "Content-Type: application/json" -d '{"alertType":"metric_alert_monitor","body":"test"}' \
    "$(url "$port" /webhooks/datadog/smoke-test)" 2>/dev/null || echo "000")
  # 400/401/404 all mean the endpoint exists (404 = unknown tenant slug, which is expected)
  if [ "$code" = "200" ] || [ "$code" = "400" ] || [ "$code" = "401" ] || [ "$code" = "404" ]; then
    check "Webhook: $name /webhooks/datadog/:slug (HTTP $code)" "pass"
  else
    check "Webhook: $name /webhooks/datadog/:slug (HTTP $code)" "fail"
  fi
done

# Summary
echo ""
echo -e "${YELLOW}═══════════════════════════${NC}"
if [ "$PASSED" -eq "$TOTAL" ]; then
  echo -e "${GREEN}ALL PASSED: $PASSED/$TOTAL${NC}"
  exit 0
else
  echo -e "${RED}$PASSED/$TOTAL passed ($((TOTAL - PASSED)) failed)${NC}"
  exit 1
fi
