-- 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.service_app_base'
local Class = require 'mc.class'

local SyssdmMsg = require 'syssdm.types.messages'

local persist_client = require 'persistence.persist_client_lib'
local open_db = require 'syssdm.db'
local datas = require 'syssdm.datas'

local SyssdmService = Class(app_base.Service)

SyssdmService.package = 'Syssdm'

function SyssdmService:ctor()
    if not self.name then
        self.name = SyssdmService.package
    end
    self.db = open_db(':memory:', datas)
    self.bus:request_name(app_base.Service.get_service_name(self.name))
end

function SyssdmService:pre_init()
    if SyssdmService.super.pre_init then
        SyssdmService.super.pre_init(self)
    end
    self.persist = persist_client.new(self.bus, self.db, self)
end

function SyssdmService:init()
    self:register_interface('PowerCtrl', 'iiii', 'i', self.__on_power_ctrl, SyssdmMsg.PowerCtrlRsp)
    self:register_interface('UpgradePrepare', 'is', 'i', self.__on_upgrade_prepare,
        SyssdmMsg.UpgradeCtrlRsp)
    self:register_interface('UpgradePrepareReply', 'isi', 'i', self.__on_upgrade_prepare_reply,
        SyssdmMsg.UpgradeCtrlRsp)
    self:register_interface('UpgradeProcess', 'iss', 'i', self.__on_upgrade_process,
        SyssdmMsg.UpgradeCtrlRsp)
    self:register_interface('UpgradeProcessReply', 'isi', 'i', self.__on_upgrade_process_reply,
        SyssdmMsg.UpgradeCtrlRsp)
    self:register_interface('UpgradeStatusReply', 'isiis', 'i', self.__on_upgrade_status_reply,
        SyssdmMsg.UpgradeCtrlRsp)
    self:register_interface('UpgradeFinish', 'is', 'i', self.__on_upgrade_finish,
        SyssdmMsg.UpgradeCtrlRsp)
    self:register_interface('UpgradeFinishReply', 'isi', 'i', self.__on_upgrade_finish_reply,
        SyssdmMsg.UpgradeCtrlRsp)
    SyssdmService.super.init(self)
end

function SyssdmService:__on_power_ctrl(SystemId, FruId, PowerCtrlType, RestartCause)
    local req = SyssdmMsg.PowerCtrlReq.new(SystemId, FruId, PowerCtrlType, RestartCause):validate()
    return self:PowerCtrl(req:unpack())
end

---@param SystemId integer
---@param FruId integer
---@param PowerCtrlType SyssdmEnums.PowerCtrlType
---@param RestartCause SyssdmEnums.RestartCause
function SyssdmService:PowerCtrl(SystemId, FruId, PowerCtrlType, RestartCause)
    self:raise_interface_not_impl('PowerCtrl')
end

function SyssdmService:__on_upgrade_prepare(SystemId, FirmwareType)
    local req = SyssdmMsg.UpgradePrepareReq.new(SystemId, FirmwareType):validate()
    return self:UpgradePrepare(req:unpack())
end

---@param SystemId integer
---@param FirmwareType string
function SyssdmService:UpgradePrepare(SystemId, FirmwareType)
    self:raise_interface_not_impl('UpgradePrepare')
end

function SyssdmService:__on_upgrade_prepare_reply(SystemId, FirmwareType, PrepareResult)
    local req =
        SyssdmMsg.UpgradePrepareReplyReq.new(SystemId, FirmwareType, PrepareResult):validate()
    return self:UpgradePrepareReply(req:unpack())
end

---@param SystemId integer
---@param FirmwareType string
---@param PrepareResult integer
function SyssdmService:UpgradePrepareReply(SystemId, FirmwareType, PrepareResult)
    self:raise_interface_not_impl('UpgradePrepareReply')
end

function SyssdmService:__on_upgrade_process(SystemId, FirmwareType, FirmwarePath)
    local req = SyssdmMsg.UpgradeProcessReq.new(SystemId, FirmwareType, FirmwarePath):validate()
    return self:UpgradeProcess(req:unpack())
end

---@param SystemId integer
---@param FirmwareType string
---@param FirmwarePath string
function SyssdmService:UpgradeProcess(SystemId, FirmwareType, FirmwarePath)
    self:raise_interface_not_impl('UpgradeProcess')
end

function SyssdmService:__on_upgrade_process_reply(SystemId, FirmwareType, ProcessResult)
    local req =
        SyssdmMsg.UpgradeProcessReplyReq.new(SystemId, FirmwareType, ProcessResult):validate()
    return self:UpgradeProcessReply(req:unpack())
end

---@param SystemId integer
---@param FirmwareType string
---@param ProcessResult integer
function SyssdmService:UpgradeProcessReply(SystemId, FirmwareType, ProcessResult)
    self:raise_interface_not_impl('UpgradeProcessReply')
end

function SyssdmService:__on_upgrade_status_reply(SystemId, FirmwareType, Status, Progress,
    ResultDescription)
    local req = SyssdmMsg.UpgradeStatusReplyReq.new(SystemId, FirmwareType, Status, Progress,
        ResultDescription):validate()
    return self:UpgradeStatusReply(req:unpack())
end

---@param SystemId integer
---@param FirmwareType string
---@param Status integer
---@param Progress integer
---@param ResultDescription string
function SyssdmService:UpgradeStatusReply(SystemId, FirmwareType, Status, Progress,
    ResultDescription)
    self:raise_interface_not_impl('UpgradeStatusReply')
end

function SyssdmService:__on_upgrade_finish(SystemId, FirmwareType)
    local req = SyssdmMsg.UpgradeFinishReq.new(SystemId, FirmwareType):validate()
    return self:UpgradeFinish(req:unpack())
end

---@param SystemId integer
---@param FirmwareType string
function SyssdmService:UpgradeFinish(SystemId, FirmwareType)
    self:raise_interface_not_impl('UpgradeFinish')
end

function SyssdmService:__on_upgrade_finish_reply(SystemId, FirmwareType, FinishResult)
    local req = SyssdmMsg.UpgradeFinishReplyReq.new(SystemId, FirmwareType, FinishResult):validate()
    return self:UpgradeFinishReply(req:unpack())
end

---@param SystemId integer
---@param FirmwareType string
---@param FinishResult integer
function SyssdmService:UpgradeFinishReply(SystemId, FirmwareType, FinishResult)
    self:raise_interface_not_impl('UpgradeFinishReply')
end

return SyssdmService
