-- 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 app_base = require 'mc.client_app_base'
local Class = require 'mc.class'
local error = require 'mc.error'
local safe_call = error.safe_call

local SyssdmMsg = require 'syssdm.types.messages'

---@class SyssdmClient: BasicClient
local SyssdmClient = Class(app_base.BasicClient)

---@param app SDBus | AppBase
---@param SystemId integer
---@param FruId integer
---@param PowerCtrlType SyssdmEnums.PowerCtrlType
---@param RestartCause SyssdmEnums.RestartCause
---@return SyssdmMsg.PowerCtrlRsp
function SyssdmClient:PowerCtrl(app, SystemId, FruId, PowerCtrlType, RestartCause)
    local req = SyssdmMsg.PowerCtrlReq.new(SystemId, FruId, PowerCtrlType, RestartCause):validate()
    return self:__call(SyssdmMsg.PowerCtrlRsp, app, 'PowerCtrl', 'iiii', req:unpack(true))
end

---@param app SDBus | AppBase
---@param SystemId integer
---@param FirmwareType string
---@return SyssdmMsg.UpgradeCtrlRsp
function SyssdmClient:UpgradePrepare(app, SystemId, FirmwareType)
    local req = SyssdmMsg.UpgradePrepareReq.new(SystemId, FirmwareType):validate()
    return self:__call(SyssdmMsg.UpgradeCtrlRsp, app, 'UpgradePrepare', 'is', req:unpack(true))
end

---@param app SDBus | AppBase
---@param SystemId integer
---@param FirmwareType string
---@param PrepareResult integer
---@return SyssdmMsg.UpgradeCtrlRsp
function SyssdmClient:UpgradePrepareReply(app, SystemId, FirmwareType, PrepareResult)
    local req =
        SyssdmMsg.UpgradePrepareReplyReq.new(SystemId, FirmwareType, PrepareResult):validate()
    return
        self:__call(SyssdmMsg.UpgradeCtrlRsp, app, 'UpgradePrepareReply', 'isi', req:unpack(true))
end

---@param app SDBus | AppBase
---@param SystemId integer
---@param FirmwareType string
---@param FirmwarePath string
---@return SyssdmMsg.UpgradeCtrlRsp
function SyssdmClient:UpgradeProcess(app, SystemId, FirmwareType, FirmwarePath)
    local req = SyssdmMsg.UpgradeProcessReq.new(SystemId, FirmwareType, FirmwarePath):validate()
    return self:__call(SyssdmMsg.UpgradeCtrlRsp, app, 'UpgradeProcess', 'iss', req:unpack(true))
end

---@param app SDBus | AppBase
---@param SystemId integer
---@param FirmwareType string
---@param ProcessResult integer
---@return SyssdmMsg.UpgradeCtrlRsp
function SyssdmClient:UpgradeProcessReply(app, SystemId, FirmwareType, ProcessResult)
    local req =
        SyssdmMsg.UpgradeProcessReplyReq.new(SystemId, FirmwareType, ProcessResult):validate()
    return
        self:__call(SyssdmMsg.UpgradeCtrlRsp, app, 'UpgradeProcessReply', 'isi', req:unpack(true))
end

---@param app SDBus | AppBase
---@param SystemId integer
---@param FirmwareType string
---@param Status integer
---@param Progress integer
---@param ResultDescription string
---@return SyssdmMsg.UpgradeCtrlRsp
function SyssdmClient:UpgradeStatusReply(app, SystemId, FirmwareType, Status, Progress,
    ResultDescription)
    local req = SyssdmMsg.UpgradeStatusReplyReq.new(SystemId, FirmwareType, Status, Progress,
        ResultDescription):validate()
    return self:__call(SyssdmMsg.UpgradeCtrlRsp, app, 'UpgradeStatusReply', 'isiis',
        req:unpack(true))
end

---@param app SDBus | AppBase
---@param SystemId integer
---@param FirmwareType string
---@return SyssdmMsg.UpgradeCtrlRsp
function SyssdmClient:UpgradeFinish(app, SystemId, FirmwareType)
    local req = SyssdmMsg.UpgradeFinishReq.new(SystemId, FirmwareType):validate()
    return self:__call(SyssdmMsg.UpgradeCtrlRsp, app, 'UpgradeFinish', 'is', req:unpack(true))
end

---@param app SDBus | AppBase
---@param SystemId integer
---@param FirmwareType string
---@param FinishResult integer
---@return SyssdmMsg.UpgradeCtrlRsp
function SyssdmClient:UpgradeFinishReply(app, SystemId, FirmwareType, FinishResult)
    local req = SyssdmMsg.UpgradeFinishReplyReq.new(SystemId, FirmwareType, FinishResult):validate()
    return self:__call(SyssdmMsg.UpgradeCtrlRsp, app, 'UpgradeFinishReply', 'isi', req:unpack(true))
end

---@class PSyssdmClient: Client
local PSyssdmClient = Class(SyssdmClient)

PSyssdmClient.__call = app_base.BasicClient.__pcall
---@param app SDBus | AppBase
---@param SystemId integer
---@param FruId integer
---@param PowerCtrlType SyssdmEnums.PowerCtrlType
---@param RestartCause SyssdmEnums.RestartCause
---@return Error
---@return SyssdmMsg.PowerCtrlRsp | nil
function PSyssdmClient:PowerCtrl(app, SystemId, FruId, PowerCtrlType, RestartCause)
    local err1, err2, rsp = safe_call(self.super.PowerCtrl, self, app, SystemId, FruId,
        PowerCtrlType, RestartCause)
    if err1 then
        return err1, nil
    else
        return err2, rsp
    end
end

---@param app SDBus | AppBase
---@param SystemId integer
---@param FirmwareType string
---@return Error
---@return SyssdmMsg.UpgradeCtrlRsp | nil
function PSyssdmClient:UpgradePrepare(app, SystemId, FirmwareType)
    local err1, err2, rsp = safe_call(self.super.UpgradePrepare, self, app, SystemId, FirmwareType)
    if err1 then
        return err1, nil
    else
        return err2, rsp
    end
end

---@param app SDBus | AppBase
---@param SystemId integer
---@param FirmwareType string
---@param PrepareResult integer
---@return Error
---@return SyssdmMsg.UpgradeCtrlRsp | nil
function PSyssdmClient:UpgradePrepareReply(app, SystemId, FirmwareType, PrepareResult)
    local err1, err2, rsp = safe_call(self.super.UpgradePrepareReply, self, app, SystemId,
        FirmwareType, PrepareResult)
    if err1 then
        return err1, nil
    else
        return err2, rsp
    end
end

---@param app SDBus | AppBase
---@param SystemId integer
---@param FirmwareType string
---@param FirmwarePath string
---@return Error
---@return SyssdmMsg.UpgradeCtrlRsp | nil
function PSyssdmClient:UpgradeProcess(app, SystemId, FirmwareType, FirmwarePath)
    local err1, err2, rsp = safe_call(self.super.UpgradeProcess, self, app, SystemId, FirmwareType,
        FirmwarePath)
    if err1 then
        return err1, nil
    else
        return err2, rsp
    end
end

---@param app SDBus | AppBase
---@param SystemId integer
---@param FirmwareType string
---@param ProcessResult integer
---@return Error
---@return SyssdmMsg.UpgradeCtrlRsp | nil
function PSyssdmClient:UpgradeProcessReply(app, SystemId, FirmwareType, ProcessResult)
    local err1, err2, rsp = safe_call(self.super.UpgradeProcessReply, self, app, SystemId,
        FirmwareType, ProcessResult)
    if err1 then
        return err1, nil
    else
        return err2, rsp
    end
end

---@param app SDBus | AppBase
---@param SystemId integer
---@param FirmwareType string
---@param Status integer
---@param Progress integer
---@param ResultDescription string
---@return Error
---@return SyssdmMsg.UpgradeCtrlRsp | nil
function PSyssdmClient:UpgradeStatusReply(app, SystemId, FirmwareType, Status, Progress,
    ResultDescription)
    local err1, err2, rsp = safe_call(self.super.UpgradeStatusReply, self, app, SystemId,
        FirmwareType, Status, Progress, ResultDescription)
    if err1 then
        return err1, nil
    else
        return err2, rsp
    end
end

---@param app SDBus | AppBase
---@param SystemId integer
---@param FirmwareType string
---@return Error
---@return SyssdmMsg.UpgradeCtrlRsp | nil
function PSyssdmClient:UpgradeFinish(app, SystemId, FirmwareType)
    local err1, err2, rsp = safe_call(self.super.UpgradeFinish, self, app, SystemId, FirmwareType)
    if err1 then
        return err1, nil
    else
        return err2, rsp
    end
end

---@param app SDBus | AppBase
---@param SystemId integer
---@param FirmwareType string
---@param FinishResult integer
---@return Error
---@return SyssdmMsg.UpgradeCtrlRsp | nil
function PSyssdmClient:UpgradeFinishReply(app, SystemId, FirmwareType, FinishResult)
    local err1, err2, rsp = safe_call(self.super.UpgradeFinishReply, self, app, SystemId,
        FirmwareType, FinishResult)
    if err1 then
        return err1, nil
    else
        return err2, rsp
    end
end

---@type SyssdmClient
local client = SyssdmClient.new('Syssdm')

---@type PSyssdmClient
client.pcall = PSyssdmClient.new('Syssdm')

return client
