{# roles/sys-srv-web-inj-compose/templates/location.lua.j2 #}
{% macro push_snippets(list_name, features) -%}
{% set kind = list_name | regex_replace('_snippets$','') %}
{% for f in features if inj_enabled.get(f) -%}
{{ list_name }}[#{{ list_name }} + 1] = [=[
  {%- include 'roles/sys-srv-web-inj-' ~ f ~ '/templates/' ~ kind ~ '_sub.j2' -%}
]=]
{% endfor -%}
{%- endmacro %}

lua_need_request_body on;

header_filter_by_lua_block {
    local ct = ngx.header.content_type or ""
    if ct:lower():find("^text/html") then
        ngx.ctx.is_html = true
    else
        ngx.ctx.is_html = false
    end
}

body_filter_by_lua_block {
    -- only apply further processing if this is an HTML response
    if not ngx.ctx.is_html then
        return
    end

    -- initialize or reuse the buffer
    ngx.ctx.buf = ngx.ctx.buf or {}
    local chunk, eof = ngx.arg[1], ngx.arg[2]

    if chunk ~= "" then
        table.insert(ngx.ctx.buf, chunk)
    end

    if not eof then
        -- drop intermediate chunks; we’ll emit only on eof
        ngx.arg[1] = nil
        return
    end

    -- on eof: concatenate all buffered chunks
    local whole = table.concat(ngx.ctx.buf)
    ngx.ctx.buf = nil  -- clear buffer

    -- remove html CSP, due to management via Infinito.Nexus policies
    whole = whole:gsub(
        '<meta[^>]-http%-equiv=["\']Content%-Security%-Policy["\'][^>]->%s*',
        ''
    )

    -- build a list of head-injection snippets
    local head_snippets = {}

    {{ push_snippets('head_snippets', inj_head_features) }}

    -- inject all collected snippets right before </head>
    local head_payload = table.concat(head_snippets, "\n") .. "</head>"
    whole = ngx.re.gsub(whole, "</head>", head_payload, "ijo", nil, 1)

    -- build a list of body-injection snippets
    local body_snippets = {}

    {{ push_snippets('body_snippets', inj_body_features) }}

    -- inject all collected snippets right before </body>
    local body_payload = table.concat(body_snippets, "\n") .. "</body>"
    whole = ngx.re.gsub(whole, "</body>", body_payload, "ijo", nil, 1)

    -- finally send the modified HTML out
    ngx.arg[1] = whole
}
