-- 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 object_manage = require 'mc.mdb.object_manage'
local class = require 'mc.class'
local c_tasks = require 'tasks'
local signal = require 'mc.signal'
local log = require 'mc.logging'
require 'object_manager.basic'

---@class c_mc_object_manage: c_basic_class
---@field on_add_object c_basic_signal
---@field on_delete_object c_basic_signal
---@field on_add_object_complete c_basic_signal
---@field on_delete_object_complete c_basic_signal
local c_mc_object_manage = class()

function c_mc_object_manage:ctor(bus)
    self.bus = bus
    self.on_add_object = signal.new()
    self.on_delete_object = signal.new()
    self.on_add_object_complete = signal.new()
    self.on_delete_object_complete = signal.new()

    -- before_add_object 用于自发现对象上树之前的处理，只要任何一个槽函数返回 false,
    -- 则框架终止上树流程，完全由业务自行决定上树时机
    self.on_before_add_object = signal.new(function(results)
        for _, r in ipairs(results) do
            if not r then
                return false
            end
        end
        return true
    end)
end

function c_mc_object_manage:init()
    c_tasks.get_instance():next_tick(function()
        self:install_signals()
    end)
end

function c_mc_object_manage:install_signals()
    log:notice('c_mc_object_manage: install object_manage signals')

    -- 添加对象回调
    object_manage.on_add_object(self.bus, function(class_name, object, position)
        log:debug('c_mc_object_manage add_object: class=%s, position=%s', class_name, position)
        self:add_object(class_name, object, position)
    end, function (object)
       return self:before_add_object(object.class_name, object)
    end)

    -- 删除对象回调
    object_manage.on_delete_object(self.bus, function(class_name, object, position)
        log:debug('c_mc_object_manage delete_object: class=%s, position=%s', class_name, position)
        self:del_object(class_name, object, position)
    end)

    -- 添加对象完成回调
    object_manage.on_add_object_complete(self.bus, function(position)
        log:debug('c_mc_object_manage add_object_complete: position=%s', position)
        self:add_object_complete(position)
    end)

    -- 删除对象完成回调
    object_manage.on_delete_object_complete(self.bus, function(position)
        log:debug('c_mc_object_manage delete_object_complete: position=%s', position)
        self:del_object_complete(position)
    end)
end

function c_mc_object_manage:before_add_object(class_name, object)
    return self.on_before_add_object:emit(class_name, object)
end

function c_mc_object_manage:add_object(class_name, object, position)
    self.on_add_object:emit(class_name, object, position)
end

function c_mc_object_manage:del_object(class_name, object, position)
    self.on_delete_object:emit(class_name, object, position)
end

function c_mc_object_manage:add_object_complete(position)
    self.on_add_object_complete:emit(position)
end

function c_mc_object_manage:del_object_complete(position)
    self.on_delete_object_complete:emit(position)
end

return c_mc_object_manage