-- 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 log = require 'mc.logging'
local json = require 'cjson'
local context = require 'mc.context'

local m = {}

local equipment_type_map = {
    ElectricalBuses = {"Bus"},
    FloorPDUs = {"FloorPDU"},
    TransferSwitches = {"AutomaticTransferSwitch", "ManualTransferSwitch"},
    PowerShelves = {"PowerShelf"},
    Switchgear = {"Switchgear"},
    RackPDUs = {"RackPDU"}
}

function m.is_power_distribution_supported(power_distribution_name)
    -- 获取对应的equipment_type列表
    local equipment_types = equipment_type_map[power_distribution_name]
    if not equipment_types then
        return false
    end

    -- 对于TransferSwitches，需要检查两种类型，只要有一种存在就返回true
    for _, equipment_type in ipairs(equipment_types) do
        local path = bus:call('bmc.kepler.maca', '/bmc/kepler/MdbService', 'bmc.kepler.Mdb', 'GetPath',
        'a{ss}ssb', context.new(), "bmc.kepler.PowerEquipment.PowerDistribution",
        json.encode({EquipmentType = equipment_type}), false)

        if path ~= '' then
            return true
        end
    end

    return false
end

function m.get_members(power_distribution_name, paths)
    if not paths then
        return {}
    end

    -- 获取对应的equipment_type列表
    local equipment_types = equipment_type_map[power_distribution_name]
    if not equipment_types then
        return {}
    end

    local uri_prefix = '/redfish/v1/PowerEquipment/' .. power_distribution_name
    local members = {}

    for _, v in ipairs(paths) do
        local obj = mdb.get_object(bus, v, 'bmc.kepler.PowerEquipment.PowerDistribution')
        if obj ~= nil then
            -- 检查设备类型是否符合映射关系
            for _, expected_type in ipairs(equipment_types) do
                if obj.EquipmentType == expected_type then
                    -- 从路径字符串中提取节点ID（最后一个/后的值）
                    local power_distribution_id = v:match("([^/]+)$")
                    members[#members + 1] = {['@odata.id'] = uri_prefix .. '/' .. power_distribution_id}
                    break -- 找到匹配类型后跳出内层循环
                end
            end
        end
    end

    return members
end

function m.is_valid_power_distribution_id(power_distribution_name, power_distribution_id)
    local equipment_types = equipment_type_map[power_distribution_name]
    if not equipment_types then
        return false
    end

    local path = '/bmc/kepler/PowerEquipment/PowerDistribution/' .. power_distribution_id
    local success, obj = pcall(function()
        return mdb.get_object(bus, path, 'bmc.kepler.PowerEquipment.PowerDistribution')
    end)

    if not success or obj == nil then
        log:error('path(%s), err(%s)', path, obj.message)
        return false
    end

    for _, equipment_type in ipairs(equipment_types) do
        if obj.EquipmentType == equipment_type then
            return true
        end
    end

    return false
end

return m