#!/bin/bash
#
# db-direct.sh - Direkte PostgreSQL-Verbindung (umgeht PgBouncer)
#
# Verwendung:
#   ./scripts/db-direct.sh migrate        # Migrationen ausführen
#   ./scripts/db-direct.sh migrate:create # Migration erstellen
#   ./scripts/db-direct.sh psql           # Interaktive psql-Session
#   ./scripts/db-direct.sh query "SQL"    # SQL-Query ausführen
#
# Credentials werden aus ~/.pgpass gelesen (Format: host:port:database:user:password)
# Alternativ: DB_PASSWORD Umgebungsvariable setzen
#

set -e

# Konfiguration (keine Secrets hier!)
DB_HOST="${DB_HOST:-10.10.181.101}"
DB_PORT="${DB_PORT:-5432}"
DB_NAME="${DB_NAME:-payload_db}"
DB_USER="${DB_USER:-payload}"

# Farbige Ausgabe
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

error() { echo -e "${RED}ERROR: $1${NC}" >&2; exit 1; }
info() { echo -e "${GREEN}$1${NC}"; }
warn() { echo -e "${YELLOW}$1${NC}"; }

# Passwort aus ~/.pgpass oder Umgebungsvariable lesen
get_password() {
    if [[ -n "${DB_PASSWORD:-}" ]]; then
        echo "$DB_PASSWORD"
        return
    fi

    local pgpass="$HOME/.pgpass"
    if [[ -f "$pgpass" ]]; then
        # Format: host:port:database:user:password
        local password
        password=$(grep "^${DB_HOST}:${DB_PORT}:${DB_NAME}:${DB_USER}:" "$pgpass" 2>/dev/null | cut -d: -f5)
        if [[ -n "$password" ]]; then
            echo "$password"
            return
        fi
        # Fallback: Wildcard-Einträge prüfen
        password=$(grep "^\*:\*:\*:${DB_USER}:" "$pgpass" 2>/dev/null | cut -d: -f5)
        if [[ -n "$password" ]]; then
            echo "$password"
            return
        fi
    fi

    error "Kein Passwort gefunden. Setze DB_PASSWORD oder erstelle ~/.pgpass"
}

# URL-Encode für Passwörter mit Sonderzeichen
urlencode() {
    local string="$1"
    local strlen=${#string}
    local encoded=""
    local pos c o

    for (( pos=0 ; pos<strlen ; pos++ )); do
        c=${string:$pos:1}
        case "$c" in
            [-_.~a-zA-Z0-9] ) o="$c" ;;
            * ) printf -v o '%%%02X' "'$c" ;;
        esac
        encoded+="$o"
    done
    echo "$encoded"
}

# Temporäre .env-Datei für sichere Credential-Übergabe
# Vermeidet Credential-Leak via `ps` command
run_with_direct_db() {
    local cmd="$1"
    shift

    local password
    password=$(get_password)
    local encoded_password
    encoded_password=$(urlencode "$password")

    # Temporäre Datei mit restriktiven Permissions
    local temp_env
    temp_env=$(mktemp)
    chmod 600 "$temp_env"

    # Trap für Cleanup bei Abbruch
    trap "rm -f '$temp_env'" EXIT

    # Nur DATABASE_URI in temp file, Rest aus Umgebung
    echo "DATABASE_URI=postgresql://${DB_USER}:${encoded_password}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=require" > "$temp_env"

    # Führe Befehl mit env aus temp file aus (nicht sichtbar in ps)
    env $(cat "$temp_env") "$cmd" "$@"
    local exit_code=$?

    # Cleanup
    rm -f "$temp_env"
    trap - EXIT

    return $exit_code
}

# Hauptlogik
case "${1:-help}" in
    migrate)
        info "Führe Migrationen direkt auf PostgreSQL aus (umgeht PgBouncer)..."
        warn "Host: ${DB_HOST}:${DB_PORT}"
        run_with_direct_db pnpm payload migrate
        info "Migrationen abgeschlossen."
        ;;

    migrate:create)
        info "Erstelle neue Migration..."
        run_with_direct_db pnpm payload migrate:create
        ;;

    migrate:status)
        info "Migrations-Status..."
        run_with_direct_db pnpm payload migrate:status
        ;;

    psql)
        info "Öffne interaktive psql-Session..."
        warn "Host: ${DB_HOST}:${DB_PORT}"
        # psql nutzt PGPASSWORD - nicht in ps sichtbar wenn via env gesetzt
        PGPASSWORD="$(get_password)" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME"
        ;;

    query)
        if [[ -z "${2:-}" ]]; then
            error "SQL-Query erforderlich: ./scripts/db-direct.sh query \"SELECT ...\""
        fi
        PGPASSWORD="$(get_password)" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "$2"
        ;;

    test)
        info "Teste direkte Verbindung zu PostgreSQL..."
        if PGPASSWORD="$(get_password)" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "SELECT 1;" > /dev/null 2>&1; then
            info "Verbindung erfolgreich!"
            PGPASSWORD="$(get_password)" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "SELECT version();"
        else
            error "Verbindung fehlgeschlagen!"
        fi
        ;;

    help|--help|-h|*)
        cat << EOF
db-direct.sh - Direkte PostgreSQL-Verbindung (umgeht PgBouncer)

Verwendung:
  ./scripts/db-direct.sh <command>

Commands:
  migrate         Migrationen ausführen
  migrate:create  Neue Migration erstellen
  migrate:status  Migrations-Status anzeigen
  psql            Interaktive psql-Session
  query "SQL"     SQL-Query ausführen
  test            Verbindung testen
  help            Diese Hilfe anzeigen

Konfiguration:
  DB_HOST         PostgreSQL Host (default: 10.10.181.101)
  DB_PORT         PostgreSQL Port (default: 5432)
  DB_NAME         Datenbank (default: payload_db)
  DB_USER         Benutzer (default: payload)
  DB_PASSWORD     Passwort (oder ~/.pgpass verwenden)

Beispiel ~/.pgpass (chmod 600):
  10.10.181.101:5432:payload_db:payload:DEIN_PASSWORT

Sicherheit:
  - Credentials werden URL-encoded (Sonderzeichen-safe)
  - DATABASE_URI wird via temp file übergeben (nicht in ps sichtbar)
  - Temp files haben chmod 600 und werden sofort gelöscht

EOF
        ;;
esac
