-- Copyright (c) 2024 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 m = {}

-- 内存资源树接口
local MEMORY_MDB_INTF <const> = "bmc.kepler.Systems.Memory"

-- multihost获取在位内存的总容量
function m.get_capacity(input)
    local capacity = 0
    local obj
    for _, path in ipairs(input) do
        for key, realpath in ipairs(path) do
            obj = mdb.get_object(bus, realpath, MEMORY_MDB_INTF)
            if obj.Presence == 1 then
                capacity = capacity + obj.CapacityMiB
            end
        end
    end
    return capacity // 1024 -- 转成以G为单位
end

-- multihost获取所有内存最大数量
function m.get_memory_count(input)
    local res = 0
    local data
    for _, path in ipairs(input) do
        for key, realpath in ipairs(path) do
            res = res + 1
        end
    end
    return res
end

-- multihost获取所有在位内存数量
function m.get_memory_presence_count(input)
    local res = 0
    local obj
    for _, path in ipairs(input) do
        for key, realpath in ipairs(path) do
            obj = mdb.get_object(bus, realpath, MEMORY_MDB_INTF)
            if obj.Presence == 1 then
                res = res + 1
            end
        end
    end
    return res
end

local function get_data_from_obj(realpath, res)
    local data = {}
    local obj = mdb.get_object(bus, realpath, MEMORY_MDB_INTF)
    if obj.Presence == 1 then
        data.AllowedSpeedsMHz = obj.AllowedSpeedsMHz
        data.CapacityMiB = obj.CapacityMiB
        data.DeviceLocator = obj.DeviceLocator
        if not obj.MemoryDeviceType then
            data.DeviceType = ''
        elseif obj.MemoryDeviceType == 'DDR5' then
            data.DeviceType = 'DDR'
        else
            data.DeviceType = obj.MemoryDeviceType
        end
        data.Manufacturer = obj.Manufacturer
        data.OperatingSpeedMHz = obj.OperatingSpeedMhz
        if not obj.Position or obj.Position == '' then
            data.Position = 'mainboard'
        else
            data.Position = obj.Position
        end
        table.insert(res, {
            ['General'] = data
        })
    end
end

-- multihost获取所有内存
function m.get_memory(input)
    local res = {}
    local data
    for _, path in ipairs(input) do
        for key, realpath in ipairs(path) do
            get_data_from_obj(realpath, res)
        end
    end
    table.sort(res, function(a , b)
        return (a.General.DeviceLocator or '') < (b.General.DeviceLocator or '')
    end)
    return res
end

return m
