-- 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 lu = require 'luaunit'
local defs = require 'unit_manager.class.logic_fw.comm_defs'
local valid = require 'unit_manager.class.logic_fw.upgrade.valid'
local utils = require 'mc.utils'
local vos = require 'utils.vos'
local skynet = require 'skynet'
local utils_core = require 'utils.core'
local client = require 'general_hardware.client'
local fructl = require 'mcu.upgrade.fructl_handler'
local drivers = require 'unit_manager.class.logic_fw.upgrade.drivers_api'
local factory = require 'factory'

TestValid = {}

function TestValid:setupClass()
    original_skynet_sleep = skynet.sleep
    original_get_file_accessible = vos.get_file_accessible
    original_remove = utils.remove_file
    original_dir = utils_core.dir
    original_mkdir_with_parents = utils.mkdir_with_parents
    original_ForeachSmBiosObjects = client.ForeachSmBiosObjects
    original_is_multihost_type = fructl.is_multihost_type
    original_get_chassis_power_status = fructl.get_chassis_power_status
    original_get_power_status = fructl.get_power_status
    original_get_cpld_device_info = drivers.get_cpld_device_info
    original_set_upg_cpld_chip = drivers.set_upg_cpld_chip
    original_get_obj = factory.get_obj

    -- 公共函数打桩

    skynet.sleep = function()
    end

    vos.get_file_accessible = function(file_path)
        return true
    end

    utils.remove_file = function()
        return true
    end

    utils.mkdir_with_parents = function()
        return true
    end

    client.ForeachSmBiosObjects = function()
        return {SmBiosStatus = 3}
    end

    utils_core.dir = function()
        return {"bypass_2_2_2.svf", "valid_1_1_1.svf"}
    end

    fructl.is_multihost_type = function()
        return false
    end

    fructl.get_chassis_power_status = function()
        return 'OFF'
    end

    fructl.get_power_status = function()
        return 'OFF'
    end

    drivers.get_cpld_device_info = function()
        return
    end

    drivers.set_upg_cpld_chip = function()
        return
    end

    factory.get_obj = function()
        return {
            get_board_obj_by_position = function()
                return {}
            end}
    end
end

function TestValid:teardownClass()
    -- 恢复公共函数打桩
    if original_skynet_sleep then
        skynet.sleep = original_skynet_sleep
    end

    -- 恢复 vos 相关函数
    if original_get_file_accessible then
        vos.get_file_accessible = original_get_file_accessible
    end

    if original_remove then
        utils.remove_file = original_remove
    end
    
    if original_mkdir_with_parents then
        utils.mkdir_with_parents = original_mkdir_with_parents
    end

    if original_ForeachSmBiosObjects then
        client.ForeachSmBiosObjects = original_ForeachSmBiosObjects
    end

    if original_is_multihost_type then
        fructl.is_multihost_type = original_is_multihost_type
    end

    if original_get_chassis_power_status then
        fructl.get_chassis_power_status = original_get_chassis_power_status
    end

    if original_get_power_status then
        fructl.get_power_status = original_get_power_status
    end

    if original_dir then
        utils_core.dir = original_dir
    end

    if original_get_cpld_device_info then
        drivers.get_cpld_device_info = original_get_cpld_device_info
    end

    if original_set_upg_cpld_chip then
        drivers.set_upg_cpld_chip = original_set_upg_cpld_chip
    end

    if original_get_obj then
        factory.get_obj = original_get_obj
    end
end

function TestValid:test_cpld_hot_valid()
    valid.get_valid_file_list = function()
        return {
            {uid = 1, chip_index = 1, system_id = 1}
        }
    end
    local signal = {
        db = {
            CpldValidating = function()
                return {
                    ValidatingCpldFlag = 1
                }
            end
        },
        fw_list = {
            {
                name = 'CPLD',
                csr = {
                    Name = "CPLD",
                    VaildBeforeAction = 0,
                    VaildBeforeActionStatus = 1
                },
                chip_info = {
                    SetBypassMode = function(self, ctx, enable)
                        return true
                    end,
                    GetBypassMode = function(self, ctx)
                        return enable
                    end
                },
                system_id = 1,
                uid = 1,
                switch_to_firmware_route = function()
                    return
                end,
                switch_to_default_route = function()
                    return
                end
            }
        },
        bus = {}
    }
    vos.get_file_accessible = function(file_path)
        return false
    end
    valid:init_valid_file(signal.fw_list[1], 1, "1", 1)
    valid:init_bypass_file(signal.fw_list[1], 1, "1", 1)
    vos.get_file_accessible = function(file_path)
        return true
    end
    valid:init_bypass_file(signal.fw_list[1], 1, "1", 1)
    valid.cpld_hot_valid(1, signal, false)
    valid.cpld_hot_valid(1, signal, true)

    signal = {
        db = {
            CpldValidating = function()
                return {
                    ValidatingCpldFlag = 1
                }
            end
        },
        fw_list = {
            {
                name = 'CPLD',
                csr = {
                    Name = "CPLD",
                    VaildBeforeAction = 0,
                    VaildBeforeActionStatus = 1
                },
                chip_info = {
                    SetBypassMode = function(self, ctx, enable)
                        return true
                    end,
                    GetBypassMode = function(self, ctx)
                        return enable
                    end
                },
                system_id = 1
            }
        },
        bus = {}
    }
    valid:init_bypass_file(signal.fw_list[1], 1, "1", 1)

    signal = {
        db = {
            CpldValidating = function()
                return {
                    ValidatingCpldFlag = 1
                }
            end
        },
        fw_list = {
            {
                name = 'CPLD',
                csr = {
                    Name = "FPGA",
                    VaildBeforeActionStatus = 1
                },
                chip_info = {
                    SetBypassMode = function(self, ctx, enable)
                        return true
                    end,
                    GetBypassMode = function(self, ctx)
                        return enable
                    end
                },
                system_id = 1,
                uid = 1,
                switch_to_firmware_route = function()
                    return
                end,
                switch_to_default_route = function()
                    return
                end
            }
        },
        bus = {}
    }
    valid:init_bypass_file(signal.fw_list[1], 1, "1", 1)
    valid.cpld_hot_valid(1, signal, true)

    signal = {
        db = {
            CpldValidating = function()
                return {
                    ValidatingCpldFlag = 1
                }
            end
        },
        fw_list = {
            {
                name = 'CPLD',
                csr = {
                    Name = "CPLD",
                    VaildBeforeAction = 0,
                    VaildBeforeActionStatus = 0
                },
                chip_info = {
                    SetBypassMode = function(self, ctx, enable)
                        return true
                    end,
                    GetBypassMode = function(self, ctx)
                        return enable
                    end
                },
                system_id = 1,
                uid = 1,
                switch_to_firmware_route = function()
                    return
                end,
                switch_to_default_route = function()
                    return
                end
            }
        },
        bus = {}
    }
    fructl.is_multihost_type = function()
        return true
    end
    fructl.get_chassis_power_status = function()
        return 'ON'
    end
    valid.cpld_hot_valid(1, signal, true)
    lu.assertEquals(signal.fw_list[1].csr.VaildBeforeAction, 1)
    fructl.is_multihost_type = function()
        return false
    end
    valid.cpld_hot_valid(1, signal, true)

    lu.assertEquals(signal.fw_list[1].csr.VaildBeforeAction, 1)
end
