#!/usr/bin/env bash
# TDD verification script for api/Dockerfile.prod
# Fails (red) if Dockerfile.prod does not exist or any check fails.
set -euo pipefail

IMAGE="reactbin-api-prod:verify-$$"
IMAGE2="reactbin-api-prod:verify-cache-$$"
PG_CONTAINER=""
APP_CONTAINER=""

cleanup() {
    [ -n "$APP_CONTAINER" ] && docker rm -f "$APP_CONTAINER" 2>/dev/null || true
    [ -n "$PG_CONTAINER" ] && docker rm -f "$PG_CONTAINER" 2>/dev/null || true
    docker rmi "$IMAGE" 2>/dev/null || true
    docker rmi "$IMAGE2" 2>/dev/null || true
}
trap cleanup EXIT

# ── US1 check 1: build ────────────────────────────────────────────────────────
echo "[verify] Building $IMAGE..."
docker build -f api/Dockerfile.prod api/ -t "$IMAGE"
echo "[verify] Build OK"

# ── US1 check 2: start with a throwaway postgres ──────────────────────────────
echo "[verify] Starting postgres..."
PG_CONTAINER=$(docker run -d \
    -e POSTGRES_DB=reactbin_verify \
    -e POSTGRES_USER=verify \
    -e POSTGRES_PASSWORD=verify \
    postgres:16-alpine)

for i in $(seq 1 30); do
    if docker exec "$PG_CONTAINER" pg_isready -U verify -q 2>/dev/null; then break; fi
    sleep 1
    if [[ $i -eq 30 ]]; then echo "FAIL: postgres did not become ready"; exit 1; fi
done

PG_IP=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$PG_CONTAINER")

echo "[verify] Starting production container..."
APP_CONTAINER=$(docker run -d \
    -p 18000:8000 \
    -e JWT_SECRET_KEY=verify-key \
    -e OWNER_USERNAME=testowner \
    -e OWNER_PASSWORD=testpassword \
    -e DATABASE_URL="postgresql+asyncpg://verify:verify@${PG_IP}:5432/reactbin_verify" \
    -e S3_ENDPOINT_URL=http://noop:9000 \
    -e S3_BUCKET_NAME=noop \
    -e S3_ACCESS_KEY_ID=noop \
    -e S3_SECRET_ACCESS_KEY=noop \
    -e S3_REGION=us-east-1 \
    "$IMAGE")

# ── US1 check 3: health endpoint ──────────────────────────────────────────────
echo "[verify] Polling health endpoint..."
for i in $(seq 1 30); do
    if curl -sf http://localhost:18000/api/v1/health > /dev/null; then break; fi
    sleep 1
    if [[ $i -eq 30 ]]; then echo "FAIL: health check timed out after 30s"; exit 1; fi
done
echo "[verify] Health check passed"

# ── US2 check 1: non-root user ────────────────────────────────────────────────
UID_IN_CONTAINER=$(docker exec "$APP_CONTAINER" id -u)
if [[ "$UID_IN_CONTAINER" -eq 0 ]]; then
    echo "FAIL: process running as root (UID 0)"; exit 1
fi
echo "[verify] Non-root user OK (UID $UID_IN_CONTAINER)"

# ── C1: stdout/stderr log capture ────────────────────────────────────────────
LOGS=$(docker logs "$APP_CONTAINER" 2>&1)
if [[ -z "$LOGS" ]]; then
    echo "FAIL: no output on stdout/stderr"; exit 1
fi
if ! echo "$LOGS" | grep -qiE "(started server|application startup complete|uvicorn)"; then
    echo "FAIL: no startup logs found on stdout/stderr"; exit 1
fi
echo "[verify] Stdout logging OK"

# ── US1 check 4: SIGTERM → exit 0 ────────────────────────────────────────────
docker stop "$APP_CONTAINER" > /dev/null
EXIT_CODE=$(docker wait "$APP_CONTAINER")
if [[ "$EXIT_CODE" -ne 0 ]]; then
    echo "FAIL: non-zero exit code $EXIT_CODE after SIGTERM"; exit 1
fi
echo "[verify] Graceful shutdown OK (exit $EXIT_CODE)"

# ── US2 check 2: dev deps absent ─────────────────────────────────────────────
if docker run --rm "$IMAGE" /app/.venv/bin/python -c "import pytest" 2>/dev/null; then
    echo "FAIL: pytest importable in production image (dev deps present)"; exit 1
fi
echo "[verify] Dev deps absent OK"

# ── C2: no hardcoded secrets in image layers ─────────────────────────────────
if docker history --no-trunc "$IMAGE" 2>&1 | grep -qiE "(password|secret_key|api_key|token)"; then
    echo "FAIL: potential secret found in image history"; exit 1
fi
echo "[verify] No secrets in image layers OK"

# ── C3: missing env var → non-zero exit ──────────────────────────────────────
set +e
docker run --rm -e JWT_SECRET_KEY=verify-key "$IMAGE" 2>/dev/null
MISSING_ENV_EXIT=$?
set -e
if [[ "$MISSING_ENV_EXIT" -eq 0 ]]; then
    echo "FAIL: container exited 0 despite missing OWNER_USERNAME"; exit 1
fi
echo "[verify] Missing-env-var exit check OK (exit $MISSING_ENV_EXIT)"

# ── US3: dep layer cached on source-only rebuild ──────────────────────────────
echo "[verify] Testing cache hit on source-only rebuild..."
touch api/app/main.py
BUILD2_OUTPUT=$(docker build --progress=plain -f api/Dockerfile.prod api/ -t "$IMAGE2" 2>&1)
if ! echo "$BUILD2_OUTPUT" | grep -q "CACHED"; then
    echo "FAIL: dependency layer not reused on source-only rebuild"; exit 1
fi
echo "[verify] Dep layer cache hit confirmed (US3 OK)"

echo "[verify] All checks passed (US1 + US2 + US3)."
