-- 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 om_event_handler = require "infrastructure.om_event_handler"
local debounce = require 'mc.debounce.debounce'
local c_object_manage = require 'mc.orm.object_manage'
local event = require 'infrastructure.event'
local debounce = require 'mc.debounce.debounce'
local npu_om_obj = require 'event.debounce_config.npu_om'

TEST_om_event_handler = {}

local npu_om = {
    Events = {
        Event_OpticalModule1Die0HostInterfaceFault = {
            EventKeyId = "Port.PortOpticalModuleHostInterfaceFault",
            EventCode = '0x29000019',
            -- 告警主体类型，默认0x29。可不配置。
            SubjectType = 0x29,
            -- 相关的属性，用来打印定位。可不配置。
            prop_names = {"HostInterfaceFaultStatus"},
            -- 防抖类型，默认持续防抖。可不配置。
            type = debounce.DEBOUNCED_CONT,
            -- 防抖次数，默认15次。可不配置。
            cont_num = 15,
            -- 是否符合告警触发条件
            trigger_fun = function(om_obj)
                if om_obj.HostInterfaceFaultStatus == 65535 then
                    return false
                end
                return om_obj.HostInterfaceFaultStatus >= 1
            end,
            -- 告警参数
            get_args = function(om_obj)
                return table.pack("Name", "NpuId")
            end,
            -- 在同Component同EventCode下区分告警事件的若干个参数索引。可不配置。
            identify_arg_index = {}
        },

        Event_OpticalModule1Die0SelfTestFault = {
            EventKeyId = "Port.PortOpticalModuleSelfTestFault",
            EventCode = '0x2900001D',
            prop_names = {"SelfTestStatus"},
            trigger_fun = function(om_obj)
                return om_obj.SelfTestStatus >= 1
            end,
            get_args = function(om_obj)
                return table.pack("Name1", "NpuId1")
            end
        }
    }
}

om_event_handler_mock = {}

local function mock_get_instance()
    return {
        bus = {}
    }
end

function TEST_om_event_handler:test_update_om_event_1()
    om_event_handler_mock.scan_raw_value = function()

    end
    om_event_handler_mock.update_latest_alarm_list = function(...)
        return true
    end
    om_event_handler_mock.generate_om_event = function(...)
        return true
    end
    om_event_handler_mock.debounce_event_list['key'] = 1
    om_event_handler_mock.cur_event_list = {}

    om_event_handler.update_om_event(om_event_handler_mock)
end

function TEST_om_event_handler:test_update_om_event()
    om_event_handler_mock.scan_raw_value = function()

    end
    om_event_handler_mock.update_latest_alarm_list = function(...)
        return true
    end
    om_event_handler_mock.generate_om_event = function(...)
        return true
    end
    om_event_handler_mock.debounce_event_list['key'] = 0
    om_event_handler_mock.cur_event_list['key'] = 1

    om_event_handler.update_om_event(om_event_handler_mock)
end

function TEST_om_event_handler:test_generate_om_event()
    om_event_handler_mock.args_fun_map['key'] = function(...)
        return
    end
    om_event_handler.generate_om_event(om_event_handler_mock, 'key', true)
end

function TEST_om_event_handler:test_print_params()
    om_event_handler_mock.prop_names_map = {
        ['key'] = {'value'},
        ['key1'] = {'value'}
    }
    om_event_handler.print_params(om_event_handler_mock, 'key', 'value')
end

function TEST_om_event_handler:test_init_debounce_value()
    om_event_handler.init_debounce_value(om_event_handler_mock)
end

function TEST_om_event_handler:test_update_latest_alarm_list_2()
    local instance = c_object_manage.get_instance
    c_object_manage.get_instance = mock_get_instance
    om_event_handler.update_latest_alarm_list(om_event_handler_mock)
    c_object_manage.get_instance = instance
end

function TEST_om_event_handler:test_update_latest_alarm_list_1()
    local instance = c_object_manage.get_instance
    c_object_manage.get_instance = mock_get_instance
    om_event_handler_mock.component_name = 'Name'
    alarm1 = {
        ['ComponentName'] = 'Name',
        ['MessageArgs'] = ''
    }
    local get_latest_alarm_list = event.get_latest_alarm_list
    event.get_latest_alarm_list = function(...)
        return {alarm1}
    end
    om_event_handler.update_latest_alarm_list(om_event_handler_mock)

    alarm1 = {
        ['ComponentName'] = 'Name',
        ['MessageArgs'] = '{"aa": "aaa"}'
    }

    om_event_handler.update_latest_alarm_list(om_event_handler_mock)

    alarm1 = {
        ['ComponentName'] = 'Name',
        ['MessageArgs'] = '{"aa": "aaa"}',
        ['EventCode'] = "02303213"
    }
    om_event_handler.update_latest_alarm_list(om_event_handler_mock)
    c_object_manage.get_instance = instance
    event.get_latest_alarm_list = get_latest_alarm_list
end

function TEST_om_event_handler:test_update_latest_alarm_list()
    local instance = c_object_manage.get_instance
    c_object_manage.get_instance = mock_get_instance
    alarm1 = {
        ['ComponentName'] = 'Name'
    }
    local get_latest_alarm_list = event.get_latest_alarm_list
    event.get_latest_alarm_list = function(...)
        return {alarm1}
    end
    om_event_handler.update_latest_alarm_list(om_event_handler_mock)
    event.get_latest_alarm_list = get_latest_alarm_list
    c_object_manage.get_instance = instance
end

function TEST_om_event_handler:test_parse_debounce_config()
    om_event_handler.parse_debounce_config(om_event_handler_mock)
end

function TEST_om_event_handler:test_init()
    om_event_handler_mock.update_latest_alarm_list = function()
    end
    om_event_handler_mock.init_debounce_value = function()
    end
    om_event_handler_mock.parse_debounce_config = function()
    end
    om_event_handler.init(om_event_handler_mock)
end

function TEST_om_event_handler:test_ctor()
    local obj = {
        PortID = 1,
        get_parent = function()
            return {
                PortID = 1,
                get_parent = function()
                    return {
                        Model = 'NPU'
                    }
                end
            }
        end
    }
    om_event_handler.ctor(om_event_handler_mock, obj, npu_om)
end

-- 测试Hi1825模型的ctor（覆盖om_event_handler.lua lines 41-42）
function TEST_om_event_handler:test_ctor_hi1825()
    local hi1825_mock = {}
    local obj = {
        ObjectName = "OpticalModule1",
        get_parent = function()
            return {
                PortID = 0,
                get_parent = function()
                    return {
                        Model = 'Hi1825'
                    }
                end
            }
        end
    }
    om_event_handler.ctor(hi1825_mock, obj, npu_om)
    lu.assertEquals(hi1825_mock.component_name, "Port1")
    lu.assertEquals(hi1825_mock.component_node_id, "Hi1825BoardOptical_moduleOpticalModule1")
end

function TEST_om_event_handler:test_npu_om_obj()
    local om_obj = {}
    om_obj.get_parent = function()
        return {LinkStatus = 'Disconnected'}
    end

    local trigger_fun_1 = npu_om_obj.Events.Event_OpticalModule1Die0LossOfLock.trigger_fun
    trigger_fun_1(om_obj)
    trigger_fun_1 = npu_om_obj.Events.Event_OpticalModule1Die0_1_RxPowerAlarm.trigger_fun
    trigger_fun_1(om_obj)
    trigger_fun_1 = npu_om_obj.Events.Event_OpticalModule1Die0_2_RxPowerAlarm.trigger_fun
    trigger_fun_1(om_obj)
    trigger_fun_1 = npu_om_obj.Events.Event_OpticalModule1Die0_3_RxPowerAlarm.trigger_fun
    trigger_fun_1(om_obj)
    trigger_fun_1 = npu_om_obj.Events.Event_OpticalModule1Die0_4_RxPowerAlarm.trigger_fun
    trigger_fun_1(om_obj)
    trigger_fun_1 = npu_om_obj.Events.Event_OpticalModule1Die0_5_RxPowerAlarm.trigger_fun
    trigger_fun_1(om_obj)
    trigger_fun_1 = npu_om_obj.Events.Event_OpticalModule1Die0_6_RxPowerAlarm.trigger_fun
    trigger_fun_1(om_obj)
    trigger_fun_1 = npu_om_obj.Events.Event_OpticalModule1Die0_7_RxPowerAlarm.trigger_fun
    trigger_fun_1(om_obj)
    trigger_fun_1 = npu_om_obj.Events.Event_OpticalModule1Die0_8_RxPowerAlarm.trigger_fun
    trigger_fun_1(om_obj)
end

function TEST_om_event_handler:test_get_port_info()
    local op_obj = {
        get_parent = function()
            return {
                NpuID = 1
            }
        end,
        cache_related_port_info = {'NPUBoard1-1 Port1', 'NPUBoard5-1 Port6'},
        SilkText = 'PIC-8 ETH2'
    }
    local str = npu_om_obj.mock_get_port_info(op_obj)
    lu.assertEquals(str, ' NPU1(NPUBoard1-1 Port1/NPUBoard5-1 Port6 PIC-8 ETH2)')
end
