#!/bin/bash

# Configuration automatique du client mobile Keycloak pour UnionFlow
# Ce script configure le client unionflow-mobile dans Keycloak

set -e

# Configuration
KEYCLOAK_URL="http://localhost:8180"
REALM="unionflow"
ADMIN_USER="admin"
ADMIN_PASSWORD="admin"
CLIENT_ID="unionflow-mobile"

echo "🔧 Configuration automatique du client mobile Keycloak..."
echo "📍 Keycloak URL: $KEYCLOAK_URL"
echo "🏛️ Realm: $REALM"
echo "📱 Client ID: $CLIENT_ID"
echo ""

# Fonction pour obtenir le token d'administration
get_admin_token() {
    echo "🔑 Obtention du token d'administration..."
    ADMIN_TOKEN=$(curl -s -X POST "$KEYCLOAK_URL/realms/master/protocol/openid-connect/token" \
        -H "Content-Type: application/x-www-form-urlencoded" \
        -d "username=$ADMIN_USER" \
        -d "password=$ADMIN_PASSWORD" \
        -d "grant_type=password" \
        -d "client_id=admin-cli" | jq -r '.access_token')
    
    if [ "$ADMIN_TOKEN" = "null" ] || [ -z "$ADMIN_TOKEN" ]; then
        echo "❌ Erreur: Impossible d'obtenir le token d'administration"
        echo "Vérifiez les credentials Keycloak (admin/admin)"
        exit 1
    fi
    echo "✅ Token d'administration obtenu"
}

# Fonction pour vérifier si le client existe déjà
check_client_exists() {
    echo "🔍 Vérification de l'existence du client $CLIENT_ID..."
    CLIENT_EXISTS=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM/clients" \
        -H "Authorization: Bearer $ADMIN_TOKEN" \
        -H "Content-Type: application/json" | jq -r ".[] | select(.clientId==\"$CLIENT_ID\") | .id")
    
    if [ -n "$CLIENT_EXISTS" ] && [ "$CLIENT_EXISTS" != "null" ]; then
        echo "⚠️ Client $CLIENT_ID existe déjà (ID: $CLIENT_EXISTS)"
        return 0
    else
        echo "ℹ️ Client $CLIENT_ID n'existe pas, création nécessaire"
        return 1
    fi
}

# Fonction pour créer le client mobile
create_mobile_client() {
    echo "📱 Création du client mobile $CLIENT_ID..."
    
    CLIENT_CONFIG='{
        "clientId": "'$CLIENT_ID'",
        "name": "UnionFlow Mobile App",
        "description": "Application mobile UnionFlow avec authentification OIDC",
        "enabled": true,
        "clientAuthenticatorType": "client-secret",
        "publicClient": true,
        "standardFlowEnabled": true,
        "implicitFlowEnabled": false,
        "directAccessGrantsEnabled": false,
        "serviceAccountsEnabled": false,
        "authorizationServicesEnabled": false,
        "rootUrl": "com.unionflow.mobile://",
        "baseUrl": "com.unionflow.mobile://home",
        "redirectUris": [
            "com.unionflow.mobile://login-callback",
            "com.unionflow.mobile://login-callback/*"
        ],
        "postLogoutRedirectUris": [
            "com.unionflow.mobile://logout-callback",
            "com.unionflow.mobile://logout-callback/*"
        ],
        "webOrigins": ["+"],
        "attributes": {
            "pkce.code.challenge.method": "S256",
            "access.token.lifespan": "900",
            "client.session.idle.timeout": "1800",
            "client.session.max.lifespan": "43200"
        },
        "defaultClientScopes": ["openid", "profile", "email", "roles"],
        "optionalClientScopes": []
    }'
    
    RESPONSE=$(curl -s -w "%{http_code}" -X POST "$KEYCLOAK_URL/admin/realms/$REALM/clients" \
        -H "Authorization: Bearer $ADMIN_TOKEN" \
        -H "Content-Type: application/json" \
        -d "$CLIENT_CONFIG")
    
    HTTP_CODE="${RESPONSE: -3}"
    if [ "$HTTP_CODE" = "201" ]; then
        echo "✅ Client mobile créé avec succès"
        
        # Récupérer l'ID du client créé
        CLIENT_UUID=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM/clients" \
            -H "Authorization: Bearer $ADMIN_TOKEN" \
            -H "Content-Type: application/json" | jq -r ".[] | select(.clientId==\"$CLIENT_ID\") | .id")
        
        echo "📋 Client UUID: $CLIENT_UUID"
        return 0
    else
        echo "❌ Erreur lors de la création du client (HTTP: $HTTP_CODE)"
        echo "Response: ${RESPONSE%???}"
        return 1
    fi
}

# Fonction pour configurer les mappers de rôles
configure_role_mappers() {
    echo "🎭 Configuration des mappers de rôles..."
    
    # Mapper pour l'audience
    AUDIENCE_MAPPER='{
        "name": "audience-mapper",
        "protocol": "openid-connect",
        "protocolMapper": "oidc-audience-mapper",
        "config": {
            "included.client.audience": "unionflow-server",
            "access.token.claim": "true"
        }
    }'
    
    # Mapper pour les rôles client
    ROLES_MAPPER='{
        "name": "client-roles-mapper",
        "protocol": "openid-connect",
        "protocolMapper": "oidc-usermodel-client-role-mapper",
        "config": {
            "client.id": "unionflow-server",
            "claim.name": "resource_access.unionflow-server.roles",
            "access.token.claim": "true",
            "id.token.claim": "false",
            "userinfo.token.claim": "false",
            "multivalued": "true"
        }
    }'
    
    # Ajouter le mapper d'audience
    curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM/clients/$CLIENT_UUID/protocol-mappers/models" \
        -H "Authorization: Bearer $ADMIN_TOKEN" \
        -H "Content-Type: application/json" \
        -d "$AUDIENCE_MAPPER" > /dev/null
    
    # Ajouter le mapper de rôles
    curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM/clients/$CLIENT_UUID/protocol-mappers/models" \
        -H "Authorization: Bearer $ADMIN_TOKEN" \
        -H "Content-Type: application/json" \
        -d "$ROLES_MAPPER" > /dev/null
    
    echo "✅ Mappers de rôles configurés"
}

# Fonction pour tester la configuration
test_configuration() {
    echo "🧪 Test de la configuration..."
    
    # Test de l'endpoint d'autorisation
    AUTH_URL="$KEYCLOAK_URL/realms/$REALM/protocol/openid-connect/auth"
    echo "📍 URL d'autorisation: $AUTH_URL"
    
    # Test de l'endpoint de token
    TOKEN_URL="$KEYCLOAK_URL/realms/$REALM/protocol/openid-connect/token"
    echo "📍 URL de token: $TOKEN_URL"
    
    # Vérifier que les endpoints répondent
    AUTH_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$AUTH_URL?client_id=$CLIENT_ID&response_type=code&redirect_uri=com.unionflow.mobile://login-callback")
    
    if [ "$AUTH_STATUS" = "200" ] || [ "$AUTH_STATUS" = "302" ]; then
        echo "✅ Endpoint d'autorisation accessible"
    else
        echo "⚠️ Endpoint d'autorisation: HTTP $AUTH_STATUS"
    fi
    
    echo "✅ Configuration testée"
}

# Fonction principale
main() {
    echo "🚀 Début de la configuration automatique..."
    echo ""
    
    # Vérifier que jq est installé
    if ! command -v jq &> /dev/null; then
        echo "❌ Erreur: jq n'est pas installé"
        echo "Installez jq avec: sudo apt-get install jq (Ubuntu) ou brew install jq (macOS)"
        exit 1
    fi
    
    # Obtenir le token d'administration
    get_admin_token
    
    # Vérifier si le client existe déjà
    if check_client_exists; then
        echo "ℹ️ Client existant trouvé, récupération de l'UUID..."
        CLIENT_UUID="$CLIENT_EXISTS"
    else
        # Créer le client mobile
        if create_mobile_client; then
            CLIENT_UUID=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM/clients" \
                -H "Authorization: Bearer $ADMIN_TOKEN" \
                -H "Content-Type: application/json" | jq -r ".[] | select(.clientId==\"$CLIENT_ID\") | .id")
        else
            echo "❌ Échec de la création du client"
            exit 1
        fi
    fi
    
    # Configurer les mappers de rôles
    configure_role_mappers
    
    # Tester la configuration
    test_configuration
    
    echo ""
    echo "🎉 Configuration terminée avec succès !"
    echo ""
    echo "📋 Résumé de la configuration:"
    echo "   • Client ID: $CLIENT_ID"
    echo "   • Client UUID: $CLIENT_UUID"
    echo "   • Type: Public (PKCE activé)"
    echo "   • Redirect URI: com.unionflow.mobile://login-callback"
    echo "   • Logout URI: com.unionflow.mobile://logout-callback"
    echo ""
    echo "🔗 URLs importantes:"
    echo "   • Authorization: $KEYCLOAK_URL/realms/$REALM/protocol/openid-connect/auth"
    echo "   • Token: $KEYCLOAK_URL/realms/$REALM/protocol/openid-connect/token"
    echo "   • Logout: $KEYCLOAK_URL/realms/$REALM/protocol/openid-connect/logout"
    echo ""
    echo "✅ L'application mobile peut maintenant s'authentifier avec Keycloak !"
}

# Exécuter le script principal
main "$@"
