-- 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 log = require 'mc.logging'
local class = require 'mc.class'

-- class sender : pass command to executor
local class_sender = class()
class_sender.cmd = nil -- abstract class command object

-- initialize value with concrete class object
function class_sender:ctor(bus, path, interface, cmd_strategy)
    log:debug('class sender constructor')
    self.bus = bus
    self.path = path
    self.interface = interface
    self.cmd = cmd_strategy
end

-- set value with concrete class object
function class_sender:set_cmd_policy(cmd_strategy)
    self.cmd = cmd_strategy
end

function class_sender:power_ctrl(system_id, fru_id, ctrl_type, restart_cause)
    log:info('power_ctrl entry')

    if self.cmd == nil then
        error('command strategy is nil')
        return -1
    end

    self.cmd:set_args(self.bus, self.path, self.interface, 'PowerCtrlSignal', 'iiii', system_id, fru_id, ctrl_type,
        restart_cause)

    local ret = self.cmd:send()

    log:info('power_ctrl exit, return %d', ret)
    return ret
end

function class_sender:upgrade_prepare(system_id, firmware_type)
    log:info('upgrade_prepare entry')

    if self.cmd == nil then
        error('command strategy is nil')
        return -1
    end

    self.cmd:set_args(self.bus, self.path, self.interface, 'UpgradePrepareSignal', 'is', system_id, firmware_type)

    local ret = self.cmd:send()

    log:info('upgrade_prepare exit, return %d', ret)
    return ret
end

function class_sender:upgrade_process(system_id, firmware_type, file_path)
    log:info('upgrade_process entry')

    if self.cmd == nil then
        error('command strategy is nil')
        return -1
    end

    self.cmd:set_args(self.bus, self.path, self.interface, 'UpgradeProcessSignal', 'iss',
                      system_id, firmware_type, file_path)

    local ret = self.cmd:send()

    log:info('upgrade_process exit, return %d', ret)
    return ret
end

function class_sender:upgrade_finish(system_id, firmware_type)
    log:info('upgrade_finish entry')

    if self.cmd == nil then
        error('command strategy is nil')
        return -1
    end

    self.cmd:set_args(self.bus, self.path, self.interface, 'UpgradeFinishSignal', 'is',
                      system_id, firmware_type)

    local ret = self.cmd:send()

    log:info('upgrade_finish exit, return %d', ret)
    return ret
end

-- class replier : pass command reply to initiator
local class_replier = class()
class_replier.cmd = nil -- abstract class command object

-- initialize value with concrete class object
function class_replier:ctor(bus, path, interface, cmd_strategy)
    log:debug('class creplier constructor')
    self.bus = bus
    self.path = path
    self.interface = interface
    self.cmd = cmd_strategy
end

-- set value with concrete class object
function class_replier:set_cmd_policy(cmd_strategy)
    self.cmd = cmd_strategy
end

function class_replier:upgrade_prepare_reply(system_id, firmware_type, prepare_result)
    log:info('upgrade_prepare_reply entry')

    if self.cmd == nil then
        error('command strategy is nil')
        return -1
    end

    self.cmd:set_args(self.bus, self.path, self.interface, 'UpgradePrepareReplySignal', 'isi',
                      system_id, firmware_type, prepare_result)

    local ret = self.cmd:send()

    log:info('upgrade_prepare_reply exit, return %d', ret)
    return ret
end

function class_replier:upgrade_process_reply(system_id, firmware_type, process_result)
    log:info('upgrade_process_reply entry')

    if self.cmd == nil then
        error('command strategy is nil')
        return -1
    end

    self.cmd:set_args(self.bus, self.path, self.interface, 'UpgradeProcessReplySignal', 'isi',
                      system_id, firmware_type, process_result)

    local ret = self.cmd:send()

    log:info('upgrade_process_reply exit, return %d', ret)
    return ret
end

function class_replier:upgrade_status_reply(system_id, firmware_type, status, pregess, result_description)
    log:info('upgrade_status_reply entry')

    if self.cmd == nil then
        error('command strategy is nil')
        return -1
    end

    self.cmd:set_args(self.bus, self.path, self.interface, 'UpgradeStatusReplySignal', 'isiis',
                      system_id, firmware_type, status, pregess, result_description)

    local ret = self.cmd:send()

    log:info('upgrade_status_reply exit, return %d', ret)
    return ret
end

function class_replier:upgrade_finish_reply(system_id, firmware_type, finish_result)
    log:info('upgrade_finish_reply entry')

    if self.cmd == nil then
        error('command strategy is nil')
        return -1
    end

    self.cmd:set_args(self.bus, self.path, self.interface, 'UpgradeFinishReplySignal', 'isi',
                      system_id, firmware_type, finish_result)

    local ret = self.cmd:send()

    log:info('upgrade_finish_reply exit, return %d', ret)
    return ret
end

local mrouter = {csender = class_sender, creplier = class_replier}

return mrouter
