-- Copyright (c) 2025 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2
--
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.

local cjson = require 'cjson'
local utils = require 'mc.utils'
local log = require 'mc.logging'

local m = {}

function m.get_receiver_list(receiver_list)
    if not receiver_list or not cjson.json_object_is_array(receiver_list) or #receiver_list == 0 then
        return
    end

    for index, server in ipairs(receiver_list) do
        server.ReceiverId = index - 1
    end

    return receiver_list
end

local function convert_string_to_boolean(data)
    if data ~= "true" and data ~= "false" then
        return cjson.null
    end

    if data == "true" then
        return true
    elseif data == "false" then
        return false
    end
end

local function convert_activated_metrics_to_array(data)
    local ret = cjson.json_object_new_array()
    if #data == 0 then
        return ret
    end

    local activated_metrics = utils.split(data, ',')
    for i = 1, #activated_metrics do
        ret[#ret + 1] = activated_metrics[i]
    end

    return ret
end

local function get_supported_sampling_rate(supported_sampling_rate)
    local ret = cjson.json_object_new_array()
    if not supported_sampling_rate then
        log:error("Get supported sampling rate failed")
        return ret
    end

    for i = 1, #supported_sampling_rate do
        ret[#ret + 1] = supported_sampling_rate[i]
    end
    return ret
end

local function get_supported_metrics(supported_metrics)
    local ret = cjson.json_object_new_array()
    if not supported_metrics then
        log:error("Get supported metrics failed")
        return ret
    end

    for i = 1, #supported_metrics do
        ret[#ret + 1] = supported_metrics[i]
    end
    return ret
end

function m.convert_traces_config_to_object(config, supported_sampling_rate)
    local result = cjson.json_object_new_object()
    result.SamplingRate = tonumber(config.SamplingRate)
    result.SupportedSamplingRate = get_supported_sampling_rate(supported_sampling_rate)
    result.SamplingPolicy = config.SamplingPolicy
    result.SamplingLevel = config.SamplingLevel
    result.ExportIntervalSeconds = tonumber(config.ExportIntervalSeconds)

    return result
end

function m.convert_metrics_config_to_object(config, supported_metrics)
    local result = cjson.json_object_new_object()
    result.ExportIntervalSeconds = tonumber(config.ExportIntervalSeconds)
    result.SupportedMetrics = get_supported_metrics(supported_metrics)
    result.ActivatedMetrics = convert_activated_metrics_to_array(config.ActivatedMetrics)

    return result
end

function m.convert_logs_config_to_object(config)
    local result = cjson.json_object_new_object()
    result.Enabled = convert_string_to_boolean(config.Enabled)
    result.ExportIntervalSeconds = tonumber(config.ExportIntervalSeconds)

    return result
end

local function convert_activated_metrics_to_string(data)
    -- 如果不设置ActivatedMetrics属性或异常情况则返回nil字符串，避免业务进行设置处理
    if type(data) ~= "userdata" then
        return 'nil'
    end

    -- 长度为0表示用户将所有指标使能置false，则返回空字符串
    if #data == 0 then
        return ''
    end

    local obj = mdb.get_object(bus, '/bmc/kepler/ObservabilityService/Metrics',
        'bmc.kepler.ObservabilityService.Metrics')
    if not obj then
        log:error("Get metrics obj failed")
        return 'nil'
    end

    for i = 1, #data do
        if not utils.array_contains(obj.SupportedMetrics, data[i]) then
            local related_properties = "Metrics/ActivatedMetrics/" .. (i - 1)
            local err = base_messages.PropertyValueNotInList(data[i], related_properties)
            err.RelatedProperties = {'#/' .. related_properties}
            error(err)
        end
    end
    return table.concat(data, ',')
end

function m.convert_traces_config_to_string(config)
    local result = {}

    local obj = mdb.get_object(bus, '/bmc/kepler/ObservabilityService/Traces',
        'bmc.kepler.ObservabilityService.Traces')
    if not obj then
        log:error("Get traces obj failed")
        return result
    end

    result.SamplingRate = tostring(config.SamplingRate) or ''
    if config.SamplingRate and not utils.array_contains(obj.SupportedSamplingRate, config.SamplingRate) then
        local related_properties = "Traces/SamplingRate"
        local err = base_messages.PropertyValueNotInList(config.SamplingRate, related_properties)
        err.RelatedProperties = {'#/' .. related_properties}
        error(err)
    end

    result.SamplingPolicy = config.SamplingPolicy
    result.SamplingLevel = config.SamplingLevel
    result.ExportIntervalSeconds = tostring(config.ExportIntervalSeconds) or ''

    return result
end

function m.convert_metrics_config_to_string(config)
    local result = {}
    result.ExportIntervalSeconds = tostring(config.ExportIntervalSeconds) or ''
    result.ActivatedMetrics = convert_activated_metrics_to_string(config.ActivatedMetrics)

    return result
end

function m.convert_logs_config_to_string(config)
    local result = {}
    result.Enabled = tostring(config.Enabled) or ''
    result.ExportIntervalSeconds = tostring(config.ExportIntervalSeconds) or ''

    return result
end

return m
