apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: wifi-densepose-ingress
  namespace: wifi-densepose
  labels:
    app: wifi-densepose
    component: ingress
  annotations:
    # NGINX Ingress Controller annotations
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
    
    # Rate limiting
    nginx.ingress.kubernetes.io/rate-limit: "100"
    nginx.ingress.kubernetes.io/rate-limit-window: "1m"
    nginx.ingress.kubernetes.io/rate-limit-connections: "10"
    
    # CORS configuration
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://wifi-densepose.com,https://app.wifi-densepose.com"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET,POST,PUT,DELETE,OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-headers: "Content-Type,Authorization,X-Requested-With"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    
    # Security headers
    nginx.ingress.kubernetes.io/configuration-snippet: |
      add_header X-Frame-Options "SAMEORIGIN" always;
      add_header X-Content-Type-Options "nosniff" always;
      add_header X-XSS-Protection "1; mode=block" always;
      add_header Referrer-Policy "strict-origin-when-cross-origin" always;
      add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' wss: https:;" always;
    
    # Load balancing
    nginx.ingress.kubernetes.io/upstream-hash-by: "$remote_addr"
    nginx.ingress.kubernetes.io/load-balance: "round_robin"
    
    # Timeouts
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "30"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "30"
    
    # Body size
    nginx.ingress.kubernetes.io/proxy-body-size: "10m"
    
    # Certificate management (cert-manager)
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    cert-manager.io/acme-challenge-type: "http01"
spec:
  tls:
  - hosts:
    - wifi-densepose.com
    - api.wifi-densepose.com
    - app.wifi-densepose.com
    secretName: wifi-densepose-tls
  rules:
  - host: wifi-densepose.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80
      - path: /health
        pathType: Exact
        backend:
          service:
            name: wifi-densepose-service
            port:
              number: 8000
  - host: api.wifi-densepose.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: wifi-densepose-service
            port:
              number: 8000
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: wifi-densepose-service
            port:
              number: 8000
      - path: /docs
        pathType: Prefix
        backend:
          service:
            name: wifi-densepose-service
            port:
              number: 8000
      - path: /metrics
        pathType: Exact
        backend:
          service:
            name: wifi-densepose-service
            port:
              number: 8080
  - host: app.wifi-densepose.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80

---
# WebSocket Ingress (separate for sticky sessions)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: wifi-densepose-websocket-ingress
  namespace: wifi-densepose
  labels:
    app: wifi-densepose
    component: websocket-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    
    # WebSocket specific configuration
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
    nginx.ingress.kubernetes.io/upstream-hash-by: "$remote_addr"
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/affinity-mode: "persistent"
    nginx.ingress.kubernetes.io/session-cookie-name: "wifi-densepose-ws"
    nginx.ingress.kubernetes.io/session-cookie-expires: "3600"
    nginx.ingress.kubernetes.io/session-cookie-max-age: "3600"
    nginx.ingress.kubernetes.io/session-cookie-path: "/ws"
    
    # WebSocket upgrade headers
    nginx.ingress.kubernetes.io/configuration-snippet: |
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_cache_bypass $http_upgrade;
    
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
  - hosts:
    - ws.wifi-densepose.com
    secretName: wifi-densepose-ws-tls
  rules:
  - host: ws.wifi-densepose.com
    http:
      paths:
      - path: /ws
        pathType: Prefix
        backend:
          service:
            name: wifi-densepose-websocket
            port:
              number: 8000

---
# Internal Ingress for monitoring and admin access
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: wifi-densepose-internal-ingress
  namespace: wifi-densepose
  labels:
    app: wifi-densepose
    component: internal-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    
    # IP whitelist for internal access
    nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
    
    # Basic auth for additional security
    nginx.ingress.kubernetes.io/auth-type: "basic"
    nginx.ingress.kubernetes.io/auth-secret: "wifi-densepose-basic-auth"
    nginx.ingress.kubernetes.io/auth-realm: "WiFi-DensePose Internal Access"
    
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
  - hosts:
    - internal.wifi-densepose.com
    secretName: wifi-densepose-internal-tls
  rules:
  - host: internal.wifi-densepose.com
    http:
      paths:
      - path: /metrics
        pathType: Prefix
        backend:
          service:
            name: wifi-densepose-internal
            port:
              number: 8080
      - path: /health
        pathType: Prefix
        backend:
          service:
            name: wifi-densepose-internal
            port:
              number: 8000
      - path: /api/v1/status
        pathType: Exact
        backend:
          service:
            name: wifi-densepose-internal
            port:
              number: 8000

---
# Certificate Issuer for Let's Encrypt
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@wifi-densepose.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: nginx
    - dns01:
        cloudflare:
          email: admin@wifi-densepose.com
          apiTokenSecretRef:
            name: cloudflare-api-token
            key: api-token

---
# Staging Certificate Issuer for testing
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: admin@wifi-densepose.com
    privateKeySecretRef:
      name: letsencrypt-staging
    solvers:
    - http01:
        ingress:
          class: nginx

---
# Basic Auth Secret for internal access
apiVersion: v1
kind: Secret
metadata:
  name: wifi-densepose-basic-auth
  namespace: wifi-densepose
type: Opaque
data:
  # Generated with: htpasswd -nb admin password | base64
  # Default: admin:password (change in production)
  auth: YWRtaW46JGFwcjEkSDY1dnFkNDAkWGJBTHZGdmJQSVcuL1pLLkNPeS4wLwo=