local redis = require "resty.redis"

-- 定义Redis连接参数
local REDIS_HOST = "redis"
local REDIS_PORT = 6379
local REDIS_PASSWORD = "secret_redis"
local REDIS_TIMEOUT = 1000  -- 1秒超时

local _M = {}

-- 设置后端upstream
function set_upstream(tenant, env)
    if env == "prod" then
        ngx.var.upstream = "php80_prod"
        ngx.var.root = "/www/autocde2.0_laravel_prod"
    elseif env == "dev" then
        ngx.var.upstream = "php80"
        ngx.var.upstream = "/www/autocde2.0_laravel"
    else
        ngx.log(ngx.ERR, "Upstream not found for env: " .. tostring(env))
        ngx.var.upstream = "php80_prod"
        ngx.var.upstream = "/www/autocde2.0_laravel_prod"
    end
    ngx.log(ngx.NOTICE, "Backend routing: ", "tenant=", tenant, ", env=", env, ", upstream=", ngx.var.upstream)
end

-- 设置前端upstream
function set_frontend_upstream(tenant, env)
    if env == "prod" then
        ngx.var.frontend_upstream = "frontend_prod"
    elseif env == "dev" then
        ngx.var.frontend_upstream = "frontend_dev"
    else

    end
    ngx.log(ngx.NOTICE, "Frontend routing: ", "tenant=", tenant, ", env=", env, ", frontend_upstream=", ngx.var.frontend_upstream)
end

-- 根据租户信息获取环境变量
function get_env(tenant)
    if not tenant then
        ngx.log(ngx.NOTICE, "Missing tenant identifier")
        tenant = "not_found"
    end
    local cache_key = "tenant_identification_location_" .. tenant
    local red = redis:new()
    red:set_timeouts(REDIS_TIMEOUT, REDIS_TIMEOUT, REDIS_TIMEOUT)

    -- 连接到Redis
    local ok, connect_err = red:connect(REDIS_HOST, REDIS_PORT)
    if not ok then
        ngx.log(ngx.ERR, "Redis connect failed: ", connect_err)
        return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)  -- 使用标准HTTP状态码
    end

    -- 认证Redis
    local ok, auth_err = red:auth(REDIS_PASSWORD)
    if not ok then
        ngx.log(ngx.ERR, "Failed to authenticate Redis: ", auth_err)
        return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
    end

    -- 选择数据库 0（默认数据库）
    local ok, err = red:select(0)
    if not ok then
        ngx.log(ngx.ERR, "Failed to select Redis database: ", err)
        return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
    end

    -- 从Redis中获取环境变量
    local env = red:get(cache_key)
    if not env then
        ngx.log(ngx.ERR, "No environment found for tenant key: ", cache_key)
        red:set_keepalive(10000, 100)  -- 归还连接到连接池
        return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)  -- 使用标准HTTP状态码
    end

    red:set_keepalive(10000, 100)

    return env
end

-- 处理API请求的路由逻辑
function _M.route_by_tenant_for_api()
    local args = ngx.req.get_uri_args()
    local tenant = ngx.req.get_headers()["X-Tenant"] or args["tenant"]

    if not tenant or tenant == "" then
        ngx.log(ngx.ERR, "Missing tenant identifier")
        return ngx.exit(ngx.HTTP_BAD_REQUEST)  -- 使用标准HTTP状态码
    end

    local env = get_env(tenant)
    set_upstream(tenant, env)
end

-- 处理前端请求的路由逻辑
function _M.route_by_tenant_for_frontend()
    local args = ngx.req.get_uri_args()
    local tenant = ngx.req.get_headers()["X-Tenant"] or args["tenant"]

    if not tenant or tenant == "" then
        ngx.log(ngx.ERR, "Missing tenant identifier")
        -- return ngx.exit(ngx.HTTP_BAD_REQUEST)  -- 使用标准HTTP状态码
    end

    local env = get_env(tenant)
    set_frontend_upstream(tenant, env)
end

return _M
