-- 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 CipherSuit = require 'iam.json_types.CipherSuit'
local FileTransfer = require 'iam.json_types.FileTransfer'
local Task = require 'iam.json_types.Task'
local Ipv4 = require 'iam.json_types.Ipv4'
local Ipv6 = require 'iam.json_types.Ipv6'
local Events = require 'iam.json_types.Events'
local IpmiCore = require 'iam.json_types.IpmiCore'
local EthernetInterfaces = require 'iam.json_types.EthernetInterfaces'
local Account = require 'iam.json_types.Account'
local CA = require 'iam.json_types.CA'
local Certificate = require 'iam.json_types.Certificate'
local CertificateService = require 'iam.json_types.CertificateService'
local FruCtrl = require 'iam.json_types.FruCtrl'
local ManagerAccounts = require 'iam.json_types.ManagerAccounts'
local ManagerAccount = require 'iam.json_types.ManagerAccount'
local AccountService = require 'iam.json_types.AccountService'
local Role = require 'iam.json_types.Role'
local Rule = require 'iam.json_types.Rule'
local LocalAccountAuthN = require 'iam.json_types.LocalAccountAuthN'
local ConfigManage = require 'iam.json_types.ConfigManage'

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

function iam_client:GetCipherSuitObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.Security.TlsConfig.CipherSuit', true)
end

function iam_client:ForeachCipherSuitObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.Security.TlsConfig.CipherSuit',
        cb, true)
end

function iam_client:GetFileTransferObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.FileTransfer', true)
end

function iam_client:ForeachFileTransferObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.FileTransfer', cb, true)
end

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

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

function iam_client:GetIpv4Objects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.EthernetInterfaces.Ipv4', true)
end

function iam_client:ForeachIpv4Objects(cb)
    return
        foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.EthernetInterfaces.Ipv4', cb, true)
end

function iam_client:GetIpv6Objects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.EthernetInterfaces.Ipv6', true)
end

function iam_client:ForeachIpv6Objects(cb)
    return
        foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.EthernetInterfaces.Ipv6', cb, true)
end

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

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

function iam_client:GetIpmiCoreObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.IpmiCore', true)
end

function iam_client:ForeachIpmiCoreObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.IpmiCore', cb, true)
end

function iam_client:GetEthernetInterfacesObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.EthernetInterfaces', true)
end

function iam_client:ForeachEthernetInterfacesObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.EthernetInterfaces', cb, true)
end

function iam_client:GetAccountObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.CertificateService.Certificate.Account', true)
end

function iam_client:ForeachAccountObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.CertificateService.Certificate.Account',
        cb, true)
end

function iam_client:GetCAObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.CertificateService.CA', true)
end

function iam_client:ForeachCAObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.CertificateService.CA', cb, true)
end

function iam_client:GetCertificateObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.CertificateService.Certificate', true)
end

function iam_client:ForeachCertificateObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.CertificateService.Certificate', cb, true)
end

function iam_client:GetCertificateServiceObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.CertificateService', true)
end

function iam_client:ForeachCertificateServiceObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.CertificateService', cb, true)
end

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

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

function iam_client:GetManagerAccountObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.AccountService.ManagerAccount', true)
end

function iam_client:ForeachManagerAccountObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.AccountService.ManagerAccount', cb, true)
end

function iam_client:GetRoleObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.AccountService.Role', true)
end

function iam_client:ForeachRoleObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.AccountService.Role', cb, true)
end

function iam_client:GetRuleObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.AccountService.Rule', true)
end

function iam_client:ForeachRuleObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.AccountService.Rule', cb, true)
end

function iam_client:GetConfigManageObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.MicroComponent.ConfigManage', true)
end

function iam_client:ForeachConfigManageObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.MicroComponent.ConfigManage', cb, true)
end

function iam_client:OnCipherSuitInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.Security.TlsConfig.CipherSuit')
end

function iam_client:OnCipherSuitInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.Security.TlsConfig.CipherSuit')
end

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

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

function iam_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 iam_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 iam_client:OnIpv4InterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.EthernetInterfaces.Ipv4')
end

function iam_client:OnIpv4InterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.EthernetInterfaces.Ipv4')
end

function iam_client:OnIpv6InterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.EthernetInterfaces.Ipv6')
end

function iam_client:OnIpv6InterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.EthernetInterfaces.Ipv6')
end

function iam_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 iam_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 iam_client:OnIpmiCorePropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.IpmiCore', {'ChannelAccesses'})
end

function iam_client:OnIpmiCoreInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.IpmiCore')
end

function iam_client:OnIpmiCoreInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.IpmiCore')
end

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

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

function iam_client:OnAccountInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.CertificateService.Certificate.Account')
end

function iam_client:OnAccountInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.CertificateService.Certificate.Account')
end

function iam_client:OnCAInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.CertificateService.CA')
end

function iam_client:OnCAInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.CertificateService.CA')
end

function iam_client:OnCertificateInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.CertificateService.Certificate')
end

function iam_client:OnCertificateInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.CertificateService.Certificate')
end

function iam_client:OnCertificateServiceInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.CertificateService')
end

function iam_client:OnCertificateServiceInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.CertificateService')
end

function iam_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', 'SysResetDetected'})
end

function iam_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 iam_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 iam_client:GetManagerAccountsManagerAccountsObject()
    return mdb.try_get_object(self:get_bus(), '/bmc/kepler/AccountService/Accounts',
        'bmc.kepler.AccountService.ManagerAccounts')
end

function iam_client:OnManagerAccountsInterfacesAdded(cb)
    local path_namespace = '/bmc/kepler/AccountService/Accounts'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), path_namespace, cb,
        'bmc.kepler.AccountService.ManagerAccounts')
end

function iam_client:OnManagerAccountsInterfacesRemoved(cb)
    local path_namespace = '/bmc/kepler/AccountService/Accounts'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), path_namespace,
        cb, 'bmc.kepler.AccountService.ManagerAccounts')
end

function iam_client:OnManagerAccountPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.AccountService.ManagerAccount', {
            'UserName', 'RoleId', 'LastLoginIP', 'LastLoginTime', 'Privileges', 'Enabled', 'Locked', 'LoginInterface'
        })
end

function iam_client:OnManagerAccountInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.AccountService.ManagerAccount')
end

function iam_client:OnManagerAccountInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.AccountService.ManagerAccount')
end

function iam_client:GetAccountServiceAccountServiceObject()
    return mdb.try_get_object(self:get_bus(), '/bmc/kepler/AccountService', 'bmc.kepler.AccountService')
end

function iam_client:OnAccountServicePropertiesChanged(cb)
    local path_namespace = '/bmc/kepler/AccountService'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), path_namespace,
        cb, 'bmc.kepler.AccountService', {'HostUserManagementEnabled'})
end

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

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

function iam_client:OnRolePropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.AccountService.Role', {'RolePrivilege'})
end

function iam_client:OnRoleInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.AccountService.Role')
end

function iam_client:OnRoleInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.AccountService.Role')
end

function iam_client:OnRulePropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.AccountService.Rule')
end

function iam_client:OnRuleInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.AccountService.Rule')
end

function iam_client:OnRuleInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.AccountService.Rule')
end

function iam_client:GetLocalAccountAuthNLocalAccountAuthNObject()
    return mdb.try_get_object(self:get_bus(), '/bmc/kepler/AccountService/LocalAccountAuthN',
        'bmc.kepler.AccountService.LocalAccountAuthN')
end

function iam_client:OnLocalAccountAuthNInterfacesAdded(cb)
    local path_namespace = '/bmc/kepler/AccountService/LocalAccountAuthN'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), path_namespace, cb,
        'bmc.kepler.AccountService.LocalAccountAuthN')
end

function iam_client:OnLocalAccountAuthNInterfacesRemoved(cb)
    local path_namespace = '/bmc/kepler/AccountService/LocalAccountAuthN'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), path_namespace,
        cb, 'bmc.kepler.AccountService.LocalAccountAuthN')
end

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

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

---@param AccountId integer
---@param UserName string
---@param Password integer[]
---@param RoleId ManagerAccounts.RoleType
---@param LoginInterface ManagerAccounts.LoginInterfaceType[]
---@param FirstLoginPolicy ManagerAccounts.FirstLoginPolicy
---@return ManagerAccounts.NewRsp
function iam_client:ManagerAccountsManagerAccountsNew(ctx, AccountId, UserName, Password, RoleId, LoginInterface,
    FirstLoginPolicy)
    local req =
        ManagerAccounts.NewReq.new(AccountId, UserName, Password, RoleId, LoginInterface, FirstLoginPolicy):validate()
    local obj = self:GetManagerAccountsManagerAccountsObject()

    return ManagerAccounts.NewRsp.new(obj:New(ctx, req:unpack(true)))
end

function iam_client:PManagerAccountsManagerAccountsNew(ctx, AccountId, UserName, Password, RoleId, LoginInterface,
    FirstLoginPolicy)
    return pcall(function()
        local req =
            ManagerAccounts.NewReq.new(AccountId, UserName, Password, RoleId, LoginInterface, FirstLoginPolicy):validate()
        local obj = self:GetManagerAccountsManagerAccountsObject()

        return ManagerAccounts.NewRsp.new(obj:New(ctx, req:unpack(true)))
    end)
end

---@param AccountId integer
---@param UserName string
---@param Password string
---@param ExtraData ManagerAccounts.ExtraData
---@return ManagerAccounts.NewOEMAccountRsp
function iam_client:ManagerAccountsManagerAccountsNewOEMAccount(ctx, AccountId, UserName, Password, ExtraData)
    local req = ManagerAccounts.NewOEMAccountReq.new(AccountId, UserName, Password, ExtraData):validate()
    local obj = self:GetManagerAccountsManagerAccountsObject()

    return ManagerAccounts.NewOEMAccountRsp.new(obj:NewOEMAccount(ctx, req:unpack(true)))
end

function iam_client:PManagerAccountsManagerAccountsNewOEMAccount(ctx, AccountId, UserName, Password, ExtraData)
    return pcall(function()
        local req = ManagerAccounts.NewOEMAccountReq.new(AccountId, UserName, Password, ExtraData):validate()
        local obj = self:GetManagerAccountsManagerAccountsObject()

        return ManagerAccounts.NewOEMAccountRsp.new(obj:NewOEMAccount(ctx, req:unpack(true)))
    end)
end

---@param UserName string
---@return ManagerAccounts.GetIdByUserNameRsp
function iam_client:ManagerAccountsManagerAccountsGetIdByUserName(ctx, UserName)
    local req = ManagerAccounts.GetIdByUserNameReq.new(UserName):validate()
    local obj = self:GetManagerAccountsManagerAccountsObject()

    return ManagerAccounts.GetIdByUserNameRsp.new(obj:GetIdByUserName(ctx, req:unpack(true)))
end

function iam_client:PManagerAccountsManagerAccountsGetIdByUserName(ctx, UserName)
    return pcall(function()
        local req = ManagerAccounts.GetIdByUserNameReq.new(UserName):validate()
        local obj = self:GetManagerAccountsManagerAccountsObject()

        return ManagerAccounts.GetIdByUserNameRsp.new(obj:GetIdByUserName(ctx, req:unpack(true)))
    end)
end

---@param UserName string
---@return ManagerAccounts.GetUidGidByUserNameRsp
function iam_client:ManagerAccountsManagerAccountsGetUidGidByUserName(ctx, UserName)
    local req = ManagerAccounts.GetUidGidByUserNameReq.new(UserName):validate()
    local obj = self:GetManagerAccountsManagerAccountsObject()

    return ManagerAccounts.GetUidGidByUserNameRsp.new(obj:GetUidGidByUserName(ctx, req:unpack(true)))
end

function iam_client:PManagerAccountsManagerAccountsGetUidGidByUserName(ctx, UserName)
    return pcall(function()
        local req = ManagerAccounts.GetUidGidByUserNameReq.new(UserName):validate()
        local obj = self:GetManagerAccountsManagerAccountsObject()

        return ManagerAccounts.GetUidGidByUserNameRsp.new(obj:GetUidGidByUserName(ctx, req:unpack(true)))
    end)
end

---@param AccountId integer
---@param PropertiesWritable ManagerAccounts.PropertyWritable
---@return ManagerAccounts.SetAccountWritableRsp
function iam_client:ManagerAccountsManagerAccountsSetAccountWritable(ctx, AccountId, PropertiesWritable)
    local req = ManagerAccounts.SetAccountWritableReq.new(AccountId, PropertiesWritable):validate()
    local obj = self:GetManagerAccountsManagerAccountsObject()

    return ManagerAccounts.SetAccountWritableRsp.new(obj:SetAccountWritable(ctx, req:unpack(true)))
end

function iam_client:PManagerAccountsManagerAccountsSetAccountWritable(ctx, AccountId, PropertiesWritable)
    return pcall(function()
        local req = ManagerAccounts.SetAccountWritableReq.new(AccountId, PropertiesWritable):validate()
        local obj = self:GetManagerAccountsManagerAccountsObject()

        return ManagerAccounts.SetAccountWritableRsp.new(obj:SetAccountWritable(ctx, req:unpack(true)))
    end)
end

---@param AccountId integer
---@return ManagerAccounts.GetAccountWritableRsp
function iam_client:ManagerAccountsManagerAccountsGetAccountWritable(ctx, AccountId)
    local req = ManagerAccounts.GetAccountWritableReq.new(AccountId):validate()
    local obj = self:GetManagerAccountsManagerAccountsObject()

    return ManagerAccounts.GetAccountWritableRsp.new(obj:GetAccountWritable(ctx, req:unpack(true)))
end

function iam_client:PManagerAccountsManagerAccountsGetAccountWritable(ctx, AccountId)
    return pcall(function()
        local req = ManagerAccounts.GetAccountWritableReq.new(AccountId):validate()
        local obj = self:GetManagerAccountsManagerAccountsObject()

        return ManagerAccounts.GetAccountWritableRsp.new(obj:GetAccountWritable(ctx, req:unpack(true)))
    end)
end

---@param AccountId integer
---@param Lockstatus boolean
---@return ManagerAccounts.SetAccountLockStateRsp
function iam_client:ManagerAccountsManagerAccountsSetAccountLockState(ctx, AccountId, Lockstatus)
    local req = ManagerAccounts.SetAccountLockStateReq.new(AccountId, Lockstatus):validate()
    local obj = self:GetManagerAccountsManagerAccountsObject()

    return ManagerAccounts.SetAccountLockStateRsp.new(obj:SetAccountLockState(ctx, req:unpack(true)))
end

function iam_client:PManagerAccountsManagerAccountsSetAccountLockState(ctx, AccountId, Lockstatus)
    return pcall(function()
        local req = ManagerAccounts.SetAccountLockStateReq.new(AccountId, Lockstatus):validate()
        local obj = self:GetManagerAccountsManagerAccountsObject()

        return ManagerAccounts.SetAccountLockStateRsp.new(obj:SetAccountLockState(ctx, req:unpack(true)))
    end)
end

---@param Path string
---@return AccountService.ImportWeakPasswordDictionaryRsp
function iam_client:AccountServiceAccountServiceImportWeakPasswordDictionary(ctx, Path)
    local req = AccountService.ImportWeakPasswordDictionaryReq.new(Path):validate()
    local obj = self:GetAccountServiceAccountServiceObject()

    return AccountService.ImportWeakPasswordDictionaryRsp.new(obj:ImportWeakPasswordDictionary(ctx, req:unpack(true)))
end

function iam_client:PAccountServiceAccountServiceImportWeakPasswordDictionary(ctx, Path)
    return pcall(function()
        local req = AccountService.ImportWeakPasswordDictionaryReq.new(Path):validate()
        local obj = self:GetAccountServiceAccountServiceObject()

        return AccountService.ImportWeakPasswordDictionaryRsp.new(
            obj:ImportWeakPasswordDictionary(ctx, req:unpack(true)))
    end)
end

---@param Path string
---@return AccountService.ExportWeakPasswordDictionaryRsp
function iam_client:AccountServiceAccountServiceExportWeakPasswordDictionary(ctx, Path)
    local req = AccountService.ExportWeakPasswordDictionaryReq.new(Path):validate()
    local obj = self:GetAccountServiceAccountServiceObject()

    return AccountService.ExportWeakPasswordDictionaryRsp.new(obj:ExportWeakPasswordDictionary(ctx, req:unpack(true)))
end

function iam_client:PAccountServiceAccountServiceExportWeakPasswordDictionary(ctx, Path)
    return pcall(function()
        local req = AccountService.ExportWeakPasswordDictionaryReq.new(Path):validate()
        local obj = self:GetAccountServiceAccountServiceObject()

        return AccountService.ExportWeakPasswordDictionaryRsp.new(
            obj:ExportWeakPasswordDictionary(ctx, req:unpack(true)))
    end)
end

---@param PublicKeyUsageType integer
---@return AccountService.GetRequestedPublicKeyRsp
function iam_client:AccountServiceAccountServiceGetRequestedPublicKey(ctx, PublicKeyUsageType)
    local req = AccountService.GetRequestedPublicKeyReq.new(PublicKeyUsageType):validate()
    local obj = self:GetAccountServiceAccountServiceObject()

    return AccountService.GetRequestedPublicKeyRsp.new(obj:GetRequestedPublicKey(ctx, req:unpack(true)))
end

function iam_client:PAccountServiceAccountServiceGetRequestedPublicKey(ctx, PublicKeyUsageType)
    return pcall(function()
        local req = AccountService.GetRequestedPublicKeyReq.new(PublicKeyUsageType):validate()
        local obj = self:GetAccountServiceAccountServiceObject()

        return AccountService.GetRequestedPublicKeyRsp.new(obj:GetRequestedPublicKey(ctx, req:unpack(true)))
    end)
end

---@param AccountId integer
---@param Policy integer
---@return AccountService.RecoverAccountRsp
function iam_client:AccountServiceAccountServiceRecoverAccount(ctx, AccountId, Policy)
    local req = AccountService.RecoverAccountReq.new(AccountId, Policy):validate()
    local obj = self:GetAccountServiceAccountServiceObject()

    return AccountService.RecoverAccountRsp.new(obj:RecoverAccount(ctx, req:unpack(true)))
end

function iam_client:PAccountServiceAccountServiceRecoverAccount(ctx, AccountId, Policy)
    return pcall(function()
        local req = AccountService.RecoverAccountReq.new(AccountId, Policy):validate()
        local obj = self:GetAccountServiceAccountServiceObject()

        return AccountService.RecoverAccountRsp.new(obj:RecoverAccount(ctx, req:unpack(true)))
    end)
end

---@param UserName string
---@param Password integer[]
---@param Config LocalAccountAuthN.Config
---@return LocalAccountAuthN.LocalAuthenticateRsp
function iam_client:LocalAccountAuthNLocalAccountAuthNLocalAuthenticate(ctx, UserName, Password, Config)
    local req = LocalAccountAuthN.LocalAuthenticateReq.new(UserName, Password, Config):validate()
    local obj = self:GetLocalAccountAuthNLocalAccountAuthNObject()

    return LocalAccountAuthN.LocalAuthenticateRsp.new(obj:LocalAuthenticate(ctx, req:unpack(true)))
end

function iam_client:PLocalAccountAuthNLocalAccountAuthNLocalAuthenticate(ctx, UserName, Password, Config)
    return pcall(function()
        local req = LocalAccountAuthN.LocalAuthenticateReq.new(UserName, Password, Config):validate()
        local obj = self:GetLocalAccountAuthNLocalAccountAuthNObject()

        return LocalAccountAuthN.LocalAuthenticateRsp.new(obj:LocalAuthenticate(ctx, req:unpack(true)))
    end)
end

---@param CipherText string
---@param AuthChallenge string
---@return LocalAccountAuthN.VncAuthenticateRsp
function iam_client:LocalAccountAuthNLocalAccountAuthNVncAuthenticate(ctx, CipherText, AuthChallenge)
    local req = LocalAccountAuthN.VncAuthenticateReq.new(CipherText, AuthChallenge):validate()
    local obj = self:GetLocalAccountAuthNLocalAccountAuthNObject()

    return LocalAccountAuthN.VncAuthenticateRsp.new(obj:VncAuthenticate(ctx, req:unpack(true)))
end

function iam_client:PLocalAccountAuthNLocalAccountAuthNVncAuthenticate(ctx, CipherText, AuthChallenge)
    return pcall(function()
        local req = LocalAccountAuthN.VncAuthenticateReq.new(CipherText, AuthChallenge):validate()
        local obj = self:GetLocalAccountAuthNLocalAccountAuthNObject()

        return LocalAccountAuthN.VncAuthenticateRsp.new(obj:VncAuthenticate(ctx, req:unpack(true)))
    end)
end

---@param AuthAlgo integer
---@param UserName string
---@param ConsoleSid integer
---@param ManagedSid integer
---@param ConsoleRandom integer[]
---@param ManagedRandom integer[]
---@param ManagedGuid integer[]
---@param Role integer
---@param Ip string
---@return LocalAccountAuthN.GenRmcp20CodeRsp
function iam_client:LocalAccountAuthNLocalAccountAuthNGenRmcp20Code(ctx, AuthAlgo, UserName, ConsoleSid, ManagedSid,
    ConsoleRandom, ManagedRandom, ManagedGuid, Role, Ip)
    local req = LocalAccountAuthN.GenRmcp20CodeReq.new(AuthAlgo, UserName, ConsoleSid, ManagedSid, ConsoleRandom,
        ManagedRandom, ManagedGuid, Role, Ip):validate()
    local obj = self:GetLocalAccountAuthNLocalAccountAuthNObject()

    return LocalAccountAuthN.GenRmcp20CodeRsp.new(obj:GenRmcp20Code(ctx, req:unpack(true)))
end

function iam_client:PLocalAccountAuthNLocalAccountAuthNGenRmcp20Code(ctx, AuthAlgo, UserName, ConsoleSid, ManagedSid,
    ConsoleRandom, ManagedRandom, ManagedGuid, Role, Ip)
    return pcall(function()
        local req = LocalAccountAuthN.GenRmcp20CodeReq.new(AuthAlgo, UserName, ConsoleSid, ManagedSid, ConsoleRandom,
            ManagedRandom, ManagedGuid, Role, Ip):validate()
        local obj = self:GetLocalAccountAuthNLocalAccountAuthNObject()

        return LocalAccountAuthN.GenRmcp20CodeRsp.new(obj:GenRmcp20Code(ctx, req:unpack(true)))
    end)
end

---@param AuthAlgo integer
---@param PayLoad integer[]
---@param AccountId integer
---@param SessionId integer
---@param SessionSequence integer
---@return LocalAccountAuthN.GenRmcp15CodeRsp
function iam_client:LocalAccountAuthNLocalAccountAuthNGenRmcp15Code(ctx, AuthAlgo, PayLoad, AccountId, SessionId,
    SessionSequence)
    local req =
        LocalAccountAuthN.GenRmcp15CodeReq.new(AuthAlgo, PayLoad, AccountId, SessionId, SessionSequence):validate()
    local obj = self:GetLocalAccountAuthNLocalAccountAuthNObject()

    return LocalAccountAuthN.GenRmcp15CodeRsp.new(obj:GenRmcp15Code(ctx, req:unpack(true)))
end

function iam_client:PLocalAccountAuthNLocalAccountAuthNGenRmcp15Code(ctx, AuthAlgo, PayLoad, AccountId, SessionId,
    SessionSequence)
    return pcall(function()
        local req =
            LocalAccountAuthN.GenRmcp15CodeReq.new(AuthAlgo, PayLoad, AccountId, SessionId, SessionSequence):validate()
        local obj = self:GetLocalAccountAuthNLocalAccountAuthNObject()

        return LocalAccountAuthN.GenRmcp15CodeRsp.new(obj:GenRmcp15Code(ctx, req:unpack(true)))
    end)
end

function iam_client:SubscribeIpv4ChangedSignal(cb)
    local sig = match_rule.signal('ChangedSignal', 'bmc.kepler.Managers.EthernetInterfaces.Ipv4')
    self.signal_slots[#self.signal_slots + 1] = self:get_bus():match(sig, function(msg)
        cb(msg:read())
    end)
end

function iam_client:SubscribeIpv6ChangedSignal(cb)
    local sig = match_rule.signal('ChangedSignal', 'bmc.kepler.Managers.EthernetInterfaces.Ipv6')
    self.signal_slots[#self.signal_slots + 1] = self:get_bus():match(sig, function(msg)
        cb(msg:read())
    end)
end

function iam_client:SubscribeEthernetInterfacesActivePortChangedSignal(cb)
    local sig = match_rule.signal('ActivePortChangedSignal', 'bmc.kepler.Managers.EthernetInterfaces')
    self.signal_slots[#self.signal_slots + 1] = self:get_bus():match(sig, function(msg)
        cb(msg:read())
    end)
end

function iam_client:SubscribeEthernetInterfacesNCSIInfoChangedSignal(cb)
    local sig = match_rule.signal('NCSIInfoChangedSignal', 'bmc.kepler.Managers.EthernetInterfaces')
    self.signal_slots[#self.signal_slots + 1] = self:get_bus():match(sig, function(msg)
        cb(msg:read())
    end)
end

function iam_client:SubscribeEthernetInterfacesEthMacChangedSignal(cb)
    local sig = match_rule.signal('EthMacChangedSignal', 'bmc.kepler.Managers.EthernetInterfaces')
    self.signal_slots[#self.signal_slots + 1] = self:get_bus():match(sig, function(msg)
        cb(msg:read())
    end)
end

function iam_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 iam_client:SubscribeManagerAccountsManagerAccountsPasswordChangedSignal(cb)
    local sig = match_rule.signal('PasswordChangedSignal', 'bmc.kepler.AccountService.ManagerAccounts'):with_path(
        '/bmc/kepler/AccountService/Accounts')
    self.signal_slots[#self.signal_slots + 1] = self:get_bus():match(sig, function(msg)
        cb(msg:read())
    end)
end

function iam_client:SubscribeManagerAccountsManagerAccountsSnmpPasswordChangedSignal(cb)
    local sig = match_rule.signal('SnmpPasswordChangedSignal', 'bmc.kepler.AccountService.ManagerAccounts'):with_path(
        '/bmc/kepler/AccountService/Accounts')
    self.signal_slots[#self.signal_slots + 1] = self:get_bus():match(sig, function(msg)
        cb(msg:read())
    end)
end

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

---@type iam_client
return iam_client.new('iam')
