-- 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 mdb = require 'mc.mdb'
local class = require 'mc.class'
local app_base = require 'mc.client_app_base'
local mdb_service = require 'mc.mdb.mdb_service'
local subscribe_signal = require 'mc.mdb.subscribe_signal'

local get_non_virtual_interface_objects = mdb_service.get_non_virtual_interface_objects
local foreach_non_virtual_interface_objects = mdb_service.foreach_non_virtual_interface_objects

local BlockIO = require 'frudata.json_types.BlockIO'
local Accessor = require 'frudata.json_types.Accessor'
local Connector = require 'frudata.json_types.Connector'
local FirmwareInfo = require 'frudata.json_types.FirmwareInfo'
local NodeLocation = require 'frudata.json_types.NodeLocation'

---@class frudata_client: BasicClient
local frudata_client = class(app_base.Client)

function frudata_client:GetBlockIOObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Chip.BlockIO', true)
end

function frudata_client:ForeachBlockIOObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Chip.BlockIO', cb, true)
end

function frudata_client:GetAccessorObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Accessor', true)
end

function frudata_client:ForeachAccessorObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Accessor', cb, true)
end

function frudata_client:GetConnectorObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Connector', true)
end

function frudata_client:ForeachConnectorObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Connector', cb, true)
end

function frudata_client:GetFirmwareInfoObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.UpdateService.FirmwareInfo', true)
end

function frudata_client:ForeachFirmwareInfoObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.UpdateService.FirmwareInfo', cb, true)
end

function frudata_client:OnBlockIOInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Chip.BlockIO')
end

function frudata_client:OnBlockIOInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Chip.BlockIO')
end

function frudata_client:OnAccessorInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Accessor')
end

function frudata_client:OnAccessorInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Accessor')
end

function frudata_client:OnConnectorInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Connector')
end

function frudata_client:OnConnectorInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Connector')
end

function frudata_client:OnFirmwareInfoInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.UpdateService.FirmwareInfo')
end

function frudata_client:OnFirmwareInfoInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.UpdateService.FirmwareInfo')
end

function frudata_client:GetNodeLocationNodeLocationObject(path_params)
    return mdb.try_get_object(self:get_bus(),
        path_params and ('/bmc/kepler/Managers/' .. path_params['ManagerId'] .. '/NodeLocation') or
            '/bmc/kepler/Managers/:ManagerId/NodeLocation', 'bmc.kepler.Managers.NodeLocation')
end

function frudata_client:GetNodeLocationObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.NodeLocation', true,
        {'/bmc/kepler/Managers/:ManagerId/NodeLocation'})
end

function frudata_client:ForeachNodeLocationObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.NodeLocation', cb, true,
        {'/bmc/kepler/Managers/:ManagerId/NodeLocation'})
end

function frudata_client:OnNodeLocationPropertiesChanged(cb, path_params)
    local path_namespace = path_params and ('/bmc/kepler/Managers/' .. path_params['ManagerId'] .. '/NodeLocation') or
                               '/bmc/kepler/Managers/:ManagerId/NodeLocation'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), path_namespace,
        cb, 'bmc.kepler.Managers.NodeLocation', {'LocationId'})
end

function frudata_client:OnNodeLocationInterfacesAdded(cb, path_params)
    local path_namespace = path_params and ('/bmc/kepler/Managers/' .. path_params['ManagerId'] .. '/NodeLocation') or
                               '/bmc/kepler/Managers/:ManagerId/NodeLocation'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), path_namespace, cb,
        'bmc.kepler.Managers.NodeLocation')
end

function frudata_client:OnNodeLocationInterfacesRemoved(cb, path_params)
    local path_namespace = path_params and ('/bmc/kepler/Managers/' .. path_params['ManagerId'] .. '/NodeLocation') or
                               '/bmc/kepler/Managers/:ManagerId/NodeLocation'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), path_namespace,
        cb, 'bmc.kepler.Managers.NodeLocation')
end

function frudata_client:ctor()
    self.signal_slots = {}
end

---@type frudata_client
return frudata_client.new('frudata')
