upstream swoole {
    server swoole-upstream:9501;
    keepalive 32;
}

server {
    listen 80;
    server_name localhost;
    root /var/app/public;

    index index.html index.htm;

    charset utf-8;

    # === Connection Optimization ===
    keepalive_timeout 65;
    keepalive_requests 1000;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    # === Buffers and Limits ===
    client_max_body_size 64M;
    large_client_header_buffers 4 32k;

    # === File Descriptor Cache ===
    open_file_cache max=2000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;

    # === Gzip Compression ===
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_min_length 256;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/json
        application/javascript
        application/x-javascript
        application/xml
        application/rss+xml
        application/atom+xml
        image/svg+xml
        font/woff2
        application/font-woff2
        application/vnd.ms-fontobject
        application/x-font-ttf;

    # === Security Headers ===
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    # === Specific Caching for Build Assets (Vite hashed) ===
    # These files have content hashes in names — cache forever
    location ^~ /build/assets/ {
        access_log off;
        expires max;
        add_header Cache-Control "public, no-transform, immutable";
        try_files $uri =404;
    }

    # === Static Assets from /dist/ and /plugins/ (legacy libs) ===
    location ^~ /dist/ {
        access_log off;
        expires 30d;
        add_header Cache-Control "public, no-transform";
        try_files $uri =404;
    }

    location ^~ /plugins/ {
        access_log off;
        expires 30d;
        add_header Cache-Control "public, no-transform";
        try_files $uri =404;
    }

    location ^~ /assets/ {
        access_log off;
        expires 30d;
        add_header Cache-Control "public, no-transform";
        try_files $uri =404;
    }

    # === Font files — long cache + CORS ===
    location ~* \.(woff|woff2|ttf|eot|otf)$ {
        access_log off;
        expires max;
        add_header Cache-Control "public, no-transform, immutable";
        add_header Access-Control-Allow-Origin "*";
        try_files $uri =404;
    }

    # === Image files ===
    location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ {
        access_log off;
        expires 30d;
        add_header Cache-Control "public, no-transform";
        try_files $uri =404;
    }

    # === Direct Access to Static Files (CSS/JS catch-all) ===
    location ~* \.(css|js)$ {
        access_log off;
        expires 7d;
        add_header Cache-Control "public, no-transform";
        try_files $uri =404;
    }

    # === Hashed Files Caching (DB-served files) ===
    location /RequestData/File/ {
        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_set_header X-Forwarded-Port $server_port;
        proxy_set_header Connection "";
        proxy_http_version 1.1;

        proxy_pass http://swoole;

        # Browser caching for hashed assets
        add_header Cache-Control "public, max-age=31536000, immutable";
    }

    # === SSE Streaming (No buffering, long timeouts) ===
    location /sse/ {
        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_set_header X-Forwarded-Port $server_port;
        proxy_set_header Connection "";
        proxy_http_version 1.1;

        proxy_pass http://swoole;

        # Disable buffering and caching for real-time streaming
        proxy_buffering off;
        proxy_cache off;
        chunked_transfer_encoding off;
        
        # Extended timeouts for long-lived streams
        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;
    }

    # === Application proxy (catch-all) ===
    location / {
        # Try static file first, then proxy to Swoole
        try_files $uri @swoole;
    }

    location @swoole {
        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_set_header X-Forwarded-Port $server_port;
        proxy_set_header Connection "";
        proxy_http_version 1.1;

        proxy_pass http://swoole;

        # Proxy buffering for better throughput for normal requests
        proxy_buffering on;
        proxy_buffer_size 32k;
        proxy_buffers 8 64k;
    }

    # === Manifest and PWA ===
    location = /manifest.json {
        access_log off;
        expires 1d;
        add_header Cache-Control "public, no-transform";
        try_files $uri =404;
    }

    location = /sw.js {
        access_log off;
        expires -1;
        add_header Cache-Control "no-cache, no-store, must-revalidate";
        try_files $uri =404;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  /var/log/nginx/error.log error;
}
