#!/bin/bash
# ============================================
# Woodpecker OAuth Credentials Sync Script
# ============================================
# Dieses Script synchronisiert die Woodpecker OAuth-Credentials
# zwischen Gitea, Vault und der .env-Datei.
#
# Verwendung:
#   ./scripts/sync-woodpecker-credentials.sh [--regenerate]
#
# Optionen:
#   --regenerate  Erstellt neue OAuth-Credentials
#
# Das Script:
# 1. Liest die aktuellen Credentials aus Vault
# 2. Aktualisiert die .env-Datei
# 3. Optional: Erstellt neue Credentials in Gitea
# ============================================

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
ENV_FILE="$PROJECT_DIR/.env"

# Vault Konfiguration
VAULT_ADDR="${VAULT_ADDR:-http://localhost:8200}"
VAULT_TOKEN="${VAULT_DEV_TOKEN:-breakpilot-dev-token}"
VAULT_SECRET_PATH="secret/cicd/woodpecker"

# Gitea Konfiguration
GITEA_URL="${GITEA_URL:-http://macmini:3003}"
GITEA_API_TOKEN_PATH="secret/cicd/api-tokens"

# Farben für Output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }

# Prüfe ob Docker verfügbar ist
check_docker() {
    if command -v docker &> /dev/null; then
        DOCKER_CMD="docker"
    elif [ -x "/usr/local/bin/docker" ]; then
        DOCKER_CMD="/usr/local/bin/docker"
    else
        log_error "Docker nicht gefunden"
        exit 1
    fi
}

# Hole Credentials aus Vault
get_vault_credentials() {
    log_info "Lade Credentials aus Vault..."

    VAULT_RESPONSE=$($DOCKER_CMD exec -e VAULT_TOKEN="$VAULT_TOKEN" breakpilot-pwa-vault \
        vault kv get -format=json "$VAULT_SECRET_PATH" 2>/dev/null || echo "{}")

    if echo "$VAULT_RESPONSE" | grep -q "gitea_client_id"; then
        GITEA_CLIENT_ID=$(echo "$VAULT_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['data']['gitea_client_id'])")
        GITEA_CLIENT_SECRET=$(echo "$VAULT_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['data']['gitea_client_secret'])")
        log_info "Credentials aus Vault geladen"
        return 0
    else
        log_warn "Keine Credentials in Vault gefunden"
        return 1
    fi
}

# Aktualisiere .env Datei
update_env_file() {
    log_info "Aktualisiere .env Datei..."

    if [ -z "$GITEA_CLIENT_ID" ] || [ -z "$GITEA_CLIENT_SECRET" ]; then
        log_error "Credentials nicht verfügbar"
        return 1
    fi

    # Erstelle Backup
    cp "$ENV_FILE" "$ENV_FILE.backup"

    # Aktualisiere oder füge WOODPECKER_GITEA_CLIENT hinzu
    if grep -q "^WOODPECKER_GITEA_CLIENT=" "$ENV_FILE"; then
        sed -i.tmp "s|^WOODPECKER_GITEA_CLIENT=.*|WOODPECKER_GITEA_CLIENT=$GITEA_CLIENT_ID|" "$ENV_FILE"
    else
        echo "WOODPECKER_GITEA_CLIENT=$GITEA_CLIENT_ID" >> "$ENV_FILE"
    fi

    # Aktualisiere oder füge WOODPECKER_GITEA_SECRET hinzu
    if grep -q "^WOODPECKER_GITEA_SECRET=" "$ENV_FILE"; then
        sed -i.tmp "s|^WOODPECKER_GITEA_SECRET=.*|WOODPECKER_GITEA_SECRET=$GITEA_CLIENT_SECRET|" "$ENV_FILE"
    else
        echo "WOODPECKER_GITEA_SECRET=$GITEA_CLIENT_SECRET" >> "$ENV_FILE"
    fi

    rm -f "$ENV_FILE.tmp"
    log_info ".env aktualisiert"
}

# Erstelle neue OAuth-Credentials in Gitea
regenerate_credentials() {
    log_info "Erstelle neue OAuth-Credentials..."

    # Hole Gitea API Token aus Vault
    API_TOKEN_RESPONSE=$($DOCKER_CMD exec -e VAULT_TOKEN="$VAULT_TOKEN" breakpilot-pwa-vault \
        vault kv get -format=json "$GITEA_API_TOKEN_PATH" 2>/dev/null)
    GITEA_API_TOKEN=$(echo "$API_TOKEN_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['data']['gitea_token'])")

    # Generiere neue Credentials
    NEW_CLIENT_ID=$(uuidgen | tr '[:upper:]' '[:lower:]')
    NEW_CLIENT_SECRET=$(openssl rand -hex 32)

    # Erstelle bcrypt Hash für das Secret
    HASHED_SECRET=$($DOCKER_CMD run --rm alpine sh -c "apk add --no-cache apache2-utils >/dev/null 2>&1 && htpasswd -nbBC 10 '' '$NEW_CLIENT_SECRET' | cut -d: -f2 | sed 's/^\$2y/\$2a/'")
    HASHED_SECRET_B64=$(echo -n "$HASHED_SECRET" | base64)

    # Lösche alte OAuth Apps
    $DOCKER_CMD exec breakpilot-pwa-postgres psql -U breakpilot -d gitea -c \
        "DELETE FROM oauth2_application WHERE name = 'Woodpecker CI';" >/dev/null

    # Erstelle neue OAuth App
    TIMESTAMP=$(date +%s)
    $DOCKER_CMD exec breakpilot-pwa-postgres psql -U breakpilot -d gitea -c \
        "INSERT INTO oauth2_application (uid, name, client_id, confidential_client, redirect_uris, created_unix, updated_unix) VALUES (1, 'Woodpecker CI', '$NEW_CLIENT_ID', true, '[\"http://macmini:8090/authorize\"]', $TIMESTAMP, $TIMESTAMP);" >/dev/null

    # Setze das gehashte Secret (via base64 decode um Shell-Escaping zu vermeiden)
    DECODED_HASH=$(echo "$HASHED_SECRET_B64" | base64 -d)
    $DOCKER_CMD exec breakpilot-pwa-postgres psql -U breakpilot -d gitea -c \
        "UPDATE oauth2_application SET client_secret = '$DECODED_HASH' WHERE client_id = '$NEW_CLIENT_ID';" >/dev/null

    # Speichere in Vault
    $DOCKER_CMD exec -e VAULT_TOKEN="$VAULT_TOKEN" breakpilot-pwa-vault vault kv put "$VAULT_SECRET_PATH" \
        gitea_client_id="$NEW_CLIENT_ID" \
        gitea_client_secret="$NEW_CLIENT_SECRET" >/dev/null

    GITEA_CLIENT_ID="$NEW_CLIENT_ID"
    GITEA_CLIENT_SECRET="$NEW_CLIENT_SECRET"

    log_info "Neue Credentials erstellt und in Vault gespeichert"
}

# Hauptlogik
main() {
    check_docker

    if [ "$1" == "--regenerate" ]; then
        regenerate_credentials
    else
        get_vault_credentials || regenerate_credentials
    fi

    update_env_file

    log_info "Credentials synchronisiert!"
    echo ""
    echo "Nächste Schritte:"
    echo "1. Sync .env zu macmini: rsync -av .env macmini:~/Projekte/breakpilot-pwa/"
    echo "2. Woodpecker neu starten: docker compose restart woodpecker-server"
    echo "3. Login testen: http://macmini:8090"
}

main "$@"
