-- 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 log = require 'mc.logging'
local singleton = require 'mc.singleton'
local card_comm = require 'device.class.network_card_adapter.card_comm'
local card_resource_path = 'device.class.network_card_adapter.resource_tree'
local card_resource_asset_data = require(card_resource_path .. '.card_resource_asset_data')
local card_resource_listen_callback = require(card_resource_path .. '.card_resource_listen_callback')

local card_resource_tree = {}
card_resource_tree.__index = card_resource_tree

function card_resource_tree.new()
    return setmetatable({}, card_resource_tree)
end

local function properties_synchronizer(resource_obj)
    card_comm.update_root_bdf(resource_obj, resource_obj)
    card_comm.update_associated_resource(resource_obj, resource_obj)

    resource_obj:listen('DeviceLocator', function(_, value)
        if not card_comm.param_validator(value) then
            return
        end
        card_comm.set_resource_id_and_node_id(resource_obj.Type, resource_obj.DeviceLocator,
            resource_obj.Position, resource_obj)
    end)

    card_comm.listen_update_resource_tree_property(resource_obj, resource_obj)
end

function card_resource_tree:init_asset_data_info(resource_obj)
    if not resource_obj then
        log:error("resource_obj is nil")
        return
    end
    card_resource_asset_data.init_asset_data(resource_obj)
end

function card_resource_tree:update_asset_uuid_info(resource_obj)
    if not resource_obj then
        log:error("resource_obj is nil")
        return
    end
    card_resource_asset_data.update_asset_uuid(resource_obj)
end

function card_resource_tree:register_listen_callback(resource_obj)
    if not resource_obj then
        log:error("resource_obj is nil")
        return
    end
    card_resource_listen_callback.register_listen_callback(resource_obj)
end

function card_resource_tree:init_id(resource_obj)
    if not resource_obj then
        log:error("resource_obj is nil")
        return
    end
    -- bridge 不通过devicelocator生成ID信息
    if card_comm.is_virtual_port(resource_obj.Type) then
        return
    end
    resource_obj.BoardIDHex = string.format('0x%04x', resource_obj.BoardID)

    local retry_times = 0
    while not card_comm.param_validator(resource_obj.DeviceLocator) and retry_times < 10 do
        retry_times = retry_times + 1
        resource_obj.tasks:sleep_ms(5000)
    end
    card_comm.set_resource_id_and_node_id(resource_obj.Type, resource_obj.DeviceLocator,
        resource_obj.Position, resource_obj)

    resource_obj:register_mdb_objects()
    properties_synchronizer(resource_obj)
end

return singleton(card_resource_tree)