#!/bin/bash
set -euo pipefail

echo "▶ Starting Zero-Downtime Blue/Green Deployment..."

: "${IMAGE?Need IMAGE}"
: "${PORT?Need PORT (Base Port)}"
: "${CONTAINER?Need CONTAINER name base}"
: "${DEPLOY_DIR?Need DEPLOY_DIR}"

cd "$DEPLOY_DIR"

PORT_BLUE=$PORT
PORT_GREEN=$((PORT + 1))

NGINX_PORT_FILE="/etc/nginx/rentpulse/active_port.conf"

# Detect current active port from the nginx active-port file (default to blue if not found)
CURRENT_PORT=$(grep -oP 'set \$backend_port \K[0-9]+' "$NGINX_PORT_FILE" 2>/dev/null || echo "$PORT_BLUE")

# Toggle logic
if [ "$CURRENT_PORT" == "$PORT_BLUE" ]; then
    NEW_PORT=$PORT_GREEN
    NEW_COLOR="green"
    OLD_COLOR="blue"
else
    NEW_PORT=$PORT_BLUE
    NEW_COLOR="blue"
    OLD_COLOR="green"
fi

NEW_CONTAINER="${CONTAINER}_${NEW_COLOR}"
OLD_CONTAINER="${CONTAINER}_${OLD_COLOR}"

echo "▶ Active Port: $CURRENT_PORT ($OLD_COLOR)"
echo "▶ Deploying to Port: $NEW_PORT ($NEW_COLOR)"

# 1. Boot the New Container safely alongside the old one
IMAGE="$IMAGE" \
APP_PORT="$NEW_PORT" \
CONTAINER_NAME="$NEW_CONTAINER" \
DJANGO_SETTINGS_MODULE="${SETTINGS:-builder.settings}" \
docker compose -p "$NEW_CONTAINER" up -d --force-recreate

# 2. Wait for the container process to come up (coarse check — not app health)
echo "▶ Waiting for $NEW_CONTAINER to stabilize..."
for i in $(seq 1 15); do
    sleep 5
    STATUS=$(docker inspect --format='{{.State.Status}}' "$NEW_CONTAINER" 2>/dev/null || echo "unknown")
    echo "  attempt $i/15 — status: $STATUS"
    [ "$STATUS" = "running" ] && break
    if [ "$i" -eq 15 ] && [ "$STATUS" != "running" ]; then
        echo "✗ Sub-container failed to start. Aborting zero-downtime switch."
        docker logs "$NEW_CONTAINER" --tail 50 2>/dev/null || true
        docker stop "$NEW_CONTAINER" 2>/dev/null || true
        exit 1
    fi
done

# 3. Real health check — retry loop, since migrations + gunicorn boot can take
#    well longer than a single early request would allow for.
echo "▶ Verifying internal HTTP heartbeat on port $NEW_PORT..."
HEARTBEAT_OK=0
for i in $(seq 1 20); do
    if curl -sf "http://127.0.0.1:$NEW_PORT" >/dev/null 2>&1; then
        echo "✓ Webserver responding (attempt $i/20)"
        HEARTBEAT_OK=1
        break
    fi
    echo "  heartbeat attempt $i/20 — not ready yet, waiting..."
    sleep 3
done

if [ "$HEARTBEAT_OK" -ne 1 ]; then
    echo "✗ Webserver not responding after $((20*3))s! Aborting switch."
    docker logs "$NEW_CONTAINER" --tail 50 2>/dev/null || true
    docker stop "$NEW_CONTAINER" 2>/dev/null || true
    exit 1
fi

# 4. SWAP Traffic instantly via nginx (graceful reload, zero downtime)
echo "▶ Success. Rerouting traffic silently..."
echo "set \$backend_port $NEW_PORT;" > "$NGINX_PORT_FILE"
if sudo nginx -t; then
    sudo systemctl reload nginx
    echo "✓ nginx now routing to port $NEW_PORT"
else
    echo "✗ nginx config test failed after port swap! Rolling back nginx port file."
    echo "set \$backend_port $CURRENT_PORT;" > "$NGINX_PORT_FILE"
    docker stop "$NEW_CONTAINER" 2>/dev/null || true
    exit 1
fi

# 5. Tear down the old container
echo "▶ Tearing down old containers ($OLD_CONTAINER and legacy $CONTAINER)..."
docker stop "$OLD_CONTAINER" "$CONTAINER" 2>/dev/null || true
docker rm "$OLD_CONTAINER" "$CONTAINER" 2>/dev/null || true

echo "✓ Zero-Downtime Deployment Complete!"