# SwarmAI Hive — Caddy reverse proxy configuration
#
# CloudFront terminates TLS. Caddy listens on :80 only.
# Do NOT use a domain name — that enables auto-HTTPS and causes
# redirect loops with CloudFront's HTTP-only origin policy.
#
# IMPORTANT: Caddy handle blocks are first-match. SSE-specific routes
# MUST come before the generic /api/* catch-all, otherwise they never
# execute and streaming silently buffers until response completes.
#
# Usage: caddy run --config /etc/caddy/Caddyfile

:80 {

    # --- Health check — BEFORE auth so external monitors can reach it ---
    # G11: /health returns no secrets, safe to expose unauthenticated.
    # Enables Route53 health checks, UptimeRobot, etc.
    handle /health {
        reverse_proxy 127.0.0.1:18321
    }

    # --- Authentication (MVP: basic auth) ---
    # @protected excludes /health so external monitors can reach it (G11)
    # Use basic_auth (not deprecated basicauth)
    @protected not path /health
    basic_auth @protected {
        {$HIVE_USER:admin} {$HIVE_PASS_HASH:INVALID_NOT_A_REAL_HASH}
    }

    # --- SSE streaming — MUST be before generic /api/* (first-match) ---
    handle /api/chat/stream {
        reverse_proxy 127.0.0.1:18321 {
            flush_interval -1
            transport http {
                read_timeout 300s
            }
        }
    }

    handle /api/chat/answer-question {
        reverse_proxy 127.0.0.1:18321 {
            flush_interval -1
            transport http {
                read_timeout 120s
            }
        }
    }

    handle /api/chat/cmd-permission-continue {
        reverse_proxy 127.0.0.1:18321 {
            flush_interval -1
            transport http {
                read_timeout 120s
            }
        }
    }

    # --- Generic API reverse proxy (catch-all for non-SSE) ---
    # CUSTOM_ROUTES_ABOVE — do not remove this marker
    handle /api/* {
        reverse_proxy 127.0.0.1:18321
    }

    # /shutdown intentionally NOT proxied — any auth'd user could kill
    # the shared backend. Desktop Tauri handler is the only caller and
    # it guards with isDesktop(). Backend also has a mode guard.

    # --- React SPA static files ---
    handle {
        root * /opt/swarmai/desktop/dist
        try_files {path} /index.html
        file_server
    }

    # --- Security headers ---
    header {
        X-Content-Type-Options nosniff
        X-Frame-Options DENY
        Referrer-Policy strict-origin-when-cross-origin
        -Server
    }

    # --- Logging ---
    log {
        output file /var/log/caddy/hive-access.log {
            roll_size 100mb
            roll_keep 5
        }
    }
}
