#!/usr/bin/env bash
# ──────────────────────────────────────────────────────────────────────────────
# CompuTrace Reporting — Production Setup Script
# Run once on a fresh Linux host to build and start the full stack.
# Usage: chmod +x setup.sh && ./setup.sh
# ──────────────────────────────────────────────────────────────────────────────
set -euo pipefail

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
info()  { echo -e "${GREEN}[INFO]${NC}  $*"; }
warn()  { echo -e "${YELLOW}[WARN]${NC}  $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }

# ── 1. Prerequisites ───────────────────────────────────────────────────────────
info "Checking prerequisites..."

command -v docker &>/dev/null        || error "Docker is not installed. Install from https://docs.docker.com/engine/install/"
docker compose version &>/dev/null   || error "'docker compose' plugin not found. Install Docker Compose v2."
docker info &>/dev/null              || error "Docker daemon is not running. Start it with: sudo systemctl start docker"

info "Docker $(docker --version | awk '{print $3}' | tr -d ',')"
info "Docker Compose $(docker compose version --short)"

# ── 2. Environment file ────────────────────────────────────────────────────────
if [ ! -f .env ]; then
    if [ -f .env.example ]; then
        cp .env.example .env
        warn ".env not found — copied from .env.example"
        warn "Please fill in all required values in .env then re-run this script."
        echo ""
        echo "  Required fields to fill in:"
        echo "    DB_HOST         — IP or hostname of your MySQL database server"
        echo "    DB_PASSWORD     — database user password"
       # echo "    AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID — from Azure portal"
       # echo "    AZURE_REDIRECT_URI — http://<this-server-ip>/api/auth/callback"
        echo "    JWT_SECRET      — random string (min 32 chars), generate with:"
        echo "                      openssl rand -base64 48"
       # echo "    CLIENT_URL      — http://<this-server-ip>"
        echo ""
        exit 1
    else
        error ".env.example not found. Cannot create .env."
    fi
fi

# ── 3. Validate required env vars ─────────────────────────────────────────────
info "Validating .env..."

# Source .env (ignore lines starting with # and blank lines)
set -o allexport
# shellcheck disable=SC1091
source <(grep -v '^\s*#' .env | grep -v '^\s*$')
set +o allexport

MISSING=()
[ -z "${DB_HOST:-}"             ] && MISSING+=("DB_HOST")
[ -z "${DB_PASSWORD:-}"         ] && MISSING+=("DB_PASSWORD")
[ -z "${AZURE_REDIRECT_URI:-}"  ] && MISSING+=("AZURE_REDIRECT_URI")
[ -z "${JWT_SECRET:-}"          ] && MISSING+=("JWT_SECRET")
[ -z "${CLIENT_URL:-}"          ] && MISSING+=("CLIENT_URL")

if [ ${#MISSING[@]} -gt 0 ]; then
    error "Missing required values in .env: ${MISSING[*]}"
fi

# Warn if placeholder values are still present
if echo "${DB_HOST}" | grep -qi "your_\|example\|placeholder"; then
    error "DB_HOST still contains a placeholder value. Set it to your actual database host."
fi
if echo "${CLIENT_URL}" | grep -qi "YOUR_SERVER"; then
    error "CLIENT_URL still contains a placeholder. Set it to http://<this-server-ip>."
fi
if echo "${AZURE_REDIRECT_URI}" | grep -qi "YOUR_SERVER"; then
    error "AZURE_REDIRECT_URI still contains a placeholder. Update it with your server IP."
fi

JWT_LEN=${#JWT_SECRET}
if [ "$JWT_LEN" -lt 32 ]; then
    error "JWT_SECRET must be at least 32 characters (currently $JWT_LEN). Generate one with: openssl rand -base64 48"
fi

info ".env looks good."

# ── 4. Build images ────────────────────────────────────────────────────────────
info "Building Docker images (this may take a few minutes on first run)..."
docker compose build --no-cache

# ── 5. Start services ─────────────────────────────────────────────────────────
info "Starting services..."
docker compose up -d

# ── 6. Wait for health checks ─────────────────────────────────────────────────
info "Waiting for services to become healthy..."

wait_healthy() {
    local service="$1"
    local max_wait=120
    local elapsed=0
    local interval=5

    while [ $elapsed -lt $max_wait ]; do
        status=$(docker compose ps --format json "$service" 2>/dev/null \
            | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('Health',''))" 2>/dev/null \
            || docker inspect --format='{{.State.Health.Status}}' "$(docker compose ps -q "$service")" 2>/dev/null \
            || echo "unknown")

        if [ "$status" = "healthy" ]; then
            info "$service is healthy."
            return 0
        fi

        echo -n "  Waiting for $service... ($elapsed s)"$'\r'
        sleep $interval
        elapsed=$((elapsed + interval))
    done

    warn "$service did not become healthy within ${max_wait}s. Check logs: docker compose logs $service"
    return 1
}

wait_healthy redis
wait_healthy server

# ── 7. Verify app is reachable ────────────────────────────────────────────────
info "Checking application health endpoint..."
sleep 3
if curl -sf "http://localhost/api/health" -o /dev/null; then
    info "Health check passed — API is reachable."
else
    warn "Health endpoint did not respond at http://localhost/api/health"
    warn "Check logs with: docker compose logs server"
fi

# ── 8. Done ───────────────────────────────────────────────────────────────────
echo ""
echo -e "${GREEN}══════════════════════════════════════════════${NC}"
echo -e "${GREEN}  CompuTrace Reporting is up and running!     ${NC}"
echo -e "${GREEN}══════════════════════════════════════════════${NC}"
echo ""
echo "  App:    http://$(hostname -I | awk '{print $1}')"
echo "  Health: http://$(hostname -I | awk '{print $1}')/api/health"
echo ""
echo "  Useful commands:"
echo "    docker compose ps           — check service status"
echo "    docker compose logs -f      — tail all logs"
echo "    docker compose logs server  — server logs only"
echo "    docker compose down         — stop everything"
echo ""
echo "  To update after a git pull:"
echo "    docker compose build --no-cache && docker compose up -d"
echo ""
