user xc_vm;
worker_processes  auto;
worker_rlimit_nofile 300000;

events {
    worker_connections  16000;
    use epoll;
    multi_accept on;
}

thread_pool pool_xc_vm threads=32 max_queue=0;

http {
    include mime.types;
    default_type  application/octet-stream;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    reset_timedout_connection on;
    include gzip.conf;
    fastcgi_read_timeout 200;
    access_log off;
    error_log /dev/null;
    keepalive_timeout 10;
    include balance.conf;
    send_timeout 20m;    
    sendfile_max_chunk 512k;
    lingering_close off;
    aio threads=pool_xc_vm;
    client_body_timeout 13s;
    client_header_timeout 13s;
    client_max_body_size 8m;
    proxy_buffer_size 16k;
    proxy_busy_buffers_size 24k;
    proxy_buffers 64 4k;
    proxy_max_temp_file_size 0;
    real_ip_header X-Forwarded-For;
    include realip_cdn.conf;
    include realip_cloudflare.conf;
    include realip_xc_vm.conf;
    include limit.conf;
    limit_req_zone $binary_remote_addr zone=one:30m rate=20r/s;
    server {
        include ports/*.conf;
        include codes/*.conf;
        include ssl.conf;
        include custom.conf;
        include ministra_legacy.conf;
        index index.php index.html index.htm;
        try_files $uri $uri.html $uri/ @extensionless-php;
        root /home/xc_vm/Public/;
        server_tokens off;
        chunked_transfer_encoding off;
        resolver 1.1.1.1 1.0.0.1 valid=300s;
        resolver_timeout 5s;
        absolute_redirect off;

        if ($request_method !~ ^(GET|POST)$) {
            return 200;
        }

        location ^~ /.well-known/acme-challenge/ {
            root /home/xc_vm/certbot-webroot;
            try_files $uri =404;
        }

        rewrite_log on;
        rewrite ^/play/(?<token>[^/]*)/(?<extension>[^/]*)$ /stream/auth?token=$token&extension=$extension break;
        rewrite ^/play/(?<token>[^/]*)$ /stream/auth?token=$token&extension=ts break;
        rewrite ^/key/(?<token>[^/]*)$ /stream/key?token=$token break;
        rewrite ^/movie/(?<username>[^/]*)/(?<password>[^/]*)/(?<stream>[^/]*)$ /stream/auth?username=$username&password=$password&stream=$stream&type=movie break;
        rewrite ^/movie/(?<token>[^/]*)/(?<stream>[^/]*)$ /stream/auth?token=$token&stream=$stream&type=movie break;
        rewrite ^/series/(?<username>[^/]*)/(?<password>[^/]*)/(?<stream>[^/]*)$ /stream/auth?username=$username&password=$password&stream=$stream&type=series break;
        rewrite ^/series/(?<token>[^/]*)/(?<stream>[^/]*)$ /stream/auth?token=$token&stream=$stream&type=series break;
        rewrite ^/subtitle/(?<username>[^/]*)/(?<password>[^/]*)/(?<sid>[^/]*)/(?<stream>[^/]*)$ /stream/auth?username=$username&password=$password&stream=$stream&sid=$sid&type=subtitle break;
        rewrite ^/subtitle/(?<username>[^/]*)/(?<password>[^/]*)/(?<stream>[^/]*)$ /stream/auth?username=$username&password=$password&stream=$stream&type=subtitle break;
        rewrite ^/hls/(?<token>[^/]*)$ /stream/segment?token=$token break;
        rewrite ^/tsauth/(?<token>[^/]*)$ /stream/timeshift?token=$token break;
        rewrite ^/thauth/(?<token>[^/]*)$ /stream/thumb?token=$token break;
        rewrite ^/auth/(?<token>[^/]*)$ /stream/live?token=$token break;
        rewrite ^/vauth/(?<token>[^/]*)$ /stream/vod?token=$token break;
        rewrite ^/subauth/(?<token>[^/]*)$ /stream/subtitle?token=$token break;
        rewrite ^/timeshift/(?<username>[^/]*)/(?<password>[^/]*)/(?<duration>[^/]*)/(?<start>[^/]*)/(?<stream>[^/]*)\.(?<extension>[^/]*)$ /stream/auth?username=$username&password=$password&stream=$stream&extension=$extension&duration=$duration&start=$start&type=timeshift break;
        rewrite ^/timeshift/(?<token>[^/]*)/(?<duration>[^/]*)/(?<start>[^/]*)/(?<stream>[^/]*)\.(?<extension>[^/]*)$ /stream/auth?token=$token&stream=$stream&extension=$extension&duration=$duration&start=$start&type=timeshift break;
        rewrite ^/thumb/(?<username>[^/]*)/(?<password>[^/]*)/(?<stream>\d+)$ /stream/auth?username=$username&password=$password&stream=$stream&type=thumb break;
        rewrite ^/thumb/(?<token>[^/]*)/(?<stream>\d+)$ /stream/auth?token=$token&stream=$stream&type=thumb break;
        rewrite ^/playlist/(?<username>[^/]*)/(?<password>[^/]*)/(?<type>[^/]*)$ /api/playlist?username=$username&password=$password&type=$type break;
        rewrite ^/playlist/(?<username>[^/]*)/(?<password>[^/]*)$ /api/playlist?username=$username&password=$password break;
        rewrite ^/player_api/(?<username>[^/]*)/(?<password>[^/]*)/(?<action>[^/]*)$ /api/player_api?username=$username&password=$password&action=$action break;
        rewrite ^/player_api/(?<username>[^/]*)/(?<password>[^/]*)$ /api/player_api?username=$username&password=$password break;
        rewrite ^/epg/(?<username>[^/]*)/(?<password>[^/]*)/gz$ /api/epg?username=$username&password=$password&gzip=1 break;
        rewrite ^/epg/(?<username>[^/]*)/(?<password>[^/]*)$ /api/epg?username=$username&password=$password break;
        rewrite ^/live/(?<username>[^/]*)/(?<password>[^/]*)/(?<stream>\d+)\.(?<extension>[^/]*)$ /stream/auth?username=$username&password=$password&stream=$stream&extension=$extension&type=live break;
        rewrite ^/live/(?<username>[^/]*)/(?<password>[^/]*)/(?<stream>\d+)$ /stream/auth?username=$username&password=$password&stream=$stream&extension=ts&type=live break;
        rewrite ^/live/(?<token>[^/]*)/(?<stream>\d+)\.(?<extension>[^/]*)$ /stream/auth?token=$token&stream=$stream&extension=$extension&type=live break;
        rewrite ^/live/(?<token>[^/]*)/(?<stream>\d+)$ /stream/auth?token=$token&stream=$stream&extension=ts&type=live break;
        rewrite ^/probe/(?<data>[^/]*)$ /stream/probe?data=$data break;
        rewrite ^/(?<username>[^/]*)/(?<password>[^/]*)/(?<stream>\d+)\.(?<extension>[^/]*)$ /stream/auth?username=$username&password=$password&stream=$stream&extension=$extension&type=live break;
        rewrite ^/(?<username>[^/]*)/(?<password>[^/]*)/(?<stream>\d+)$ /stream/auth?username=$username&password=$password&stream=$stream&extension=ts&type=live break;

        location = /xmltv.php {
            rewrite ^ /api/epg last;
        }
        
        location = /get.php {
            rewrite ^ /api/playlist last;
        }
        
        location = /panel_api.php {
            rewrite ^ /api/player_api last;
        }
        
        location = /streaming/live.php {
            return 302 /stream/auth?type=live&$args;
        }
        
        location = /streaming/rtmp.php {
            return 302 /stream/rtmp?$args;
        }
        
        location = /streaming/timeshift.php {
            return 302 /stream/auth?type=timeshift&$args;
        }
        
        location = /streaming/vod.php {
            return 302 /stream/auth?type=movie&$args;
        }

        location = /server/load.php {
            return 302 /c/portal.php?$args;
        }

        # ─── Legacy Stream PHP Compatibility (no direct www execution) ──
        location ~ ^/stream/(auth|key|segment|live|vod|timeshift|thumb|subtitle|rtmp)\.php$ {
            return 302 /stream/$1?$args;
        }

        location = /probe.php {
            return 302 /stream/probe?$args;
        }

        # ─── Streaming Hot Path → Stream Gateway ─────────────────
        location ~ ^/stream/(auth|key|segment|live|vod|timeshift|thumb|subtitle|rtmp|probe)$ {
            limit_req zone=one burst=8;
            include limit_queue.conf;
            fastcgi_index index.php;
            fastcgi_pass php;
            include fastcgi_params;
            fastcgi_buffering on;
            fastcgi_buffers 128 32k;
            fastcgi_buffer_size 32k;
            fastcgi_max_temp_file_size 0;
            fastcgi_keep_conn on;
            fastcgi_param SCRIPT_FILENAME /home/xc_vm/Public/stream/index.php;
            fastcgi_param SCRIPT_NAME /public/stream/index.php;
            fastcgi_param XC_STREAM $1;
        }

        location ~* ^/images/(.*/)?index\.html$ {
            return 404;
        }

        location ^~ /images/ {
            alias /home/xc_vm/storage/images/;
            location ~* \.(php|php\d*|phtml|phar)$ {
                return 403;
            }
        }
        
        location ~ ^/status$ {
            allow 127.0.0.1;
            deny all;
            fastcgi_index index.php;
            fastcgi_pass php;
            include fastcgi_params;
            fastcgi_buffering on;
            fastcgi_buffers 96 32k;
            fastcgi_buffer_size 32k;
            fastcgi_max_temp_file_size 0;
            fastcgi_keep_conn on;
            fastcgi_param SCRIPT_FILENAME /home/xc_vm/Public/stream/index.php;
            fastcgi_param SCRIPT_NAME /public/stream/index.php;
            fastcgi_param XC_STREAM status;
        }
        
        location /nginx_status {
            allow 127.0.0.1;
            deny all;
            stub_status on;
        }

        # ─── Legacy Admin Stream Endpoints (compat) ───────────────
        location ~ ^/admin/(api|index|live|proxy_api|thumb|timeshift|vod)$ {
            limit_req zone=one burst=8;
            include limit_queue.conf;
            fastcgi_index index.php;
            fastcgi_pass php;
            include fastcgi_params;
            fastcgi_buffering on;
            fastcgi_buffers 128 32k;
            fastcgi_buffer_size 32k;
            fastcgi_busy_buffers_size 128k;
            fastcgi_max_temp_file_size 0;
            fastcgi_keep_conn on;
            fastcgi_param SCRIPT_FILENAME /home/xc_vm/Public/admin/index.php;
            fastcgi_param SCRIPT_NAME /public/admin/index.php;
            fastcgi_param XC_ADMIN $1;
        }

        location ~ ^/admin/(api|index|live|proxy_api|thumb|timeshift|vod)\.php$ {
            return 302 /admin/$1?$args;
        }

        location = /progress {
            limit_req zone=one burst=8;
            include limit_queue.conf;
            fastcgi_index index.php;
            fastcgi_pass php;
            include fastcgi_params;
            fastcgi_buffering on;
            fastcgi_buffers 128 32k;
            fastcgi_buffer_size 32k;
            fastcgi_busy_buffers_size 128k;
            fastcgi_max_temp_file_size 0;
            fastcgi_keep_conn on;
            fastcgi_param SCRIPT_FILENAME /home/xc_vm/Public/progress/index.php;
            fastcgi_param SCRIPT_NAME /public/progress/index.php;
        }

        location = /progress.php {
            return 302 /progress?$args;
        }

        # ─── Streaming API → Front Controller ───────────────────────
        location ~ ^/api/(player_api|enigma2|xplugin|epg|playlist)$ {
            limit_req zone=one burst=8;
            include limit_queue.conf;
            fastcgi_index index.php;
            fastcgi_pass php;
            include fastcgi_params;
            fastcgi_buffering on;
            fastcgi_buffers 128 32k;
            fastcgi_buffer_size 32k;
            fastcgi_max_temp_file_size 0;
            fastcgi_keep_conn on;
            fastcgi_param SCRIPT_FILENAME /home/xc_vm/Public/index.php;
            fastcgi_param SCRIPT_NAME /public/index.php;
            fastcgi_param XC_SCOPE api;
            fastcgi_param XC_API $1;
        }

        # ─── Streaming API → Front Controller (legacy *.php) ──────
        location ~ ^/(player_api|enigma2|xplugin|epg|playlist)\.php$ {
            limit_req zone=one burst=8;
            include limit_queue.conf;
            fastcgi_index index.php;
            fastcgi_pass php;
            include fastcgi_params;
            fastcgi_buffering on;
            fastcgi_buffers 128 32k;
            fastcgi_buffer_size 32k;
            fastcgi_max_temp_file_size 0;
            fastcgi_keep_conn on;
            fastcgi_param SCRIPT_FILENAME /home/xc_vm/Public/index.php;
            fastcgi_param SCRIPT_NAME /public/index.php;
            fastcgi_param XC_SCOPE api;
            fastcgi_param XC_API $1;
        }

        # ─── Internal API → Front Controller (server-to-server) ────
        # Аутентификация: InternalApiController проверяет password + IP whitelist
        location = /api {
            fastcgi_index index.php;
            fastcgi_pass php;
            include fastcgi_params;
            fastcgi_buffering on;
            fastcgi_buffers 128 32k;
            fastcgi_buffer_size 32k;
            fastcgi_max_temp_file_size 0;
            fastcgi_keep_conn on;
            fastcgi_param SCRIPT_FILENAME /home/xc_vm/Public/index.php;
            fastcgi_param SCRIPT_NAME /public/index.php;
            fastcgi_param XC_SCOPE api;
            fastcgi_param XC_API internal;
        }

        location = /api.php {
            fastcgi_index index.php;
            fastcgi_pass php;
            include fastcgi_params;
            fastcgi_buffering on;
            fastcgi_buffers 128 32k;
            fastcgi_buffer_size 32k;
            fastcgi_max_temp_file_size 0;
            fastcgi_keep_conn on;
            fastcgi_param SCRIPT_FILENAME /home/xc_vm/Public/index.php;
            fastcgi_param SCRIPT_NAME /public/index.php;
            fastcgi_param XC_SCOPE api;
            fastcgi_param XC_API internal;
        }

        # ─── Ministra Legacy URL /c/ ─────────────────────────────
        location = /c {
            if ($ministra_legacy_redirect = 0) {
                return 404;
            }

            return 302 /c/;
        }

        location ^~ /c/ {
            if ($ministra_legacy_redirect = 0) {
                return 404;
            }

            alias /home/xc_vm/ministra/;
            index index.html;
            try_files $uri $uri.html $uri/ /c/index.html =404;

            location ~ \.php$ {
                if ($ministra_legacy_redirect = 0) {
                    return 404;
                }

                limit_req zone=one burst=8;
                include limit_queue.conf;
                try_files $uri =404;
                fastcgi_index index.php;
                fastcgi_pass php;
                include fastcgi_params;
                fastcgi_buffering on;
                fastcgi_buffers 128 32k;
                fastcgi_buffer_size 32k;
                fastcgi_max_temp_file_size 0;
                fastcgi_keep_conn on;
                fastcgi_param SCRIPT_FILENAME $request_filename;
                fastcgi_param SCRIPT_NAME $fastcgi_script_name;
            }
        }

        location = /portal.php {
            if ($ministra_legacy_redirect = 0) {
                return 404;
            }

            return 302 /c/portal.php?$args;
        }

        location ~ \.php$ {
            return 404;
        }
        
        location @extensionless-php {
            return 404;
        }
    }
}
