-- 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 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 UpdateService = require 'power_mgmt.json_types.UpdateService'
local FirmwareInventory = require 'power_mgmt.json_types.FirmwareInventory'
local FirmwareInfo = require 'power_mgmt.json_types.FirmwareInfo'
local Time = require 'power_mgmt.json_types.Time'
local BlockIO = require 'power_mgmt.json_types.BlockIO'
local Component = require 'power_mgmt.json_types.Component'
local Frudata = require 'power_mgmt.json_types.Frudata'
local FruCtrl = require 'power_mgmt.json_types.FruCtrl'
local Events = require 'power_mgmt.json_types.Events'
local Task = require 'power_mgmt.json_types.Task'
local Chassis = require 'power_mgmt.json_types.Chassis'
local SerialManagement = require 'power_mgmt.json_types.SerialManagement'
local Uart = require 'power_mgmt.json_types.Uart'
local File = require 'power_mgmt.json_types.File'
local Performance = require 'power_mgmt.json_types.Performance'

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

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

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

function power_mgmt_client:GetTimeObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.Time', true)
end

function power_mgmt_client:ForeachTimeObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.Time', cb, true)
end

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

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

function power_mgmt_client:GetComponentObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Component', true)
end

function power_mgmt_client:ForeachComponentObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Component', cb, true)
end

function power_mgmt_client:GetFrudataObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.FrudataService.Frudata', true)
end

function power_mgmt_client:ForeachFrudataObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.FrudataService.Frudata', cb, true)
end

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

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

function power_mgmt_client:GetEventsObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Events', true)
end

function power_mgmt_client:ForeachEventsObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Events', cb, true)
end

function power_mgmt_client:GetTaskObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.TaskService.Task', true)
end

function power_mgmt_client:ForeachTaskObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.TaskService.Task', cb, true)
end

function power_mgmt_client:GetSerialManagementObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.SerialManagement', true)
end

function power_mgmt_client:ForeachSerialManagementObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.SerialManagement', cb, true)
end

function power_mgmt_client:GetUartObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.Uart', true)
end

function power_mgmt_client:ForeachUartObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.Uart', cb, true)
end

function power_mgmt_client:GetPerformanceObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Debug.Performance', true)
end

function power_mgmt_client:ForeachPerformanceObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Debug.Performance', cb, true)
end

function power_mgmt_client:GetUpdateServiceUpdateServiceObject()
    return mdb.try_get_object(self:get_bus(), '/bmc/kepler/UpdateService', 'bmc.kepler.UpdateService')
end

function power_mgmt_client:OnUpdateServiceInterfacesAdded(cb)
    local path_namespace = '/bmc/kepler/UpdateService'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), path_namespace, cb,
        'bmc.kepler.UpdateService')
end

function power_mgmt_client:OnUpdateServiceInterfacesRemoved(cb)
    local path_namespace = '/bmc/kepler/UpdateService'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), path_namespace,
        cb, 'bmc.kepler.UpdateService')
end

function power_mgmt_client:GetFirmwareInventoryFirmwareInventoryObject()
    return mdb.try_get_object(self:get_bus(), '/bmc/kepler/UpdateService/FirmwareInventory',
        'bmc.kepler.UpdateService.FirmwareInventory')
end

function power_mgmt_client:OnFirmwareInventoryInterfacesAdded(cb)
    local path_namespace = '/bmc/kepler/UpdateService/FirmwareInventory'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), path_namespace, cb,
        'bmc.kepler.UpdateService.FirmwareInventory')
end

function power_mgmt_client:OnFirmwareInventoryInterfacesRemoved(cb)
    local path_namespace = '/bmc/kepler/UpdateService/FirmwareInventory'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), path_namespace,
        cb, 'bmc.kepler.UpdateService.FirmwareInventory')
end

function power_mgmt_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 power_mgmt_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 power_mgmt_client:OnTimeInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.Time')
end

function power_mgmt_client:OnTimeInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.Time')
end

function power_mgmt_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 power_mgmt_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 power_mgmt_client:OnComponentInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Component')
end

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

function power_mgmt_client:OnFrudataInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.FrudataService.Frudata')
end

function power_mgmt_client:OnFrudataInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.FrudataService.Frudata')
end

function power_mgmt_client:OnFruCtrlPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.FruCtrl', {'PowerState'})
end

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

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

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

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

function power_mgmt_client:OnTaskInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.TaskService.Task')
end

function power_mgmt_client:OnTaskInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.TaskService.Task')
end

function power_mgmt_client:GetChassisChassisObject(path_params)
    return mdb.try_get_object(self:get_bus(), path_params and ('/bmc/kepler/Chassis/' .. path_params['ChassisId']) or
        '/bmc/kepler/Chassis/:ChassisId', 'bmc.kepler.Chassis')
end

function power_mgmt_client:OnChassisInterfacesAdded(cb, path_params)
    local path_namespace = path_params and ('/bmc/kepler/Chassis/' .. path_params['ChassisId']) or '/bmc/kepler/Chassis'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), path_namespace, cb,
        'bmc.kepler.Chassis')
end

function power_mgmt_client:OnChassisInterfacesRemoved(cb, path_params)
    local path_namespace = path_params and ('/bmc/kepler/Chassis/' .. path_params['ChassisId']) or '/bmc/kepler/Chassis'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), path_namespace,
        cb, 'bmc.kepler.Chassis')
end

function power_mgmt_client:GetEventsEventsObject(path_params)
    return mdb.try_get_object(self:get_bus(),
        path_params and ('/bmc/kepler/Systems/' .. path_params['SystemId'] .. '/Events') or
            '/bmc/kepler/Systems/:SystemId/Events', 'bmc.kepler.Systems.Events')
end

function power_mgmt_client:OnEventsInterfacesAdded(cb, path_params)
    local path_namespace = path_params and ('/bmc/kepler/Systems/' .. path_params['SystemId'] .. '/Events') or
                               '/bmc/kepler/Systems'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), path_namespace, cb,
        'bmc.kepler.Systems.Events')
end

function power_mgmt_client:OnEventsInterfacesRemoved(cb, path_params)
    local path_namespace = path_params and ('/bmc/kepler/Systems/' .. path_params['SystemId'] .. '/Events') or
                               '/bmc/kepler/Systems'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), path_namespace,
        cb, 'bmc.kepler.Systems.Events')
end

function power_mgmt_client:OnSerialManagementInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.SerialManagement')
end

function power_mgmt_client:OnSerialManagementInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.SerialManagement')
end

function power_mgmt_client:OnUartInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.Uart')
end

function power_mgmt_client:OnUartInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.Uart')
end

function power_mgmt_client:GetFileFileObject(path_params)
    return mdb.try_get_object(self:get_bus(),
        path_params and ('/bmc/kepler/Managers/' .. path_params['Id'] .. '/Security/File') or
            '/bmc/kepler/Managers/:Id/Security/File', 'bmc.kepler.Managers.Security.File')
end

function power_mgmt_client:OnFileInterfacesAdded(cb, path_params)
    local path_namespace = path_params and ('/bmc/kepler/Managers/' .. path_params['Id'] .. '/Security/File') or
                               '/bmc/kepler/Managers'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), path_namespace, cb,
        'bmc.kepler.Managers.Security.File')
end

function power_mgmt_client:OnFileInterfacesRemoved(cb, path_params)
    local path_namespace = path_params and ('/bmc/kepler/Managers/' .. path_params['Id'] .. '/Security/File') or
                               '/bmc/kepler/Managers'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), path_namespace,
        cb, 'bmc.kepler.Managers.Security.File')
end

function power_mgmt_client:OnPerformancePropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Debug.Performance')
end

function power_mgmt_client:OnPerformanceInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Debug.Performance')
end

function power_mgmt_client:OnPerformanceInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Debug.Performance')
end

---@param FilePath string
---@param Parameters UpdateService.Object
---@return UpdateService.StartUpgradeRsp
function power_mgmt_client:UpdateServiceUpdateServiceStartUpgrade(ctx, FilePath, Parameters)
    local req = UpdateService.StartUpgradeReq.new(FilePath, Parameters):validate()
    local obj = self:GetUpdateServiceUpdateServiceObject()

    return UpdateService.StartUpgradeRsp.new(obj:StartUpgrade(ctx, req:unpack(true)))
end

function power_mgmt_client:PUpdateServiceUpdateServiceStartUpgrade(ctx, FilePath, Parameters)
    return pcall(function()
        local req = UpdateService.StartUpgradeReq.new(FilePath, Parameters):validate()
        local obj = self:GetUpdateServiceUpdateServiceObject()

        return UpdateService.StartUpgradeRsp.new(obj:StartUpgrade(ctx, req:unpack(true)))
    end)
end

---@param SystemId integer
---@param FirmwareType string
---@param VersionStr string
---@param PrepareResult integer
---@return UpdateService.PrepareReplyRsp
function power_mgmt_client:UpdateServiceUpdateServicePrepareReply(ctx, SystemId, FirmwareType, VersionStr, PrepareResult)
    local req = UpdateService.PrepareReplyReq.new(SystemId, FirmwareType, VersionStr, PrepareResult):validate()
    local obj = self:GetUpdateServiceUpdateServiceObject()

    return UpdateService.PrepareReplyRsp.new(obj:PrepareReply(ctx, req:unpack(true)))
end

function power_mgmt_client:PUpdateServiceUpdateServicePrepareReply(ctx, SystemId, FirmwareType, VersionStr,
    PrepareResult)
    return pcall(function()
        local req = UpdateService.PrepareReplyReq.new(SystemId, FirmwareType, VersionStr, PrepareResult):validate()
        local obj = self:GetUpdateServiceUpdateServiceObject()

        return UpdateService.PrepareReplyRsp.new(obj:PrepareReply(ctx, req:unpack(true)))
    end)
end

---@param SystemId integer
---@param FirmwareType string
---@param ProcessResult integer
---@return UpdateService.ProcessReplyRsp
function power_mgmt_client:UpdateServiceUpdateServiceProcessReply(ctx, SystemId, FirmwareType, ProcessResult)
    local req = UpdateService.ProcessReplyReq.new(SystemId, FirmwareType, ProcessResult):validate()
    local obj = self:GetUpdateServiceUpdateServiceObject()

    return UpdateService.ProcessReplyRsp.new(obj:ProcessReply(ctx, req:unpack(true)))
end

function power_mgmt_client:PUpdateServiceUpdateServiceProcessReply(ctx, SystemId, FirmwareType, ProcessResult)
    return pcall(function()
        local req = UpdateService.ProcessReplyReq.new(SystemId, FirmwareType, ProcessResult):validate()
        local obj = self:GetUpdateServiceUpdateServiceObject()

        return UpdateService.ProcessReplyRsp.new(obj:ProcessReply(ctx, req:unpack(true)))
    end)
end

---@param SystemId integer
---@param FirmwareType string
---@param FinishResult integer
---@return UpdateService.FinishReplyRsp
function power_mgmt_client:UpdateServiceUpdateServiceFinishReply(ctx, SystemId, FirmwareType, FinishResult)
    local req = UpdateService.FinishReplyReq.new(SystemId, FirmwareType, FinishResult):validate()
    local obj = self:GetUpdateServiceUpdateServiceObject()

    return UpdateService.FinishReplyRsp.new(obj:FinishReply(ctx, req:unpack(true)))
end

function power_mgmt_client:PUpdateServiceUpdateServiceFinishReply(ctx, SystemId, FirmwareType, FinishResult)
    return pcall(function()
        local req = UpdateService.FinishReplyReq.new(SystemId, FirmwareType, FinishResult):validate()
        local obj = self:GetUpdateServiceUpdateServiceObject()

        return UpdateService.FinishReplyRsp.new(obj:FinishReply(ctx, req:unpack(true)))
    end)
end

---@param SystemId integer
---@param FirmwareType string
---@param ResultCode integer
---@param Progress integer
---@param ResultDetail string
---@return UpdateService.UpdateUpgradeStatusRsp
function power_mgmt_client:UpdateServiceUpdateServiceUpdateUpgradeStatus(ctx, SystemId, FirmwareType, ResultCode,
    Progress, ResultDetail)
    local req =
        UpdateService.UpdateUpgradeStatusReq.new(SystemId, FirmwareType, ResultCode, Progress, ResultDetail):validate()
    local obj = self:GetUpdateServiceUpdateServiceObject()

    return UpdateService.UpdateUpgradeStatusRsp.new(obj:UpdateUpgradeStatus(ctx, req:unpack(true)))
end

function power_mgmt_client:PUpdateServiceUpdateServiceUpdateUpgradeStatus(ctx, SystemId, FirmwareType, ResultCode,
    Progress, ResultDetail)
    return pcall(function()
        local req =
            UpdateService.UpdateUpgradeStatusReq.new(SystemId, FirmwareType, ResultCode, Progress, ResultDetail):validate()
        local obj = self:GetUpdateServiceUpdateServiceObject()

        return UpdateService.UpdateUpgradeStatusRsp.new(obj:UpdateUpgradeStatus(ctx, req:unpack(true)))
    end)
end

---@param TaskId integer
---@return UpdateService.GetUpgradeStatusRsp
function power_mgmt_client:UpdateServiceUpdateServiceGetUpgradeStatus(ctx, TaskId)
    local req = UpdateService.GetUpgradeStatusReq.new(TaskId):validate()
    local obj = self:GetUpdateServiceUpdateServiceObject()

    return UpdateService.GetUpgradeStatusRsp.new(obj:GetUpgradeStatus(ctx, req:unpack(true)))
end

function power_mgmt_client:PUpdateServiceUpdateServiceGetUpgradeStatus(ctx, TaskId)
    return pcall(function()
        local req = UpdateService.GetUpgradeStatusReq.new(TaskId):validate()
        local obj = self:GetUpdateServiceUpdateServiceObject()

        return UpdateService.GetUpgradeStatusRsp.new(obj:GetUpgradeStatus(ctx, req:unpack(true)))
    end)
end

---@param SystemId integer
---@param Id string
---@return UpdateService.RollbackRsp
function power_mgmt_client:UpdateServiceUpdateServiceRollback(ctx, SystemId, Id)
    local req = UpdateService.RollbackReq.new(SystemId, Id):validate()
    local obj = self:GetUpdateServiceUpdateServiceObject()

    return UpdateService.RollbackRsp.new(obj:Rollback(ctx, req:unpack(true)))
end

function power_mgmt_client:PUpdateServiceUpdateServiceRollback(ctx, SystemId, Id)
    return pcall(function()
        local req = UpdateService.RollbackReq.new(SystemId, Id):validate()
        local obj = self:GetUpdateServiceUpdateServiceObject()

        return UpdateService.RollbackRsp.new(obj:Rollback(ctx, req:unpack(true)))
    end)
end

---@param SystemId integer
---@param Id string
---@return UpdateService.ExportRsp
function power_mgmt_client:UpdateServiceUpdateServiceExport(ctx, SystemId, Id)
    local req = UpdateService.ExportReq.new(SystemId, Id):validate()
    local obj = self:GetUpdateServiceUpdateServiceObject()

    return UpdateService.ExportRsp.new(obj:Export(ctx, req:unpack(true)))
end

function power_mgmt_client:PUpdateServiceUpdateServiceExport(ctx, SystemId, Id)
    return pcall(function()
        local req = UpdateService.ExportReq.new(SystemId, Id):validate()
        local obj = self:GetUpdateServiceUpdateServiceObject()

        return UpdateService.ExportRsp.new(obj:Export(ctx, req:unpack(true)))
    end)
end

---@param FilePath string
---@param FirmwareType string
---@return UpdateService.CheckFirmwareTypeRsp
function power_mgmt_client:UpdateServiceUpdateServiceCheckFirmwareType(ctx, FilePath, FirmwareType)
    local req = UpdateService.CheckFirmwareTypeReq.new(FilePath, FirmwareType):validate()
    local obj = self:GetUpdateServiceUpdateServiceObject()

    return UpdateService.CheckFirmwareTypeRsp.new(obj:CheckFirmwareType(ctx, req:unpack(true)))
end

function power_mgmt_client:PUpdateServiceUpdateServiceCheckFirmwareType(ctx, FilePath, FirmwareType)
    return pcall(function()
        local req = UpdateService.CheckFirmwareTypeReq.new(FilePath, FirmwareType):validate()
        local obj = self:GetUpdateServiceUpdateServiceObject()

        return UpdateService.CheckFirmwareTypeRsp.new(obj:CheckFirmwareType(ctx, req:unpack(true)))
    end)
end

---@param FilePath string
---@return UpdateService.ParseFirmwarePackageRsp
function power_mgmt_client:UpdateServiceUpdateServiceParseFirmwarePackage(ctx, FilePath)
    local req = UpdateService.ParseFirmwarePackageReq.new(FilePath):validate()
    local obj = self:GetUpdateServiceUpdateServiceObject()

    return UpdateService.ParseFirmwarePackageRsp.new(obj:ParseFirmwarePackage(ctx, req:unpack(true)))
end

function power_mgmt_client:PUpdateServiceUpdateServiceParseFirmwarePackage(ctx, FilePath)
    return pcall(function()
        local req = UpdateService.ParseFirmwarePackageReq.new(FilePath):validate()
        local obj = self:GetUpdateServiceUpdateServiceObject()

        return UpdateService.ParseFirmwarePackageRsp.new(obj:ParseFirmwarePackage(ctx, req:unpack(true)))
    end)
end

---@param FirmwareInfoTable FirmwareInventory.Object
---@param Updateable boolean
---@param Capability integer
---@param MaxPackageSizeMiB integer
---@return FirmwareInventory.AddRsp
function power_mgmt_client:FirmwareInventoryFirmwareInventoryAdd(ctx, FirmwareInfoTable, Updateable, Capability,
    MaxPackageSizeMiB)
    local req = FirmwareInventory.AddReq.new(FirmwareInfoTable, Updateable, Capability, MaxPackageSizeMiB):validate()
    local obj = self:GetFirmwareInventoryFirmwareInventoryObject()

    return FirmwareInventory.AddRsp.new(obj:Add(ctx, req:unpack(true)))
end

function power_mgmt_client:PFirmwareInventoryFirmwareInventoryAdd(ctx, FirmwareInfoTable, Updateable, Capability,
    MaxPackageSizeMiB)
    return pcall(function()
        local req =
            FirmwareInventory.AddReq.new(FirmwareInfoTable, Updateable, Capability, MaxPackageSizeMiB):validate()
        local obj = self:GetFirmwareInventoryFirmwareInventoryObject()

        return FirmwareInventory.AddRsp.new(obj:Add(ctx, req:unpack(true)))
    end)
end

---@param Id string
---@return FirmwareInventory.DeleteRsp
function power_mgmt_client:FirmwareInventoryFirmwareInventoryDelete(ctx, Id)
    local req = FirmwareInventory.DeleteReq.new(Id):validate()
    local obj = self:GetFirmwareInventoryFirmwareInventoryObject()

    return FirmwareInventory.DeleteRsp.new(obj:Delete(ctx, req:unpack(true)))
end

function power_mgmt_client:PFirmwareInventoryFirmwareInventoryDelete(ctx, Id)
    return pcall(function()
        local req = FirmwareInventory.DeleteReq.new(Id):validate()
        local obj = self:GetFirmwareInventoryFirmwareInventoryObject()

        return FirmwareInventory.DeleteRsp.new(obj:Delete(ctx, req:unpack(true)))
    end)
end

---@param EventCode string
---@param Enabled integer
---@param ObjectIndex integer
---@param MockState integer
---@return Events.MockEventRsp
function power_mgmt_client:EventsEventsMockEvent(ctx, path_params, EventCode, Enabled, ObjectIndex, MockState)
    local req = Events.MockEventReq.new(EventCode, Enabled, ObjectIndex, MockState):validate()
    local obj = self:GetEventsEventsObject(path_params)

    return Events.MockEventRsp.new(obj:MockEvent(ctx, req:unpack(true)))
end

function power_mgmt_client:PEventsEventsMockEvent(ctx, path_params, EventCode, Enabled, ObjectIndex, MockState)
    return pcall(function()
        local req = Events.MockEventReq.new(EventCode, Enabled, ObjectIndex, MockState):validate()
        local obj = self:GetEventsEventsObject(path_params)

        return Events.MockEventRsp.new(obj:MockEvent(ctx, req:unpack(true)))
    end)
end

---@param StartId integer
---@param Count integer
---@param QueryParameters Events.KeyValueTable[]
---@return Events.GetAlarmListRsp
function power_mgmt_client:EventsEventsGetAlarmList(ctx, path_params, StartId, Count, QueryParameters)
    local req = Events.GetAlarmListReq.new(StartId, Count, QueryParameters):validate()
    local obj = self:GetEventsEventsObject(path_params)

    return Events.GetAlarmListRsp.new(obj:GetAlarmList(ctx, req:unpack(true)))
end

function power_mgmt_client:PEventsEventsGetAlarmList(ctx, path_params, StartId, Count, QueryParameters)
    return pcall(function()
        local req = Events.GetAlarmListReq.new(StartId, Count, QueryParameters):validate()
        local obj = self:GetEventsEventsObject(path_params)

        return Events.GetAlarmListRsp.new(obj:GetAlarmList(ctx, req:unpack(true)))
    end)
end

---@param StartId integer
---@param Count integer
---@param QueryParameters Events.KeyValueTable[]
---@return Events.GetEventListRsp
function power_mgmt_client:EventsEventsGetEventList(ctx, path_params, StartId, Count, QueryParameters)
    local req = Events.GetEventListReq.new(StartId, Count, QueryParameters):validate()
    local obj = self:GetEventsEventsObject(path_params)

    return Events.GetEventListRsp.new(obj:GetEventList(ctx, req:unpack(true)))
end

function power_mgmt_client:PEventsEventsGetEventList(ctx, path_params, StartId, Count, QueryParameters)
    return pcall(function()
        local req = Events.GetEventListReq.new(StartId, Count, QueryParameters):validate()
        local obj = self:GetEventsEventsObject(path_params)

        return Events.GetEventListRsp.new(obj:GetEventList(ctx, req:unpack(true)))
    end)
end

---@return Events.ClearEventListRsp
function power_mgmt_client:EventsEventsClearEventList(ctx, path_params)
    local obj = self:GetEventsEventsObject(path_params)

    return Events.ClearEventListRsp.new(obj:ClearEventList(ctx))
end

function power_mgmt_client:PEventsEventsClearEventList(ctx, path_params)
    return pcall(function()
        local obj = self:GetEventsEventsObject(path_params)

        return Events.ClearEventListRsp.new(obj:ClearEventList(ctx))
    end)
end

---@return Events.GetEventInfoRsp
function power_mgmt_client:EventsEventsGetEventInfo(ctx, path_params)
    local obj = self:GetEventsEventsObject(path_params)

    return Events.GetEventInfoRsp.new(obj:GetEventInfo(ctx))
end

function power_mgmt_client:PEventsEventsGetEventInfo(ctx, path_params)
    return pcall(function()
        local obj = self:GetEventsEventsObject(path_params)

        return Events.GetEventInfoRsp.new(obj:GetEventInfo(ctx))
    end)
end

---@param EventCode string
---@param MaskState integer
---@param Mode integer
---@return Events.MaskEventRsp
function power_mgmt_client:EventsEventsMaskEvent(ctx, path_params, EventCode, MaskState, Mode)
    local req = Events.MaskEventReq.new(EventCode, MaskState, Mode):validate()
    local obj = self:GetEventsEventsObject(path_params)

    return Events.MaskEventRsp.new(obj:MaskEvent(ctx, req:unpack(true)))
end

function power_mgmt_client:PEventsEventsMaskEvent(ctx, path_params, EventCode, MaskState, Mode)
    return pcall(function()
        local req = Events.MaskEventReq.new(EventCode, MaskState, Mode):validate()
        local obj = self:GetEventsEventsObject(path_params)

        return Events.MaskEventRsp.new(obj:MaskEvent(ctx, req:unpack(true)))
    end)
end

---@return Events.GetMaskedEventListRsp
function power_mgmt_client:EventsEventsGetMaskedEventList(ctx, path_params)
    local obj = self:GetEventsEventsObject(path_params)

    return Events.GetMaskedEventListRsp.new(obj:GetMaskedEventList(ctx))
end

function power_mgmt_client:PEventsEventsGetMaskedEventList(ctx, path_params)
    return pcall(function()
        local obj = self:GetEventsEventsObject(path_params)

        return Events.GetMaskedEventListRsp.new(obj:GetMaskedEventList(ctx))
    end)
end

---@param EventInfo Events.KeyValueTable[]
---@return Events.AddEventRsp
function power_mgmt_client:EventsEventsAddEvent(ctx, path_params, EventInfo)
    local req = Events.AddEventReq.new(EventInfo):validate()
    local obj = self:GetEventsEventsObject(path_params)

    return Events.AddEventRsp.new(obj:AddEvent(ctx, req:unpack(true)))
end

function power_mgmt_client:PEventsEventsAddEvent(ctx, path_params, EventInfo)
    return pcall(function()
        local req = Events.AddEventReq.new(EventInfo):validate()
        local obj = self:GetEventsEventsObject(path_params)

        return Events.AddEventRsp.new(obj:AddEvent(ctx, req:unpack(true)))
    end)
end

---@param Path string
---@return Events.ExportEventRsp
function power_mgmt_client:EventsEventsExportEvent(ctx, path_params, Path)
    local req = Events.ExportEventReq.new(Path):validate()
    local obj = self:GetEventsEventsObject(path_params)

    return Events.ExportEventRsp.new(obj:ExportEvent(ctx, req:unpack(true)))
end

function power_mgmt_client:PEventsEventsExportEvent(ctx, path_params, Path)
    return pcall(function()
        local req = Events.ExportEventReq.new(Path):validate()
        local obj = self:GetEventsEventsObject(path_params)

        return Events.ExportEventRsp.new(obj:ExportEvent(ctx, req:unpack(true)))
    end)
end

---@param EventName string[]
---@return Events.CheckEventNameRsp
function power_mgmt_client:EventsEventsCheckEventName(ctx, path_params, EventName)
    local req = Events.CheckEventNameReq.new(EventName):validate()
    local obj = self:GetEventsEventsObject(path_params)

    return Events.CheckEventNameRsp.new(obj:CheckEventName(ctx, req:unpack(true)))
end

function power_mgmt_client:PEventsEventsCheckEventName(ctx, path_params, EventName)
    return pcall(function()
        local req = Events.CheckEventNameReq.new(EventName):validate()
        local obj = self:GetEventsEventsObject(path_params)

        return Events.CheckEventNameRsp.new(obj:CheckEventName(ctx, req:unpack(true)))
    end)
end

---@param AlarmName string
---@return Events.SetAlarmNameRsp
function power_mgmt_client:EventsEventsSetAlarmName(ctx, path_params, AlarmName)
    local req = Events.SetAlarmNameReq.new(AlarmName):validate()
    local obj = self:GetEventsEventsObject(path_params)

    return Events.SetAlarmNameRsp.new(obj:SetAlarmName(ctx, req:unpack(true)))
end

function power_mgmt_client:PEventsEventsSetAlarmName(ctx, path_params, AlarmName)
    return pcall(function()
        local req = Events.SetAlarmNameReq.new(AlarmName):validate()
        local obj = self:GetEventsEventsObject(path_params)

        return Events.SetAlarmNameRsp.new(obj:SetAlarmName(ctx, req:unpack(true)))
    end)
end

---@param EventCode string
---@param Severity integer
---@return Events.SetEventSeverityRsp
function power_mgmt_client:EventsEventsSetEventSeverity(ctx, path_params, EventCode, Severity)
    local req = Events.SetEventSeverityReq.new(EventCode, Severity):validate()
    local obj = self:GetEventsEventsObject(path_params)

    return Events.SetEventSeverityRsp.new(obj:SetEventSeverity(ctx, req:unpack(true)))
end

function power_mgmt_client:PEventsEventsSetEventSeverity(ctx, path_params, EventCode, Severity)
    return pcall(function()
        local req = Events.SetEventSeverityReq.new(EventCode, Severity):validate()
        local obj = self:GetEventsEventsObject(path_params)

        return Events.SetEventSeverityRsp.new(obj:SetEventSeverity(ctx, req:unpack(true)))
    end)
end

---@param EventKeyId string
---@param Action integer
---@return Events.SetEventActionRsp
function power_mgmt_client:EventsEventsSetEventAction(ctx, path_params, EventKeyId, Action)
    local req = Events.SetEventActionReq.new(EventKeyId, Action):validate()
    local obj = self:GetEventsEventsObject(path_params)

    return Events.SetEventActionRsp.new(obj:SetEventAction(ctx, req:unpack(true)))
end

function power_mgmt_client:PEventsEventsSetEventAction(ctx, path_params, EventKeyId, Action)
    return pcall(function()
        local req = Events.SetEventActionReq.new(EventKeyId, Action):validate()
        local obj = self:GetEventsEventsObject(path_params)

        return Events.SetEventActionRsp.new(obj:SetEventAction(ctx, req:unpack(true)))
    end)
end

---@param EventInfo Events.KeyValueTable[]
---@return Events.AddSelRsp
function power_mgmt_client:EventsEventsAddSel(ctx, path_params, EventInfo)
    local req = Events.AddSelReq.new(EventInfo):validate()
    local obj = self:GetEventsEventsObject(path_params)

    return Events.AddSelRsp.new(obj:AddSel(ctx, req:unpack(true)))
end

function power_mgmt_client:PEventsEventsAddSel(ctx, path_params, EventInfo)
    return pcall(function()
        local req = Events.AddSelReq.new(EventInfo):validate()
        local obj = self:GetEventsEventsObject(path_params)

        return Events.AddSelRsp.new(obj:AddSel(ctx, req:unpack(true)))
    end)
end

---@param SrcFile string
---@param DstFile string
---@param Uid integer
---@param Gid integer
---@return File.CopyRsp
function power_mgmt_client:FileFileCopy(ctx, path_params, SrcFile, DstFile, Uid, Gid)
    local req = File.CopyReq.new(SrcFile, DstFile, Uid, Gid):validate()
    local obj = self:GetFileFileObject(path_params)

    return File.CopyRsp.new(obj:Copy(ctx, req:unpack(true)))
end

function power_mgmt_client:PFileFileCopy(ctx, path_params, SrcFile, DstFile, Uid, Gid)
    return pcall(function()
        local req = File.CopyReq.new(SrcFile, DstFile, Uid, Gid):validate()
        local obj = self:GetFileFileObject(path_params)

        return File.CopyRsp.new(obj:Copy(ctx, req:unpack(true)))
    end)
end

---@param SrcFile string
---@param DstFile string
---@param Uid integer
---@param Gid integer
---@return File.MoveRsp
function power_mgmt_client:FileFileMove(ctx, path_params, SrcFile, DstFile, Uid, Gid)
    local req = File.MoveReq.new(SrcFile, DstFile, Uid, Gid):validate()
    local obj = self:GetFileFileObject(path_params)

    return File.MoveRsp.new(obj:Move(ctx, req:unpack(true)))
end

function power_mgmt_client:PFileFileMove(ctx, path_params, SrcFile, DstFile, Uid, Gid)
    return pcall(function()
        local req = File.MoveReq.new(SrcFile, DstFile, Uid, Gid):validate()
        local obj = self:GetFileFileObject(path_params)

        return File.MoveRsp.new(obj:Move(ctx, req:unpack(true)))
    end)
end

---@param DstFile string
---@param FileMode integer
---@return File.ChmodRsp
function power_mgmt_client:FileFileChmod(ctx, path_params, DstFile, FileMode)
    local req = File.ChmodReq.new(DstFile, FileMode):validate()
    local obj = self:GetFileFileObject(path_params)

    return File.ChmodRsp.new(obj:Chmod(ctx, req:unpack(true)))
end

function power_mgmt_client:PFileFileChmod(ctx, path_params, DstFile, FileMode)
    return pcall(function()
        local req = File.ChmodReq.new(DstFile, FileMode):validate()
        local obj = self:GetFileFileObject(path_params)

        return File.ChmodRsp.new(obj:Chmod(ctx, req:unpack(true)))
    end)
end

---@param DstFile string
---@param Uid integer
---@param Gid integer
---@return File.ChownRsp
function power_mgmt_client:FileFileChown(ctx, path_params, DstFile, Uid, Gid)
    local req = File.ChownReq.new(DstFile, Uid, Gid):validate()
    local obj = self:GetFileFileObject(path_params)

    return File.ChownRsp.new(obj:Chown(ctx, req:unpack(true)))
end

function power_mgmt_client:PFileFileChown(ctx, path_params, DstFile, Uid, Gid)
    return pcall(function()
        local req = File.ChownReq.new(DstFile, Uid, Gid):validate()
        local obj = self:GetFileFileObject(path_params)

        return File.ChownRsp.new(obj:Chown(ctx, req:unpack(true)))
    end)
end

---@param DstFile string
---@return File.DeleteRsp
function power_mgmt_client:FileFileDelete(ctx, path_params, DstFile)
    local req = File.DeleteReq.new(DstFile):validate()
    local obj = self:GetFileFileObject(path_params)

    return File.DeleteRsp.new(obj:Delete(ctx, req:unpack(true)))
end

function power_mgmt_client:PFileFileDelete(ctx, path_params, DstFile)
    return pcall(function()
        local req = File.DeleteReq.new(DstFile):validate()
        local obj = self:GetFileFileObject(path_params)

        return File.DeleteRsp.new(obj:Delete(ctx, req:unpack(true)))
    end)
end

---@param DstFile string
---@param OpenMode string
---@param FileMode integer
---@param Uid integer
---@param Gid integer
---@return File.CreateRsp
function power_mgmt_client:FileFileCreate(ctx, path_params, DstFile, OpenMode, FileMode, Uid, Gid)
    local req = File.CreateReq.new(DstFile, OpenMode, FileMode, Uid, Gid):validate()
    local obj = self:GetFileFileObject(path_params)

    return File.CreateRsp.new(obj:Create(ctx, req:unpack(true)))
end

function power_mgmt_client:PFileFileCreate(ctx, path_params, DstFile, OpenMode, FileMode, Uid, Gid)
    return pcall(function()
        local req = File.CreateReq.new(DstFile, OpenMode, FileMode, Uid, Gid):validate()
        local obj = self:GetFileFileObject(path_params)

        return File.CreateRsp.new(obj:Create(ctx, req:unpack(true)))
    end)
end

---@param DstFile string
---@return File.ChangeOwnerRsp
function power_mgmt_client:FileFileChangeOwner(ctx, path_params, DstFile)
    local req = File.ChangeOwnerReq.new(DstFile):validate()
    local obj = self:GetFileFileObject(path_params)

    return File.ChangeOwnerRsp.new(obj:ChangeOwner(ctx, req:unpack(true)))
end

function power_mgmt_client:PFileFileChangeOwner(ctx, path_params, DstFile)
    return pcall(function()
        local req = File.ChangeOwnerReq.new(DstFile):validate()
        local obj = self:GetFileFileObject(path_params)

        return File.ChangeOwnerRsp.new(obj:ChangeOwner(ctx, req:unpack(true)))
    end)
end

---@param DstFile string
---@param Permission string
---@return File.IsPermittedRsp
function power_mgmt_client:FileFileIsPermitted(ctx, path_params, DstFile, Permission)
    local req = File.IsPermittedReq.new(DstFile, Permission):validate()
    local obj = self:GetFileFileObject(path_params)

    return File.IsPermittedRsp.new(obj:IsPermitted(ctx, req:unpack(true)))
end

function power_mgmt_client:PFileFileIsPermitted(ctx, path_params, DstFile, Permission)
    return pcall(function()
        local req = File.IsPermittedReq.new(DstFile, Permission):validate()
        local obj = self:GetFileFileObject(path_params)

        return File.IsPermittedRsp.new(obj:IsPermitted(ctx, req:unpack(true)))
    end)
end

function power_mgmt_client:SubscribeUpdateServiceUpdateServiceUpgradePrepareSignal(cb)
    local sig = match_rule.signal('UpgradePrepareSignal', 'bmc.kepler.UpdateService'):with_path(
        '/bmc/kepler/UpdateService')
    self.signal_slots[#self.signal_slots + 1] = self:get_bus():match(sig, function(msg)
        cb(msg:read())
    end)
end

function power_mgmt_client:SubscribeUpdateServiceUpdateServiceUpgradeProcessSignal(cb)
    local sig = match_rule.signal('UpgradeProcessSignal', 'bmc.kepler.UpdateService'):with_path(
        '/bmc/kepler/UpdateService')
    self.signal_slots[#self.signal_slots + 1] = self:get_bus():match(sig, function(msg)
        cb(msg:read())
    end)
end

function power_mgmt_client:SubscribeUpdateServiceUpdateServiceUpgradeFinishSignal(cb)
    local sig = match_rule.signal('UpgradeFinishSignal', 'bmc.kepler.UpdateService'):with_path(
        '/bmc/kepler/UpdateService')
    self.signal_slots[#self.signal_slots + 1] = self:get_bus():match(sig, function(msg)
        cb(msg:read())
    end)
end

function power_mgmt_client:SubscribeUpdateServiceUpdateServiceRollbackSignal(cb)
    local sig = match_rule.signal('RollbackSignal', 'bmc.kepler.UpdateService'):with_path('/bmc/kepler/UpdateService')
    self.signal_slots[#self.signal_slots + 1] = self:get_bus():match(sig, function(msg)
        cb(msg:read())
    end)
end

function power_mgmt_client:SubscribeUpdateServiceUpdateServiceExportSignal(cb)
    local sig = match_rule.signal('ExportSignal', 'bmc.kepler.UpdateService'):with_path('/bmc/kepler/UpdateService')
    self.signal_slots[#self.signal_slots + 1] = self:get_bus():match(sig, function(msg)
        cb(msg:read())
    end)
end

function power_mgmt_client:SubscribeFruCtrlBeforePowerOnSignal(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 power_mgmt_client:ctor()
    self.signal_slots = {}
end

---@type power_mgmt_client
return power_mgmt_client.new('power_mgmt')
