#!/bin/bash
set -euo pipefail

# Keycloak Deployment Script
# This script deploys and configures Keycloak for Sankofa Phoenix

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

# Colors for 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"
}

# Check prerequisites
check_prerequisites() {
    log_info "Checking prerequisites..."
    
    if ! command -v kubectl &> /dev/null; then
        log_error "kubectl is not installed"
        exit 1
    fi
    
    if ! command -v helm &> /dev/null; then
        log_error "helm is not installed"
        exit 1
    fi
    
    if ! kubectl cluster-info &> /dev/null; then
        log_error "Cannot connect to Kubernetes cluster"
        exit 1
    fi
    
    log_info "Prerequisites check passed"
}

# Generate random password
generate_password() {
    openssl rand -base64 32 | tr -d "=+/" | cut -c1-25
}

# Deploy PostgreSQL for Keycloak
deploy_postgres() {
    log_info "Deploying PostgreSQL for Keycloak..."
    
    POSTGRES_PASSWORD="${KEYCLOAK_DB_PASSWORD:-$(generate_password)}"
    
    kubectl create namespace keycloak --dry-run=client -o yaml | kubectl apply -f -
    
    kubectl create secret generic keycloak-db-credentials \
        --from-literal=username=keycloak \
        --from-literal=password="$POSTGRES_PASSWORD" \
        --namespace=keycloak \
        --dry-run=client -o yaml | kubectl apply -f -
    
    log_info "PostgreSQL secret created"
    log_warn "PostgreSQL password saved in secret: keycloak-db-credentials"
}

# Deploy Keycloak
deploy_keycloak() {
    log_info "Deploying Keycloak..."
    
    ADMIN_PASSWORD="${KEYCLOAK_ADMIN_PASSWORD:-$(generate_password)}"
    
    kubectl create secret generic keycloak-credentials \
        --from-literal=username=admin \
        --from-literal=password="$ADMIN_PASSWORD" \
        --namespace=keycloak \
        --dry-run=client -o yaml | kubectl apply -f -
    
    log_info "Keycloak admin credentials created"
    log_warn "Admin password saved in secret: keycloak-credentials"
    
    # Apply Keycloak manifests
    kubectl apply -f "$PROJECT_ROOT/gitops/apps/keycloak/namespace.yaml"
    kubectl apply -f "$PROJECT_ROOT/gitops/apps/keycloak/postgres.yaml"
    kubectl apply -f "$PROJECT_ROOT/gitops/apps/keycloak/deployment.yaml"
    
    log_info "Waiting for Keycloak to be ready..."
    kubectl wait --for=condition=available --timeout=300s \
        deployment/keycloak -n keycloak || {
        log_error "Keycloak deployment failed"
        kubectl logs -n keycloak deployment/keycloak --tail=50
        exit 1
    }
    
    log_info "Keycloak deployed successfully"
}

# Configure Keycloak clients
configure_clients() {
    log_info "Configuring Keycloak clients..."
    
    # Wait for Keycloak to be fully ready
    log_info "Waiting for Keycloak API to be ready..."
    for i in {1..30}; do
        if kubectl exec -n keycloak deployment/keycloak -- \
            curl -s http://localhost:8080/health/ready &>/dev/null; then
            break
        fi
        sleep 2
    done
    
    # Get admin credentials
    ADMIN_USER=$(kubectl get secret keycloak-credentials -n keycloak -o jsonpath='{.data.username}' | base64 -d)
    ADMIN_PASS=$(kubectl get secret keycloak-credentials -n keycloak -o jsonpath='{.data.password}' | base64 -d)
    
    # Port-forward for client configuration
    log_info "Configuring clients via API..."
    kubectl port-forward -n keycloak svc/keycloak 8080:8080 &
    PF_PID=$!
    sleep 3
    
    # Get admin token
    TOKEN=$(curl -s -X POST "http://localhost:8080/realms/master/protocol/openid-connect/token" \
        -H "Content-Type: application/x-www-form-urlencoded" \
        -d "username=$ADMIN_USER" \
        -d "password=$ADMIN_PASS" \
        -d "grant_type=password" \
        -d "client_id=admin-cli" | jq -r '.access_token')
    
    if [ "$TOKEN" == "null" ] || [ -z "$TOKEN" ]; then
        log_error "Failed to get admin token"
        kill $PF_PID 2>/dev/null || true
        exit 1
    fi
    
    # Generate client secrets
    API_SECRET="${SANKOFA_API_CLIENT_SECRET:-$(generate_password)}"
    PORTAL_SECRET="${PORTAL_CLIENT_SECRET:-$(generate_password)}"
    
    # Create API client
    log_info "Creating API client..."
    curl -s -X POST "http://localhost:8080/admin/realms/master/clients" \
        -H "Authorization: Bearer $TOKEN" \
        -H "Content-Type: application/json" \
        -d "{
            \"clientId\": \"sankofa-api\",
            \"name\": \"Sankofa API Client\",
            \"enabled\": true,
            \"clientAuthenticatorType\": \"client-secret\",
            \"secret\": \"$API_SECRET\",
            \"standardFlowEnabled\": false,
            \"serviceAccountsEnabled\": true,
            \"publicClient\": false,
            \"protocol\": \"openid-connect\"
        }" > /dev/null
    
    # Create Portal client
    log_info "Creating Portal client..."
    curl -s -X POST "http://localhost:8080/admin/realms/master/clients" \
        -H "Authorization: Bearer $TOKEN" \
        -H "Content-Type: application/json" \
        -d "{
            \"clientId\": \"portal-client\",
            \"name\": \"Sankofa Portal Client\",
            \"enabled\": true,
            \"clientAuthenticatorType\": \"client-secret\",
            \"secret\": \"$PORTAL_SECRET\",
            \"standardFlowEnabled\": true,
            \"directAccessGrantsEnabled\": true,
            \"publicClient\": false,
            \"protocol\": \"openid-connect\",
            \"redirectUris\": [
                \"http://localhost:3000/*\",
                \"https://portal.sankofa.nexus/*\"
            ],
            \"webOrigins\": [\"+\"]
        }" > /dev/null
    
    # Save secrets
    kubectl create secret generic keycloak-client-secrets \
        --from-literal=api-client-secret="$API_SECRET" \
        --from-literal=portal-client-secret="$PORTAL_SECRET" \
        --namespace=keycloak \
        --dry-run=client -o yaml | kubectl apply -f -
    
    kill $PF_PID 2>/dev/null || true
    
    log_info "Keycloak clients configured successfully"
    log_warn "Client secrets saved in secret: keycloak-client-secrets"
}

# Main deployment
main() {
    log_info "Starting Keycloak deployment..."
    
    check_prerequisites
    deploy_postgres
    deploy_keycloak
    configure_clients
    
    log_info "Keycloak deployment completed!"
    log_info "Access Keycloak at: https://keycloak.sankofa.nexus"
    log_warn "Admin credentials are in secret: keycloak-credentials"
    log_warn "Client secrets are in secret: keycloak-client-secrets"
}

# Run main function
main "$@"
