# Copyright (c) Abstract Machines
# SPDX-License-Identifier: Apache-2.0

# This is the default Magistrala NGINX configuration.

user nginx;
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 65535;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    # Explanation: https://serverfault.com/questions/787919/optimal-value-for-nginx-worker-connections
    # We'll keep 10k connections per core (assuming one worker per core)
    worker_connections 10000;
}

http {
    include snippets/http_access_log.conf;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    client_max_body_size 5M;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    resolver 127.0.0.11 ipv6=off valid=10s;
    resolver_timeout 5s;

    # Include single-node or multiple-node (cluster) upstream
    include snippets/mqtt-ws-upstream.conf;
    include snippets/fluxmq-http-upstream.conf;

    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        http2 on;

        set $dynamic_server_name "$MG_NGINX_SERVER_NAME";

        if ($dynamic_server_name = '') {
            set $dynamic_server_name "localhost";
        }

        server_name $dynamic_server_name;
        set $auth_upstream "auth:${MG_AUTH_HTTP_PORT}";
        set $domains_upstream "domains:${MG_DOMAINS_HTTP_PORT}";
        set $users_upstream "users:${MG_USERS_HTTP_PORT}";
        set $groups_upstream "groups:${MG_GROUPS_HTTP_PORT}";
        set $clients_upstream "clients:${MG_CLIENTS_HTTP_PORT}";
        set $channels_upstream "channels:${MG_CHANNELS_HTTP_PORT}";
        set $rules_upstream "re:${MG_RE_HTTP_PORT}";
        set $alarms_upstream "alarms:${MG_ALARMS_HTTP_PORT}";
        set $reports_upstream "reports:${MG_REPORTS_HTTP_PORT}";

        include snippets/ssl.conf;

        add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
        add_header X-Frame-Options DENY;
        add_header X-Content-Type-Options nosniff;
        add_header Access-Control-Allow-Origin '*';
        add_header Access-Control-Allow-Methods '*';
        add_header Access-Control-Allow-Headers '*';

        location ^~ /.well-known/acme-challenge/ {
            root /var/www/certbot;
            default_type text/plain;
            try_files $uri =404;
        }

        # Proxy pass to auth service
        location ~ ^/(pats) {
            include snippets/proxy-headers.conf;
            add_header Access-Control-Expose-Headers Location;
            proxy_pass http://$auth_upstream;
        }

        # Proxy pass to domains service
        location ~ ^/(domains|invitations) {
            include snippets/proxy-headers.conf;
            add_header Access-Control-Expose-Headers Location;
            proxy_pass http://$domains_upstream;
        }

        # Proxy pass to users service
        location ~ ^/(users|password|verify-email|authorize|oauth/callback/[^/]+) {
            include snippets/proxy-headers.conf;
            add_header Access-Control-Expose-Headers Location;
            proxy_pass http://$users_upstream;
        }

        # Proxy pass to groups service
        location ~ "^/([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})/(groups)" {
            include snippets/proxy-headers.conf;
            add_header Access-Control-Expose-Headers Location;
            proxy_pass http://$groups_upstream;
        }

        # Proxy pass to clients service
        location ~ "^/([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})/(clients)" {
            include snippets/proxy-headers.conf;
            add_header Access-Control-Expose-Headers Location;
            proxy_pass http://$clients_upstream;
        }

        # Proxy pass to channels service
        location ~ "^/([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})/(channels)" {
            include snippets/proxy-headers.conf;
            add_header Access-Control-Expose-Headers Location;
            proxy_pass http://$channels_upstream;
        }

        # Proxy pass to rule engine service
        location ~ "^/([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})/(rules)" {
            include snippets/proxy-headers.conf;
            add_header Access-Control-Expose-Headers Location;
            proxy_pass http://$rules_upstream;
        }

        # Proxy pass to alarm service
        location ~ "^/([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})/(alarms)" {
            include snippets/proxy-headers.conf;
            add_header Access-Control-Expose-Headers Location;
            proxy_pass http://$alarms_upstream;
        }

        # Proxy pass to reports service
        location ~ "^/([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})/(reports)" {
            include snippets/proxy-headers.conf;
            add_header Access-Control-Expose-Headers Location;
            proxy_pass http://$reports_upstream;
        }

        location /health {
            include snippets/proxy-headers.conf;
            proxy_pass http://$clients_upstream;
        }

        location /metrics {
            include snippets/proxy-headers.conf;
            proxy_pass http://$clients_upstream;
        }

        # Proxy pass to FluxMQ HTTP API
        location /http/ {
            include snippets/proxy-headers.conf;
            proxy_pass http://fluxmq_http_cluster/;
        }

        # Proxy pass to FluxMQ MQTT over WebSocket
        location /mqtt {
            include snippets/proxy-headers.conf;
            include snippets/ws-upgrade.conf;
            proxy_pass http://mqtt_ws_cluster;
        }

        # UI proxy – populated by docker/setup-tls.sh; empty = no catch-all (local dev)
        include snippets/ui-proxy.conf;
    }
}

# MQTT
stream {
   include snippets/stream_access_log.conf;

    # Include single-node or multiple-node (cluster) upstream
    include snippets/mqtt-upstream.conf;
    include snippets/fluxmq-amqp-upstream.conf;

    server {
        listen ${MG_NGINX_MQTT_PORT};
        listen [::]:${MG_NGINX_MQTT_PORT};
        listen ${MG_NGINX_MQTTS_PORT} ssl;
        listen [::]:${MG_NGINX_MQTTS_PORT} ssl;

        include snippets/ssl.conf;

        proxy_pass mqtt_cluster;
    }

    # FluxMQ AMQP 0.9.1 (event store)
    server {
        listen ${MG_NGINX_AMQP_PORT};
        listen [::]:${MG_NGINX_AMQP_PORT};

        proxy_pass fluxmq_amqp_cluster;
    }
}

error_log info.log info;
