

    #───────────────────────────────────────────────────────────────────────────
    # VOD-on-the-fly + Geo-lock by country
    #
    # Access pattern:  http://domain.com/hls/<slug>/<video>.mp4/index.m3u8
    # e.g.              http://domain.com/hls/vod/sample.mp4/index.m3u8
    #
    # Files live at:   /usr/local/mediacp/nginx/vod/sample.mp4
    #───────────────────────────────────────────────────────────────────────────
    location ~ ^/hls/(?<slug>[^/]+)/(?<video>[^/]+\.mp4)/ {
        # ── 1) Geo-lock check, cached 60s per (slug|country)
        access_by_lua_block {
            local settings_cache = ngx.shared.server_settings_cache
            local allow_cache    = ngx.shared.geolock_cache

            local slug = ngx.var.slug
            local geo  = ngx.var.geoip_country_code or ""
            local key  = slug .. "|" .. geo

            -- 1) fast‐path: final allow/deny
            local allowed = allow_cache:get(key)
            if allowed ~= nil then
                if not allowed then
                    return ngx.exit(ngx.HTTP_FORBIDDEN)
                end
                return
            end

            -- 2) load server settings (id, geolock, config)
            local id_key      = slug .. ":id"
            local gl_key      = slug .. ":geolock"
            local cfg_key     = slug .. ":config"
            local server_id   = settings_cache:get(id_key)
            local geolock     = settings_cache:get(gl_key)
            local config      = settings_cache:get(cfg_key)

            if not server_id then
                -- first time: fetch from MySQL
                local mysql = require "resty.mysql"
                local db, err = mysql:new()
                if not db then
                    ngx.log(ngx.ERR, "mysql:new() failed: ", err)
                    return ngx.exit(500)
                end
                db:set_timeout(1000)
                local ok
                ok, err = db:connect{
                    path     = "/usr/local/mediacp/mysql/data/mysql.sock",
                    database = "mediacp",
                    user     = "root",
                    password = "",
                    charset  = "utf8",
                }
                if not ok then
                    ngx.log(ngx.ERR, "DB connect error: ", err)
                    return ngx.exit(500)
                end

                local sql = string.format([[
                    SELECT id, geolock, geolock_config
                      FROM servers
                     WHERE slug = %s
                     LIMIT 1
                ]], ngx.quote_sql_str(slug))
                local res, err = db:query(sql)
                if not res or #res == 0 then
                    return ngx.exit(ngx.HTTP_NOT_FOUND)
                end

                server_id = tonumber(res[1].id)
                geolock   = tonumber(res[1].geolock)
                config    = tonumber(res[1].geolock_config)

                -- cache each separately for 10m
                settings_cache:set(id_key,    server_id, 600)
                settings_cache:set(gl_key,    geolock,   600)
                settings_cache:set(cfg_key,   config,    600)
            end

            -- 3) geolock logic
            if geolock == 0 or config == 0 then
                allowed = true
            else
                local country_sql = string.format([[
                    SELECT 1
                      FROM geolock_countries
                     WHERE server_id = %s
                       AND code      = %s
                     LIMIT 1
                ]], ngx.quote_sql_str(server_id),
                   ngx.quote_sql_str(geo))
                local db = require("resty.mysql").new()
                db:set_timeout(1000)
                db:connect{
                    path     = "/usr/local/mediacp/mysql/data/mysql.sock",
                    database = "mediacp",
                    user     = "root",
                    password = "",
                    charset  = "utf8",
                }
                local res, err = db:query(country_sql)
                if not res then
                    ngx.log(ngx.ERR, "DB query error: ", err)
                    return ngx.exit(500)
                end

                if config == 1 then
                    allowed = (#res > 0)
                elseif config == 2 then
                    allowed = not (#res > 0)
                else
                    allowed = true
                end
            end

            ngx.log(ngx.DEBUG, "slug=", slug,
                              " geo=", geo,
                              " geolock=", geolock,
                              " config=", config,
                              " allowed=", allowed)

            -- 4) cache decision
            allow_cache:set(key, allowed, 600)
            if not allowed then
                return ngx.exit(ngx.HTTP_FORBIDDEN)
            end
        }


        # ── 2) Serve via Kaltura VOD module
        #    Request: /hls/<slug>/<video>.mp4/index.m3u8
        #    Alias maps to /usr/local/mediacp/nginx/vod/<video>.mp4
        alias /usr/local/mediacp/nginx/vod/$slug/$video;

        # Activate on-the-fly HLS packaging
        vod hls;
        vod_mode local;
        vod_last_modified 'Sun, 19 Nov 2000 08:52:00 GMT';
        vod_last_modified_types *;
		vod_hls_segment_file_name_prefix   "segment";

        access_log /usr/local/mediacp/nginx/log/vod_access.log;
        error_log /usr/local/mediacp/nginx/log/vod_error.log;

        gzip on;
        gzip_types application/vnd.apple.mpegurl;

        add_header Access-Control-Allow-Headers '*';
        add_header Access-Control-Allow-Origin '*';
        add_header Access-Control-Allow-Methods 'GET, HEAD, OPTIONS';
    }

    location ~ ^/clear_vod_config_cache/(?<slug>[^/]+)$ {
        allow 127.0.0.1;
        deny all;

        content_by_lua_block {
            local slug = ngx.var.slug
            local settings_cache = ngx.shared.server_settings_cache
            local geolock_cache  = ngx.shared.geolock_cache

            -- delete the three settings keys
            settings_cache:delete(slug .. ":id")
            settings_cache:delete(slug .. ":geolock")
            settings_cache:delete(slug .. ":config")

            -- delete all geolock entries for this slug
            local keys = geolock_cache:get_keys(1000)
            for _, k in ipairs(keys) do
                if k:sub(1, #slug + 1) == slug .. "|" then
                    geolock_cache:delete(k)
                end
            end

            ngx.status = ngx.HTTP_OK
            ngx.say("Cleared cache for slug: ", slug)
        }
    }


    # Wowza Compatible URL
    location ~ ^/([^/]+)/mp4:(.+\.mp4)/playlist\.m3u8$ {
        # $1 → vodtest
        # $2 → sample.mp4
        proxy_pass http://127.0.0.1:2023/hls/$1/$2/index.m3u8;
        proxy_http_version 1.1;
        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_buffering off;
    }
