#!/usr/bin/env bash
# -----------------------------------------------------------------------------
# tests/smoke.sh
#
# Appelle les endpoints clés de l'API et vérifie les codes HTTP attendus.
# Sortie non-zéro si au moins un appel échoue.
#
# Usage :
#   ADMIN_TOKEN=xxxxx [INFOLAB_URL=http://localhost:8003] ./tests/smoke.sh
#
# Idempotent : un cleanup best-effort en début de script supprime les ressources
# de test (projet "nos-ecoles" + membre "collectif-des-ecoles-de-marseille").
# -----------------------------------------------------------------------------
set -uo pipefail

URL="${INFOLAB_URL:-http://localhost:8003}"
TOKEN="${ADMIN_TOKEN:-}"

if [[ -z "$TOKEN" ]]; then
    echo "ERR: variable d'env ADMIN_TOKEN requise" >&2
    exit 2
fi

PASS=0
FAIL=0
BODY="$(mktemp -t smoke.XXXXXX 2>/dev/null || mktemp)"
trap 'rm -f "$BODY"' EXIT

# Appelle un endpoint et vérifie le code HTTP. Logue un extrait du body.
# Args : label expected_code method path [body_json]
call() {
    local label="$1" expected="$2" method="$3" path="$4" body="${5:-}"
    local -a headers=(-H 'Accept: application/json')
    if [[ -n "$body" ]]; then
        headers+=(-H 'Content-Type: application/json')
    fi
    if [[ "$method" != "GET" ]]; then
        headers+=(-H "Authorization: Bearer $TOKEN")
    fi

    local code
    if [[ -n "$body" ]]; then
        # Important : on pipe le body via stdin avec --data-binary @-, pas via argv.
        # Sur Windows/Git Bash, passer un body UTF-8 en argument à curl convertit
        # les bytes multi-octets en cp1252 et casse le JSON. stdin = binary safe.
        code=$(printf '%s' "$body" \
               | curl -sS -o "$BODY" -w '%{http_code}' -X "$method" "${headers[@]}" --data-binary @- "$URL$path")
    else
        code=$(curl -sS -o "$BODY" -w '%{http_code}' -X "$method" "${headers[@]}" "$URL$path")
    fi

    local snip
    snip=$(head -c 220 "$BODY" 2>/dev/null || echo '')

    if [[ "$code" == "$expected" ]]; then
        printf '  OK   [%s] %-6s %s — %s\n' "$code" "$method" "$path" "$label"
        printf '       > %s\n' "$snip"
        PASS=$((PASS+1))
    else
        printf '  FAIL [%s, attendu %s] %-6s %s — %s\n' "$code" "$expected" "$method" "$path" "$label"
        printf '       > %s\n' "$snip"
        FAIL=$((FAIL+1))
    fi
}

# Extrait le 1er "id":N du body courant.
extract_id() {
    sed -n 's/.*"id":[[:space:]]*\([0-9][0-9]*\).*/\1/p' "$BODY" | head -1
}

# Compte les occurrences de "id":N dans le body (approximation suffisante pour les listes).
count_ids() {
    grep -oE '"id":[[:space:]]*[0-9]+' "$BODY" | wc -l | tr -d ' '
}

echo "== Smoke test infolab @ $URL =="

# Cleanup best-effort : autorise les ré-exécutions.
curl -sS -o /dev/null -X DELETE -H "Authorization: Bearer $TOKEN" "$URL/api/projects/nos-ecoles" >/dev/null 2>&1 || true
curl -sS -o /dev/null -X DELETE -H "Authorization: Bearer $TOKEN" "$URL/api/members/collectif-des-ecoles-de-marseille" >/dev/null 2>&1 || true

# 1) Sanity
call "Health"            200 GET /api/health

# 2) Catégories seedées
call "Categories list"   200 GET /api/categories
count=$(count_ids)
if [[ "$count" == "6" ]]; then
    echo "  OK   categories.length = 6"
    PASS=$((PASS+1))
else
    echo "  FAIL categories.length = $count (attendu 6)"
    FAIL=$((FAIL+1))
fi

# Récupère l'id de "education-ecoles" pour ne pas dépendre de l'auto-increment.
curl -sS -o "$BODY" "$URL/api/categories/education-ecoles" >/dev/null
CAT_ID=$(extract_id)
CAT_ID="${CAT_ID:-6}"

# 3) Création du membre
MEMBER_BODY=$(cat <<'JSON'
{"display_name":"Collectif des écoles de Marseille","kind":"collective","bio":"Réseau citoyen pour les écoles publiques marseillaises."}
JSON
)
call "Create member"     201 POST /api/members "$MEMBER_BODY"

# 4) Création du projet (ré-utilise CAT_ID dynamique)
PROJECT_BODY=$(cat <<JSON
{"title":"Nos Écoles","category_id":$CAT_ID,"status":"active","short_description":"Plateforme citoyenne pour partager l'état des écoles publiques.","context_description":"Issu de la mobilisation citoyenne de 2024.","objectives":"Cartographier, partager, alerter.","progress_percent":25}
JSON
)
call "Create project"    201 POST /api/projects "$PROJECT_BODY"

# 5) Rattachement du membre au projet
call "Add team member"   201 POST /api/projects/nos-ecoles/members \
    '{"member_slug":"collectif-des-ecoles-de-marseille","role":"admin"}'

# 6) Étape de roadmap (apostrophe via heredoc pour éviter les soucis de quoting)
ROADMAP_BODY=$(cat <<'JSON'
{"title":"Création de l'outil 15min","description":"Premier MVP en 15 minutes.","is_done":false}
JSON
)
call "Add roadmap step"  201 POST /api/projects/nos-ecoles/roadmap "$ROADMAP_BODY"

# 7) Vérifie le détail complet du projet
call "Project detail"    200 GET /api/projects/nos-ecoles

# 8) KPIs et flux d'activité
call "Stats"             200 GET /api/stats
call "Activity"          200 GET /api/activity

echo
echo "==== Résumé ===="
echo "  OK   : $PASS"
echo "  FAIL : $FAIL"

if [[ "$FAIL" -gt 0 ]]; then
    exit 1
fi
exit 0
