#!/usr/bin/env bash
#
# Command Sovereignty: SQLite to PostgreSQL Migration Script
#
# Usage: ./scripts/migrate-to-postgres.sh
#
# WARNING: This will stop your service, spin up a local PostgreSQL container,
# dump your SQLite data into it, and switch your app to use PostgreSQL.
# Your SQLite database will be backed up before proceeding.
#

set -euo pipefail

PROJECT_DIR="/home/vincent/projects/command-sovereignty"
DB_SQLITE="$PROJECT_DIR/instance/auth.db"
ENV_FILE="$HOME/.config/command-sovereignty/env"
BACKUP_DIR="$PROJECT_DIR/backups"
LOG_FILE="$PROJECT_DIR/logs/migration.log"

PG_USER="postgres"
PG_DB="commandsovereignty"
PG_PORT=5432
PG_CONTAINER="cs-postgres-local"
# Generate a secure random password for the local DB
PG_PASS="cs_local_pg_$(openssl rand -hex 12)"

mkdir -p "$BACKUP_DIR" "$(dirname "$LOG_FILE")"

log() {
    local msg="[$(date '+%Y-%m-%d %H:%M:%S')] $1"
    echo "$msg" | tee -a "$LOG_FILE"
}

die() {
    log "FATAL: $1"
    exit 1
}

# 1. Pre-flight checks
log "Starting migration to PostgreSQL..."

if ! command -v docker &> /dev/null; then
    die "Docker is not installed or not in PATH."
fi

if ! command -v psql &> /dev/null; then
    log "psql client is not installed. Installing postgresql-client..."
    sudo apt-get update && sudo apt-get install -y postgresql-client
fi

if ! command -v sqlite3 &> /dev/null; then
    die "sqlite3 is not installed. Run: sudo apt install sqlite3"
fi

if [ ! -f "$DB_SQLITE" ]; then
    die "SQLite database not found at $DB_SQLITE"
fi

# 2. Stop the current service
log "Stopping Command Sovereignty service..."
systemctl --user stop command-sovereignty.service || true
sleep 2

# 3. Backup the current SQLite DB
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/auth_${TIMESTAMP}_pre_pg_migration.db.gz"
log "Backing up SQLite DB to $BACKUP_FILE..."
gzip -c "$DB_SQLITE" > "$BACKUP_FILE"

# 4. Spin up PostgreSQL
log "Spinning up PostgreSQL container ($PG_CONTAINER)..."
docker rm -f "$PG_CONTAINER" > /dev/null 2>&1 || true
docker run -d \
    --name "$PG_CONTAINER" \
    -e POSTGRES_USER="$PG_USER" \
    -e POSTGRES_PASSWORD="$PG_PASS" \
    -e POSTGRES_DB="$PG_DB" \
    -p "$PG_PORT:5432" \
    postgres:16-alpine

# 5. Wait for PostgreSQL to be ready
log "Waiting for PostgreSQL to initialize..."
WAIT=0
while ! docker exec "$PG_CONTAINER" pg_isready -U "$PG_USER" > /dev/null 2>&1; do
    sleep 1
    WAIT=$((WAIT + 1))
    if [ "$WAIT" -gt 30 ]; then
        die "PostgreSQL failed to start within 30 seconds."
    fi
done
log "PostgreSQL is ready."

# 6. Dump SQLite and load into PostgreSQL
log "Dumping SQLite and importing to PostgreSQL..."
sqlite3 "$DB_SQLITE" .dump | \
    psql -h 127.0.0.1 -p "$PG_PORT" -U "$PG_USER" -d "$PG_DB" -v ON_ERROR_STOP=1 \
    --password -w <<<"$PG_PASS"

if [ $? -ne 0 ]; then
    die "Database import failed. Check $LOG_FILE for details."
fi

# 7. Verify data
PROFILES_SQLITE=$(sqlite3 "$DB_SQLITE" "SELECT count(*) FROM profiles;")
PROFILES_PG=$(psql -h 127.0.0.1 -p "$PG_PORT" -U "$PG_USER" -d "$PG_DB" -t -c "SELECT count(*) FROM profiles;" --password -w <<<"$PG_PASS")

if [ "$PROFILES_SQLITE" != "$PROFILES_PG" ]; then
    die "Data mismatch! SQLite had $PROFILES_SQLITE profiles, Postgres has $PROFILES_PG."
fi

log "Data verified: $PROFILES_PG profiles in PostgreSQL."

# 8. Update Environment Config
log "Updating environment config at $ENV_FILE..."
NEW_URL="DATABASE_URL=postgresql://$PG_USER:$PG_PASS@127.0.0.1:$PG_PORT/$PG_DB"

# Backup env file
cp "$ENV_FILE" "${ENV_FILE}.bak.${TIMESTAMP}"

# Replace DATABASE_URL line
if grep -q "^DATABASE_URL" "$ENV_FILE"; then
    sed -i "s|^DATABASE_URL=.*|$NEW_URL|" "$ENV_FILE"
else
    echo "$NEW_URL" >> "$ENV_FILE"
fi

# 9. Restart the service
log "Restarting Command Sovereignty service..."
systemctl --user restart command-sovereignty.service

# 10. Verify health
sleep 3
log "Waiting for app to start..."
HEALTH=$(curl -s http://127.0.0.1:5003/health 2>/dev/null || echo '{"status":"error"}')

echo ""
log "=========================================="
if echo "$HEALTH" | grep -q '"healthy"'; then
    log "Migration SUCCESSFUL!"
    log "App is running on PostgreSQL."
else
    log "Migration COMPLETED but app health check returned: $HEALTH"
    log "Check logs at $PROJECT_DIR/logs/app.log"
fi

log "=========================================="
log "PostgreSQL Credentials:"
log "  Host: 127.0.0.1:$PG_PORT"
log "  DB:   $PG_DB"
log "  User: $PG_USER"
log "  Pass: $PG_PASS"
log "=========================================="