#!/bin/bash
set -e

echo "========================================="
echo "   NexusGuard SD-WAN: SYSTEM UPDATE      "
echo "========================================="

STATE_FILE=".update-state"
FORCE_REBUILD=false
BACKUP=false
NO_MIGRATE=false

# Parse command line arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        --force)
            FORCE_REBUILD=true
            shift
            ;;
        --backup)
            BACKUP=true
            shift
            ;;
        --no-migrate)
            NO_MIGRATE=true
            shift
            ;;
        *)
            echo "[!] Unknown option: $1"
            exit 1
            ;;
    esac
done

# 1. Pastikan file env ada
if [ ! -f .env ]; then
    echo "[-] ERROR: .env file not found. Please run ./setup.sh first to initialize configuration."
    exit 1
fi

# 2. Update Code dari Git (Main & Submodules)
echo "[+] Pulling latest source code from repository..."
GIT_PULL_FAILED=false
git pull origin main || { GIT_PULL_FAILED=true; echo "[!] Git pull for main repo skipped or failed, continuing..."; }

echo "[+] Syncing and updating submodules..."
SUBMODULE_FAILED=false
git submodule update --init --recursive --remote || { SUBMODULE_FAILED=true; echo "[!] Git submodule update skipped or failed."; }

# 3. Hitung state hash (git + .env) untuk deteksi perubahan
CURRENT_HASH=$(echo "$(git rev-parse HEAD 2>/dev/null)$(git submodule status 2>/dev/null)$(sha256sum .env 2>/dev/null)" | sha256sum | cut -d" " -f1)

# 4. Tentukan apakah perlu rebuild
NEEDS_REBUILD=false
if [ "$FORCE_REBUILD" = true ]; then
    echo "[+] --force flag detected. Will rebuild."
    NEEDS_REBUILD=true
elif [ "$GIT_PULL_FAILED" = true ] || [ "$SUBMODULE_FAILED" = true ]; then
    echo "[!] Git operation failed. Rebuilding as safe fallback."
    NEEDS_REBUILD=true
elif [ ! -f "$STATE_FILE" ]; then
    echo "[+] First run (no state file found). Full cycle required."
    NEEDS_REBUILD=true
else
    PREVIOUS_HASH=$(cat "$STATE_FILE" 2>/dev/null || echo "")
    if [ "$CURRENT_HASH" != "$PREVIOUS_HASH" ]; then
        echo "[+] State hash changed. Rebuilding."
        NEEDS_REBUILD=true
    else
        echo "[-] No changes detected. Skipping build and restart."
    fi
fi

# 5. Rebuild cycle — hanya jika ada perubahan
if [ "$NEEDS_REBUILD" = true ]; then
    # Source .env untuk build process
    echo "[+] Sourcing environment variables from root .env..."
    set -a && . .env && set +a

    # Volume safety check
    echo "[+] Checking PostgreSQL volume safety..."
    if ! docker volume inspect pgdata >/dev/null 2>&1; then
        echo "[!] WARNING: PostgreSQL volume 'pgdata' not found. It will be created on container startup."
        echo "[!] If you expect existing data, check your volume configuration."
    else
        echo "[+] PostgreSQL volume 'pgdata' found."
    fi

    # Backup option
    if [ "$BACKUP" = true ]; then
        echo "[+] Creating backup of PostgreSQL data..."
        BACKUP_DIR="./backups"
        mkdir -p "$BACKUP_DIR"
        TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
        BACKUP_FILE="$BACKUP_DIR/pgdata_backup_$TIMESTAMP.tar"
        
        # Backup the volume using a temporary container
        if docker run --rm -v pgdata:/data -v "$(pwd)/$BACKUP_DIR":/backup ubuntu tar czf "/backup/pgdata_backup_$TIMESTAMP.tar.gz" -C /data . 2>/dev/null; then
            echo "[+] Backup created successfully: $BACKUP_FILE.gz"
        else
            echo "[!] Backup failed. Continuing without backup."
        fi
    fi

    # Password sync if DB_PASSWORD changed
    echo "[+] Checking for PostgreSQL password synchronization..."
    # Get current DB_PASSWORD from .env
    CURRENT_DB_PASSWORD="${DB_PASSWORD:-nexusguard}"
    
    # Try to connect to existing postgres container and update password if needed
    POSTGRES_CONTAINER=$(docker compose ps -q postgres 2>/dev/null)
    if [ -n "$POSTGRES_CONTAINER" ]; then
        echo "[+] Found running PostgreSQL container. Checking password..."
        # Test if current password works
        if docker exec "$POSTGRES_CONTAINER" pg_isready -U nexusguard -d nexusguard 2>/dev/null; then
            echo "[+] Current password works. No password update needed."
        else
            echo "[!] Current password failed. Attempting to update PostgreSQL password to match .env..."
            # Try to alter user password (requires superuser or same user)
            if docker exec -u postgres "$POSTGRES_CONTAINER" psql -c "ALTER USER nexusguard WITH PASSWORD '$CURRENT_DB_PASSWORD';" 2>/dev/null; then
                echo "[+] PostgreSQL password updated successfully."
            else
                echo "[!] Failed to update password. You may need to manually update it or check permissions."
                echo "[!] Continuing update - authentication may fail if password mismatch."
            fi
        fi
    else
        echo "[i] No running PostgreSQL container found. Password will be set on container initialization (if data directory is empty)."
    fi

    echo "[+] Stopping existing containers..."
    docker compose down

    echo "[+] Rebuilding Docker images..."
    docker compose build --build-arg VITE_API_BASE_URL=$VITE_API_BASE_URL

    echo "[+] Restarting containers..."
    docker compose up -d

    if [ "$NO_MIGRATE" = false ]; then
        echo "[+] Running automated database migrations..."
        docker exec nexus-guard-suite-server-core-1 ./server-core -migrate-prod || echo "[!] Migration skipped or failed. It might not be needed."
    else
        echo "[+] Skipping database migration (--no-migrate flag used)."
    fi

    echo "[+] Backfilling interface addresses..."
    docker exec nexus-guard-suite-server-core-1 ./server-core -backfill-interface 2>/dev/null || echo "[!] Backfill skipped or not needed."

    echo "[+] Cleaning up unused dangling images..."
    docker image prune -f

    # Simpan state secara atomik (tmp + mv untuk cegah korupsi file)
    echo "$CURRENT_HASH" > "$STATE_FILE.tmp" && mv "$STATE_FILE.tmp" "$STATE_FILE"

    echo "========================================="
    echo " Update & Deployment complete!           "
    echo " Dashboard : http://localhost:${WEB_PORT:-80}"
    echo " API Port  : ${API_PORT:-8080}"
    if [ "$BACKUP" = true ]; then
        echo " Backup    : Stored in ./backups/ directory"
    fi
    echo "========================================="
else
    echo "========================================="
    echo " No update needed — system is current.   "
    echo "========================================="
fi