-- 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 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 org_freedesktop_dbus = require 'sd_bus.org_freedesktop_dbus'

local match_rule = org_freedesktop_dbus.MatchRule
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 Scanner = require 'fructrl.json_types.Scanner'
local Accessor = require 'fructrl.json_types.Accessor'
local Env = require 'fructrl.json_types.Env'
local SecureBoot = require 'fructrl.json_types.SecureBoot'
local SystemControl = require 'fructrl.json_types.SystemControl'
local SystemsFruCtrl = require 'fructrl.json_types.SystemsFruCtrl'
local Reboot = require 'fructrl.json_types.Reboot'

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

function fructrl_client:GetScannerObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Scanner', true)
end

function fructrl_client:ForeachScannerObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Scanner', cb, true)
end

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

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

function fructrl_client:GetEnvObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.SOC.Env', true)
end

function fructrl_client:ForeachEnvObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.SOC.Env', cb, true)
end

function fructrl_client:GetSecureBootObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.SOC.SecureCore.SecureBoot', true)
end

function fructrl_client:ForeachSecureBootObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.SOC.SecureCore.SecureBoot', cb,
        true)
end

function fructrl_client:GetSystemControlObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.SystemControl', true)
end

function fructrl_client:ForeachSystemControlObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.SystemControl', cb, true)
end

function fructrl_client:GetSystemsFruCtrlObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.FruCtrl', true)
end

function fructrl_client:ForeachSystemsFruCtrlObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.FruCtrl', cb, true)
end

function fructrl_client:GetRebootObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.MicroComponent.Reboot', true)
end

function fructrl_client:ForeachRebootObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.MicroComponent.Reboot', cb, true)
end

function fructrl_client:OnScannerPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Scanner')
end

function fructrl_client:OnScannerInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Scanner')
end

function fructrl_client:OnScannerInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Scanner')
end

function fructrl_client:OnAccessorPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Accessor')
end

function fructrl_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 fructrl_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 fructrl_client:OnEnvPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.SOC.Env')
end

function fructrl_client:OnEnvInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.SOC.Env')
end

function fructrl_client:OnEnvInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.SOC.Env')
end

function fructrl_client:OnSecureBootPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.SOC.SecureCore.SecureBoot')
end

function fructrl_client:OnSecureBootInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.SOC.SecureCore.SecureBoot')
end

function fructrl_client:OnSecureBootInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.SOC.SecureCore.SecureBoot')
end

function fructrl_client:OnSystemControlPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.SystemControl')
end

function fructrl_client:OnSystemControlInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.SystemControl')
end

function fructrl_client:OnSystemControlInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.SystemControl')
end

function fructrl_client:OnSystemsFruCtrlPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.FruCtrl')
end

function fructrl_client:OnSystemsFruCtrlInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.FruCtrl')
end

function fructrl_client:OnSystemsFruCtrlInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.FruCtrl')
end

function fructrl_client:OnRebootPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.MicroComponent.Reboot')
end

function fructrl_client:OnRebootInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.MicroComponent.Reboot')
end

function fructrl_client:OnRebootInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.MicroComponent.Reboot')
end

function fructrl_client:SubscribeSystemsFruCtrlBeforePowerOnSignal(cb)
    local sig = match_rule.signal('BeforePowerOnSignal', 'bmc.kepler.Systems.FruCtrl')
    self.signal_slots[#self.signal_slots + 1] = self:get_bus():match(sig, function(msg)
        cb(msg:read())
    end)
end

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

---@type fructrl_client
return fructrl_client.new('fructrl')
