#!/bin/bash

# Zeal Kubernetes Deployment Generator
# This script interactively collects configuration and generates a customized K8s deployment

set -e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Default values
DEFAULT_NAMESPACE="zeal"
DEFAULT_NEXTJS_REPLICAS="3"
DEFAULT_CRDT_REPLICAS="2"
DEFAULT_REDIS_IMAGE="redis:7-alpine"
DEFAULT_DOMAIN="zeal.yourdomain.com"
DEFAULT_USE_SUPABASE="yes"

# Function to prompt for input with default
prompt_with_default() {
    local prompt=$1
    local default=$2
    local var_name=$3
    
    echo -e "${BLUE}$prompt${NC} ${YELLOW}[$default]${NC}: "
    read -r input
    if [ -z "$input" ]; then
        eval "$var_name='$default'"
    else
        eval "$var_name='$input'"
    fi
}

# Function to prompt for secret
prompt_secret() {
    local prompt=$1
    local var_name=$2
    
    echo -e "${BLUE}$prompt${NC}: "
    read -rs input
    echo
    eval "$var_name='$input'"
}

# Function to validate input
validate_not_empty() {
    local value=$1
    local field=$2
    
    if [ -z "$value" ]; then
        echo -e "${RED}Error: $field cannot be empty${NC}"
        return 1
    fi
    return 0
}

echo -e "${GREEN}🚀 Zeal Kubernetes Deployment Generator${NC}"
echo -e "${GREEN}=====================================>${NC}"
echo

# Collect basic configuration
echo -e "${YELLOW}=== Basic Configuration ===${NC}"
prompt_with_default "Kubernetes namespace" "$DEFAULT_NAMESPACE" "NAMESPACE"
prompt_with_default "Domain name (for ingress)" "$DEFAULT_DOMAIN" "DOMAIN"
echo

# Collect container images
echo -e "${YELLOW}=== Container Images ===${NC}"
echo -e "${YELLOW}Enter your container registry and image tags${NC}"
prompt_with_default "Next.js image (e.g., myregistry/zeal-nextjs:v1.0.0)" "" "NEXTJS_IMAGE"
validate_not_empty "$NEXTJS_IMAGE" "Next.js image" || exit 1

prompt_with_default "CRDT server image (e.g., myregistry/zeal-crdt:v1.0.0)" "" "CRDT_IMAGE"
validate_not_empty "$CRDT_IMAGE" "CRDT server image" || exit 1

prompt_with_default "Redis image" "$DEFAULT_REDIS_IMAGE" "REDIS_IMAGE"
echo

# Collect replicas configuration
echo -e "${YELLOW}=== Scaling Configuration ===${NC}"
prompt_with_default "Next.js replicas" "$DEFAULT_NEXTJS_REPLICAS" "NEXTJS_REPLICAS"
prompt_with_default "CRDT server replicas" "$DEFAULT_CRDT_REPLICAS" "CRDT_REPLICAS"
echo

# Collect database configuration
echo -e "${YELLOW}=== Database Configuration ===${NC}"
prompt_with_default "Use Supabase? (yes/no)" "$DEFAULT_USE_SUPABASE" "USE_SUPABASE"

if [[ "$USE_SUPABASE" =~ ^[Yy][Ee]?[Ss]?$ ]]; then
    echo -e "${YELLOW}Configuring Supabase...${NC}"
    prompt_with_default "Supabase URL" "" "SUPABASE_URL"
    validate_not_empty "$SUPABASE_URL" "Supabase URL" || exit 1
    
    prompt_secret "Supabase Anon Key" "SUPABASE_ANON_KEY"
    validate_not_empty "$SUPABASE_ANON_KEY" "Supabase Anon Key" || exit 1
    
    prompt_secret "Supabase Service Role Key" "SUPABASE_SERVICE_ROLE_KEY"
    validate_not_empty "$SUPABASE_SERVICE_ROLE_KEY" "Supabase Service Role Key" || exit 1
    
    DATABASE_URL="postgresql://postgres:password@db.supabase.co:5432/postgres"
else
    echo -e "${YELLOW}Configuring PostgreSQL...${NC}"
    prompt_with_default "PostgreSQL connection URL" "" "DATABASE_URL"
    validate_not_empty "$DATABASE_URL" "Database URL" || exit 1
fi
echo

# Collect authentication configuration
echo -e "${YELLOW}=== Authentication Configuration ===${NC}"
prompt_secret "NextAuth Secret (generate with: openssl rand -base64 32)" "NEXTAUTH_SECRET"
validate_not_empty "$NEXTAUTH_SECRET" "NextAuth Secret" || exit 1

prompt_with_default "NextAuth URL" "https://$DOMAIN" "NEXTAUTH_URL"
echo

# Collect optional configuration
echo -e "${YELLOW}=== Optional Configuration ===${NC}"
prompt_with_default "Enable TLS/HTTPS? (yes/no)" "yes" "ENABLE_TLS"
prompt_with_default "Cert-manager cluster issuer" "letsencrypt-prod" "CLUSTER_ISSUER"
echo

# Generate the deployment file
OUTPUT_FILE="k8s/deployment-generated.yaml"
echo -e "${YELLOW}Generating deployment configuration...${NC}"

cat > "$OUTPUT_FILE" << EOF
# Generated by generate-k8s-deployment.sh
# Date: $(date)
# 
# Container Images:
#   Next.js: $NEXTJS_IMAGE
#   CRDT: $CRDT_IMAGE
#   Redis: $REDIS_IMAGE

apiVersion: v1
kind: Namespace
metadata:
  name: $NAMESPACE
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: zeal-config
  namespace: $NAMESPACE
data:
  NEXTAUTH_URL: "$NEXTAUTH_URL"
  CRDT_SERVER_URL: "ws://crdt-service:8080"
  NEXT_PUBLIC_CRDT_SERVER_URL: "ws://$DOMAIN"
  NODE_ENV: "production"
  USE_SUPABASE: "$([[ "$USE_SUPABASE" =~ ^[Yy][Ee]?[Ss]?$ ]] && echo "true" || echo "false")"
  SUPABASE_URL: "$([[ "$USE_SUPABASE" =~ ^[Yy][Ee]?[Ss]?$ ]] && echo "http://supabase-gateway:8000" || echo "")"
---
apiVersion: v1
kind: Secret
metadata:
  name: zeal-secrets
  namespace: $NAMESPACE
type: Opaque
stringData:
  NEXTAUTH_SECRET: "$NEXTAUTH_SECRET"
  DATABASE_URL: "$DATABASE_URL"
EOF

# Add Supabase secrets if using Supabase
if [[ "$USE_SUPABASE" =~ ^[Yy][Ee]?[Ss]?$ ]]; then
    cat >> "$OUTPUT_FILE" << EOF
  SUPABASE_ANON_KEY: "$SUPABASE_ANON_KEY"
  SUPABASE_SERVICE_ROLE_KEY: "$SUPABASE_SERVICE_ROLE_KEY"
EOF
fi

cat >> "$OUTPUT_FILE" << EOF
  REDIS_URL: "redis://redis-service:6379"
---
# Next.js Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nextjs-deployment
  namespace: $NAMESPACE
spec:
  replicas: $NEXTJS_REPLICAS
  selector:
    matchLabels:
      app: nextjs
  template:
    metadata:
      labels:
        app: nextjs
    spec:
      containers:
      - name: nextjs
        image: $NEXTJS_IMAGE
        imagePullPolicy: $(if [[ "$NEXTJS_IMAGE" =~ ^localhost:|^[^/]+:[0-9]+/ ]]; then echo "Always"; else echo "Never"; fi)
        ports:
        - containerPort: 3000
        envFrom:
        - configMapRef:
            name: zeal-config
        - secretRef:
            name: zeal-secrets
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "1Gi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /api/health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /api/health
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5
---
# CRDT Server Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: crdt-deployment
  namespace: $NAMESPACE
spec:
  replicas: $CRDT_REPLICAS
  selector:
    matchLabels:
      app: crdt
  template:
    metadata:
      labels:
        app: crdt
    spec:
      containers:
      - name: crdt
        image: $CRDT_IMAGE
        imagePullPolicy: $(if [[ "$CRDT_IMAGE" =~ ^localhost:|^[^/]+:[0-9]+/ ]]; then echo "Always"; else echo "Never"; fi)
        ports:
        - containerPort: 8080
        env:
        - name: RUST_LOG
          value: "info,crdt_server=debug"
        - name: SERVER_HOST
          value: "0.0.0.0"
        - name: SERVER_PORT
          value: "8080"
        envFrom:
        - secretRef:
            name: zeal-secrets
        resources:
          requests:
            memory: "256Mi"
            cpu: "100m"
          limits:
            memory: "512Mi"
            cpu: "200m"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 10
---
# Redis Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-deployment
  namespace: $NAMESPACE
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: $REDIS_IMAGE
        ports:
        - containerPort: 6379
        resources:
          requests:
            memory: "128Mi"
            cpu: "50m"
          limits:
            memory: "256Mi"
            cpu: "100m"
---
# Services
apiVersion: v1
kind: Service
metadata:
  name: nextjs-service
  namespace: $NAMESPACE
spec:
  selector:
    app: nextjs
  ports:
  - port: 3000
    targetPort: 3000
  type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
  name: crdt-service
  namespace: $NAMESPACE
spec:
  selector:
    app: crdt
  ports:
  - port: 8080
    targetPort: 8080
  type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
  name: redis-service
  namespace: $NAMESPACE
spec:
  selector:
    app: redis
  ports:
  - port: 6379
    targetPort: 6379
  type: ClusterIP
---
# Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: zeal-ingress
  namespace: $NAMESPACE
  annotations:
    kubernetes.io/ingress.class: nginx
EOF

# Add TLS annotations if enabled
if [[ "$ENABLE_TLS" =~ ^[Yy][Ee]?[Ss]?$ ]]; then
    cat >> "$OUTPUT_FILE" << EOF
    cert-manager.io/cluster-issuer: $CLUSTER_ISSUER
EOF
fi

cat >> "$OUTPUT_FILE" << EOF
    nginx.ingress.kubernetes.io/websocket-services: "crdt-service"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
spec:
EOF

# Add TLS configuration if enabled
if [[ "$ENABLE_TLS" =~ ^[Yy][Ee]?[Ss]?$ ]]; then
    cat >> "$OUTPUT_FILE" << EOF
  tls:
  - hosts:
    - $DOMAIN
    secretName: zeal-tls
EOF
fi

cat >> "$OUTPUT_FILE" << EOF
  rules:
  - host: $DOMAIN
    http:
      paths:
      - path: /socket.io
        pathType: ImplementationSpecific
        backend:
          service:
            name: crdt-service
            port:
              number: 8080
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nextjs-service
            port:
              number: 3000
---
# Horizontal Pod Autoscaler for Next.js
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nextjs-hpa
  namespace: $NAMESPACE
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nextjs-deployment
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
EOF

echo
echo -e "${GREEN}✅ Deployment configuration generated successfully!${NC}"
echo -e "${GREEN}📄 Output file: $OUTPUT_FILE${NC}"
echo
echo -e "${YELLOW}Next steps:${NC}"
echo "1. Review the generated configuration: cat $OUTPUT_FILE"
echo "2. Apply to your cluster: kubectl apply -f $OUTPUT_FILE"
echo "3. Check deployment status: kubectl get all -n $NAMESPACE"
echo
echo -e "${YELLOW}Important:${NC}"
echo "- Ensure your container images are pushed to the registry"
echo "- Verify your cluster has the required resources"
echo "- Configure any necessary image pull secrets if using a private registry"