-- Copyright (c) 2025 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 lu = require 'luaunit'
local bios_factory = require 'factory.bios_factory'
local bios_fw_signal = require 'interface.signal'
local client = require 'bios.client'
local bios_service = require 'service.bios_service'
local krun_service = require'service.krun_service'
local upgrade_service = require 'service.upgrade_service'
local skynet = require 'skynet'
local upgrade_state_machine = require 'service.upgrade_state_machine'

TestSignal = {}

function TestSignal:test_not_support_parallel_upgrade()
    local get_service = bios_factory.get_service
    bios_factory.get_service = function ()
        return {
            dft_mode = true
        }
    end
    local ctx = {}
    local system_id = 1
    local firmware_type = 'Bios'
    local cfg_path = ''
    local hpm_path = ''
    local parameters = {
        UpgradeMode = 'Parallel'
    }
    local UpdateServiceUpdateServicePrepareReply = client.UpdateServiceUpdateServicePrepareReply
    client.UpdateServiceUpdateServicePrepareReply = function ()
        return true
    end
    local ok = bios_fw_signal.upgrade_prepare_callback(ctx, system_id, firmware_type, cfg_path, hpm_path, parameters)
    lu.assertEquals(ok, nil)
    bios_factory.get_service = get_service
    bios_factory.UpdateServiceUpdateServicePrepareReply = UpdateServiceUpdateServicePrepareReply
end

function TestSignal:test_check_same_version()
    local lu_obj = {}
    local PUpdateServiceUpdateServicePrepareReply = client.PUpdateServiceUpdateServicePrepareReply
    client.PUpdateServiceUpdateServicePrepareReply = function(_,
        ctx, system_id, firmware_type, version, status, parameters)
        lu_obj.firmware_type = firmware_type
        lu_obj.version = version
        lu_obj.status = status
    end

    local cfg = {
        firmware_type = 'Bios',
        system_id = 255
    }
    local parameters = {
        ForceUpdate = 'false',
        Version = '1.23'
    }
    local bios_ser = bios_service.get_instance()
    local bios_object_collection = bios_ser.bios_object_collection
    bios_ser.bios_object_collection = {
        {
            get_prop = function ()
                return '1.23'
            end
        }
    }
    local get_service = bios_factory.get_service
    bios_factory.get_service = function ()
        return bios_ser
    end
    bios_fw_signal.prepare_upgrade(cfg, parameters)
    lu.assertEquals(lu_obj.status, 71)

    local state_machine = upgrade_state_machine.get_instance()
    local pre_state = state_machine.state['bios']
    state_machine.state['bios'] = 'PROCESS_START'
    bios_fw_signal.prepare_upgrade(cfg, parameters)
    lu.assertEquals(lu_obj.status, 36)
    state_machine.state['bios'] = pre_state

    local krun_ser = krun_service.get_instance()
    local krun_flash_collection = krun_ser.krun_flash_collection
    krun_ser.krun_flash_collection = {
        {
            get_prop = function ()
                return '1.23'
            end
        }
    }
    bios_factory.get_service = function ()
        return krun_ser
    end
    cfg = {
        firmware_type = 'Krun',
        system_id = 255
    }
    bios_fw_signal.prepare_upgrade(cfg, parameters)
    lu.assertEquals(lu_obj.status, 71)

    client.PUpdateServiceUpdateServicePrepareReply = PUpdateServiceUpdateServicePrepareReply
    bios_ser.bios_object_collection = bios_object_collection
    krun_ser.krun_flash_collection = krun_flash_collection
    bios_factory.get_service = get_service
end

function TestSignal:test_activate_bios_fw_callback()
    local values = {
        ['SysResetDetected'] = {
            value = function() return 1 end,
            _flag = true
        }
    }
    bios_fw_signal.check_boot_guard_running = {}
    local interface = 'bmc.kepler.Systems.FruCtrl'
    local path = '/bmc/kepler/Systems/1/FruCtrl'

    upgrade_service.get_instance().get_cached_bios_upgrade_mode = function ()
        return 0x01
    end

    bios_fw_signal.init_status = function(system_id)
        return
    end

    bios_fw_signal.is_multihost = function(system_id)
        return false
    end
    local fork_once = skynet.fork_once
    skynet.fork_once = function(cb, ...)
        cb(...)
    end

    local get_service = bios_factory.get_service

    local obj = {
        get_prop = function(status)
            return 1
        end
    }
    local service = {
        get_smbios_obj = function(status)
            return obj
        end
    }
    bios_factory.get_service = function(str)
        return service
    end
    bios_fw_signal.activate_bios_fw_callback(values, path, interface)
    bios_factory.get_service = get_service
    skynet.fork_once = fork_once
end

function TestSignal:test_activate_bios_fw_callback_special_scene()
    local values = {
        ['SysResetDetected'] = {
            value = function() return 1 end,
            _flag = true
        }
    }
    bios_fw_signal.check_boot_guard_running = {}
    local interface = 'bmc.kepler.Systems.FruCtrl'
    local path = '/bmc/kepler/Systems/1/FruCtrl'

    upgrade_service.get_instance().get_cached_bios_upgrade_mode = function ()
        return 0x01
    end

    bios_fw_signal.init_status = function(system_id)
        return
    end

    bios_fw_signal.is_multihost = function(system_id)
        return false
    end
    local fork_once = skynet.fork_once
    skynet.fork_once = function(cb, ...)
        bios_fw_signal.check_boot_guard_running[1] = true
        cb(...)
    end
    bios_fw_signal.activate_bios_fw_callback(values, path, interface)
    skynet.fork_once = fork_once
end