#!/usr/bin/env bash
# RemoteRig — Pi-side deploy script
# Deploys a new binary with backup, health-check, and automatic rollback.
#
# Usage:
#   sudo ./deploy.sh [BINARY_PATH] [DEPLOY_PATH] [SERVICE_NAME]
#
# Defaults:
#   BINARY_PATH   = ./remoterig (new binary to deploy)
#   DEPLOY_PATH   = /opt/remoterig/remoterig
#   SERVICE_NAME  = remoterig
#
# Examples:
#   # Deploy locally-built binary with defaults
#   sudo ./deploy.sh ./remoterig
#
#   # Custom paths
#   sudo ./deploy.sh /tmp/remoterig-arm64 /opt/remoterig/remoterig remoterig

set -euo pipefail

# ---------------------------------------------------------------------------
# Args
# ---------------------------------------------------------------------------
BINARY="${1:-remoterig}"
DEPLOY_PATH="${2:-/opt/remoterig/remoterig}"
SERVICE="${3:-remoterig}"
TIMESTAMP="$(date +%Y%m%d%H%M%S)"
BACKUP="${DEPLOY_PATH}.${TIMESTAMP}.bak"
MAX_BACKUPS=3

# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
info()  { echo "[INFO]  $*"; }
ok()    { echo "[OK]    $*"; }
fail()  { echo "[FAIL]  $*" >&2; }

# ---------------------------------------------------------------------------
# Pre-flight checks
# ---------------------------------------------------------------------------
if [ "$(id -u)" -ne 0 ]; then
    echo "ERROR: must run as root (sudo ./deploy.sh ...)" >&2
    exit 1
fi

if [ ! -f "${BINARY}" ]; then
    fail "Binary not found: ${BINARY}"
    exit 1
fi

echo "=============================================="
echo " RemoteRig Deploy"
echo " Binary:       ${BINARY}"
echo " Deploy path:  ${DEPLOY_PATH}"
echo " Service:      ${SERVICE}"
echo " Timestamp:    ${TIMESTAMP}"
echo "=============================================="

# ---------------------------------------------------------------------------
# 1. Backup existing binary
# ---------------------------------------------------------------------------
info "Backing up current binary..."
if [ -f "${DEPLOY_PATH}" ]; then
    cp "${DEPLOY_PATH}" "${BACKUP}"
    ok "Backed up to ${BACKUP}"
else
    info "No existing binary at ${DEPLOY_PATH} — fresh install"
fi

# ---------------------------------------------------------------------------
# 2. Deploy new binary
# ---------------------------------------------------------------------------
info "Deploying new binary..."
cp "${BINARY}" "${DEPLOY_PATH}"
chmod +x "${DEPLOY_PATH}"
ok "Binary installed at ${DEPLOY_PATH}"

# ---------------------------------------------------------------------------
# 3. Reload systemd and restart service
# ---------------------------------------------------------------------------
info "Reloading systemd and restarting ${SERVICE}..."
systemctl daemon-reload

# Restart (or start if not running)
if systemctl is-active --quiet "${SERVICE}" 2>/dev/null; then
    systemctl restart "${SERVICE}"
else
    systemctl start "${SERVICE}"
fi
ok "Service restart issued"

# ---------------------------------------------------------------------------
# 4. Health check
# ---------------------------------------------------------------------------
info "Waiting 3s for service to stabilize..."
sleep 3

if systemctl is-active --quiet "${SERVICE}"; then
    ok "${SERVICE} is active — deploy successful"

    # Optional: curl health endpoint
    if command -v curl >/dev/null 2>&1; then
        HEALTH_URL="http://localhost:8080/health"
        if curl -sf --max-time 3 "${HEALTH_URL}" >/dev/null 2>&1; then
            ok "Health check passed: ${HEALTH_URL}"
        else
            info "Health endpoint not reachable (may need more startup time)"
        fi
    fi
else
    fail "${SERVICE} is NOT active — rolling back"

    # -----------------------------------------------------------------------
    # 5. Rollback on failure
    # -----------------------------------------------------------------------
    if [ -f "${BACKUP}" ]; then
        info "Restoring backup: ${BACKUP}"
        cp "${BACKUP}" "${DEPLOY_PATH}"
        chmod +x "${DEPLOY_PATH}"

        systemctl restart "${SERVICE}" 2>/dev/null || true

        sleep 2
        if systemctl is-active --quiet "${SERVICE}"; then
            ok "Rollback successful — previous binary restored and service is active"
        else
            fail "Rollback failed — service still not active"
            echo "Check logs: journalctl -u ${SERVICE} -n 50" >&2
            exit 1
        fi
    else
        fail "No backup available — cannot roll back"
        echo "Check logs: journalctl -u ${SERVICE} -n 50" >&2
        exit 1
    fi
fi

# ---------------------------------------------------------------------------
# 6. Cleanup old backups (keep last N)
# ---------------------------------------------------------------------------
info "Cleaning up old backups (keeping last ${MAX_BACKUPS})..."
DEPLOY_DIR="$(dirname "${DEPLOY_PATH}")"
BASE_NAME="$(basename "${DEPLOY_PATH}")"

# List backups, skip current, keep last MAX_BACKUPS, delete the rest
ls -1t "${DEPLOY_DIR}/${BASE_NAME}."*.bak 2>/dev/null | \
    tail -n +$((MAX_BACKUPS + 1)) | \
    while IFS= read -r old_backup; do
        rm -f "${old_backup}"
        info "Removed old backup: $(basename "${old_backup}")"
    done

ok "Deploy complete — ${MAX_BACKUPS} backups retained"
echo ""
