local balancer = require "ngx.balancer"
local exit = require "sm.utils.exit"
local cjson = require "cjson"
local os_getenv = os.getenv
local server_id = os_getenv("SERVER_ID")

local remote_addr = ngx.var.remote_addr
local request_id = ngx.var.request_id
local sources =  cjson.decode(ngx.var.sources)

ngx.log(ngx.INFO, "[Balancer] Sources: ".. ngx.var.sources)

-- 计算总权重
local total_weight = 0
for _, item in ipairs(sources) do
    total_weight = total_weight + item.weight
end

-- 生成随机数
local rand = math.random(total_weight)

-- 根据权重选择
local selected_item
if #sources == 1 then
    selected_item = sources[1]
else
    for _, item in ipairs(sources) do
        if rand <= item.weight then
            selected_item = item
            break
        else
            rand = rand - item.weight
        end
    end
end

ngx.log(ngx.INFO, "[Balancer] Selected upstream peer: ".. selected_item.address.. ":".. selected_item.port .. " sni: " .. (selected_item.host or ""))
balancer.set_timeouts(600, 600, 600)
local ok, err
if selected_item.resolve or selected_item.sni then
    ngx.log(ngx.INFO, "[Balancer] Set sni: " .. tostring(selected_item.sni))
    ok, err = balancer.set_current_peer(selected_item.ip, selected_item.port, selected_item.sni or selected_item.address)
else
    ngx.log(ngx.INFO, "[Balancer] Set sni: nil")
    ok, err = balancer.set_current_peer(selected_item.ip, selected_item.port)
end

if not ok then
    ngx.log(ngx.ERR, "[Balancer] Failed to set upstream peer" .. err)
    return exit.error(remote_addr, request_id, "[Balancer] Failed to set upstream peer" .. err)
end 