-- Copyright (c) 2026 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 skynet = require 'skynet'

TestSoftwareEventMgmt = {}

function TestSoftwareEventMgmt:test_generate_tc_conn_csr_failure_event()
    local CONNECTOR_INTF <const> = 'bmc.kepler.Connector'
    local DEFAULT_SMBIOS_PATH <const> = '/bmc/kepler/Systems/1/SmBios'
    local CSR_FAILURE_EVENT_COMPONENT <const> = 'BMC'
    local is_alarm = false
    local values = {
        SmBiosStatus = true
    }
    local mock_obj_not3 = {path = DEFAULT_SMBIOS_PATH, SmBiosStatus = 0}
    local mock_obj_is3 = {path = DEFAULT_SMBIOS_PATH, SmBiosStatus = 3}
    local mock_client = {
        OnSmBiosPropertiesChanged = function(_, func)
            func(values, DEFAULT_SMBIOS_PATH, nil)
        end,
        OnSmBiosInterfacesAdded = function(_, func)
            func(nil, DEFAULT_SMBIOS_PATH, mock_obj_not3)
        end,
        ForeachSmBiosObjects = function(_, func)
            func(mock_obj_is3)
        end,
        OnConnectorPropertiesChanged = function(_, func)
            func(CONNECTOR_INTF, DEFAULT_SMBIOS_PATH, CONNECTOR_INTF)
        end,
        GetSmBiosObjects = function()
            return {
                [DEFAULT_SMBIOS_PATH] = mock_obj_is3
            }
        end
    }

    local mock_event = {
        get_latest_alarm_list = function()
            return {
                {
                    ComponentName = CSR_FAILURE_EVENT_COMPONENT,
                    EventCode = 1,
                    EventName = "Event",
                    MessageArgs = "Message"
                }
            }
        end
    }

    local mock_cmn = {
        generate_event = function()
            is_alarm = true
            return true
        end,
        skynet = {
            sleep = function()
            end
        }
    }

    skynet.fork_once = function (func)
        func()
    end

    local back_mock_client = package.loaded['pcie_device.client']
    local back_mock_event = package.loaded['infrastructure.event']
    local back_mock_cmn = package.loaded['common']
    package.loaded['pcie_device.client'] = mock_client
    package.loaded['infrastructure.event'] = mock_event
    package.loaded['common'] = mock_cmn
    package.loaded['software_event_mgmt'] = nil

    local c_software_event_mgmt = require 'software_event_mgmt'

    local mock_conn_pair_list = {
        Conn1 = {
            tc_conn = {Presence = 1, LoadStatus = 1, Type = "UBInterface", Slot = 1},
            conn = {Presence = 0},
            pai = { Location = "RiserCard1" }
        }
    }

    c_software_event_mgmt:ctor()
    c_software_event_mgmt.conn_pair_list = mock_conn_pair_list
    c_software_event_mgmt:init()
    c_software_event_mgmt:update_conn_tc_csr_failure_event({Presence = 1, LoadStatus = 1, Type = "UBInterface", Slot = 1},
        {Presence = 0}, { Location = "RiserCard1" })
    mock_client.OnConnectorPropertiesChanged = function(_, func)

        func(CONNECTOR_INTF, DEFAULT_SMBIOS_PATH, CONNECTOR_INTF)
    end
    c_software_event_mgmt:update_conn_tc_csr_failure_event({Presence = 1, LoadStatus = 1, Type = "UBInterface", Slot = 1, path = DEFAULT_SMBIOS_PATH},
        {Presence = 0}, { Location = "RiserCard1" })

    c_software_event_mgmt.get_alarm_list_matched(nil, "FatalName", nil, nil, nil)
    c_software_event_mgmt.get_alarm_list_matched(nil, CSR_FAILURE_EVENT_COMPONENT, "Event", nil, nil)
    c_software_event_mgmt.get_alarm_list_matched(nil, CSR_FAILURE_EVENT_COMPONENT, "Event", 1, true)
    c_software_event_mgmt.get_alarm_list_matched(nil, CSR_FAILURE_EVENT_COMPONENT, "Event", 1, "Message")
    mock_event.get_latest_alarm_list = function()
        error("", 1)
    end
    c_software_event_mgmt.get_alarm_list_matched(nil, CSR_FAILURE_EVENT_COMPONENT, "Event", 1, "Message")
    c_software_event_mgmt.parse_tc_csr_failure_args(nil, nil)
    c_software_event_mgmt:generate_tc_conn_csr_failure_event(nil, {}, {})
    c_software_event_mgmt:generate_tc_conn_csr_failure_event(false, {}, {})
    lu.assertEquals(is_alarm, true)

    local back_mock_cjson = package.loaded['cjson']
    local mock_cjson = {encode = function()
        return "Message"
    end}
    package.loaded['cjson'] = mock_cjson
    package.loaded['software_event_mgmt'] = nil

    c_software_event_mgmt = require 'software_event_mgmt'
    c_software_event_mgmt:generate_tc_conn_csr_failure_event(false, {}, {Location = "RiserCard1"})

    mock_cmn.generate_event = function()
        error("", 1)
    end
    c_software_event_mgmt:generate_tc_conn_csr_failure_event(false, {}, {Location = "RiserCard1"})

    package.loaded['pcie_device.client'] = back_mock_client
    package.loaded['infrastructure.event'] = back_mock_event
    package.loaded['common'] = back_mock_cmn
    package.loaded['cjson'] = back_mock_cjson
end

function TestSoftwareEventMgmt:test_business_add_mgmt()
    local back_mock_class_mgmt = package.loaded['mc.class_mgnt']
    local back_mock_software_event_mgmt = package.loaded['software_event_mgmt']
    local mock_conn_pair_list = {}
    local mock_class_mgmt = function()
        return {
            [1] = "pcie_addr_info"
        }
    end
    local mock_software_event_mgmt = {
        get_instance = function()
            return {
                conn_pair_list = mock_conn_pair_list,
                update_event_task_list = {
                    tc_connector_csr_failure = function()
                    end
                }
            }
        end
    }
    package.loaded['mc.class_mgnt'] = mock_class_mgmt
    package.loaded['software_event_mgmt'] = mock_software_event_mgmt
    package.loaded['biz_topo.class.business_connector'] = nil

    local c_business_connector = require 'biz_topo.class.business_connector'
    local signal_func
    local mock_signal = {
        on = function(_, func)
            signal_func = func
        end
    }
    c_business_connector:ctor({RefPCIeAddrInfo = 1, ObjectName = "obj"}, "0101", mock_signal)
    c_business_connector.ref_mgmt_connector_tianchi = {
        Type = 'UBInterfaceCard'
    }
    signal_func("0101")
    lu.assertEquals(mock_conn_pair_list.ref_addr_info_obj, nil)
    package.loaded['mc.class_mgnt'] = back_mock_class_mgmt
    package.loaded['software_event_mgmt'] = back_mock_software_event_mgmt
end