-- 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 bs = require 'mc.bitstring'
local ncsi_protocol_intf = require 'ncsi_protocol_intf'
local ncsi_utils = require 'ncsi.ncsi_protocol.ncsi_utils'
local ncsi_def = require 'ncsi.ncsi_protocol.ncsi_def'
local ncsi_oem_command = require 'ncsi.ncsi_protocol.ncsi_oem_command'
local ncsi_cmd = require 'ncsi.ncsi_protocol.ncsi_cmd'
local core = require 'network.core'
local ncsi_mac = require 'ncsi.ncsi_protocol.ncsi_mac'
local ncsi_vlan_mode = require 'ncsi.ncsi_protocol.ncsi_vlan_mode'
local ncsi_parameter = require 'ncsi.ncsi_protocol.ncsi_parameter'

-- 测试套件
TestNCSIOemCommand = {}

-- 命令类型常量定义
local OEM_COMMAND = 0x50
local OEM_COMMAND_RSP = 0xD0
local GET_LOG_CMD_ID = 0x00
local GET_LOG_SUB_CMD = 0x15
local GET_LOG_SUB_CMD_NEW = 0x16
local GET_LLDP_OVER_NCSI_STATUS = 0x0B
local GET_NETCARD_TEMP_SUB_CMD = 0x0A
local GET_HW_OEM_CMD_CAP_SUB_CMD = 0x11
local GET_FACTORY_DEFAULT_MAC_SUB_CMD = 0x04
local MANUFACTURE_ID_HUAWEI = 0x000007DB
local GET_LLDP_OVER_NCSI_CMD_ID = 0x04
local GET_NETCARD_TEMP_CMD_ID = 0x00
local GET_CONTROLLER_INFO_CMD_ID = 0x00
local GET_FACTORY_DEFAULT_MAC_CMD_ID = 0x01

local get_lldp_over_ncsi_rsp_bs = bs.new([[<<
    rsp_code:16,
    reason_code:16,
    manufacture_id:32,
    cmd_rev:8,
    cmd_id:8,
    sub_cmd:8,
    reserved:8,
    status:8,
    reserved1:3/string,
    check_sum:32
>>]])

local get_netcard_temp_rsp_bs = bs.new([[<<
    rsp_code:16,
    reason_code:16,
    manufacture_id:32,
    cmd_rev:8,
    cmd_id:8,
    sub_cmd:8,
    reserved:8,
    temp:16,
    reserved1:16,
    check_sum:32
>>]])

local get_hw_oem_cmd_cap_rsp_bs = bs.new([[<<
    rsp_code:16,
    reason_code:16,
    manufacture_id:32,
    cmd_rev:8,
    cmd_id:8,
    sub_cmd:8,
    reserved:8,
    capability:32,
    reserved1:52/string,
    check_sum:32
>>]])

local get_factory_default_mac_rsp_bs = bs.new([[<<
    rsp_code:16,
    reason_code:16,
    manufacture_id:32,
    cmd_rev:8,
    cmd_id:8,
    sub_cmd:8,
    reserved:8,
    mac_count:8,
    reserved1:3/string,
    mac_addr:48/string,
    check_sum:32
>>]])

local get_log_over_ncsi_rsp_bs = bs.new([[<<
    rsp_code:16,
    reason_code:16,
    manufacture_id:32,
    cmd_rev:8,
    cmd_id:8,
    sub_cmd:8,
    reserved:8,
    data:1024/string,
    check_sum:32
>>]])

local get_log_over_ncsi_rsp_control_bs = bs.new([[<<
    rsp_code:16,
    reason_code:16,
    manufacture_id:32,
    cmd_rev:8,
    cmd_id:8,
    sub_cmd:8,
    reserved:8,
    total_len:32,
    sub_log_num:8,
    reserved1:8,
    data:514/string
>>]])

local get_log_over_ncsi_rsp_data_bs = bs.new([[<<
    rsp_code:16,
    reason_code:16,
    manufacture_id:32,
    cmd_rev:8,
    cmd_id:8,
    sub_cmd:8,
    reserved:8,
    last_frame:8,
    reserved1:3/string,
    data:2056/string
>>]])

-- Mock函数
local function mock_htonl(value)
    return value
end

local function mock_ntohl(value)
    return value
end

-- 模拟发送NCSI命令的函数
local function mock_send_ncsi_cmd(req_data, len, eth_name)
    TestNCSIOemCommand.last_req_data = req_data
    TestNCSIOemCommand.last_len = len
    TestNCSIOemCommand.last_eth_name = eth_name
    return ncsi_def.NCSI_SUCCESS
end

-- 初始化函数，在每个测试用例前执行
function TestNCSIOemCommand:setUp()
    ncsi_parameter.get_instance():init_ncsi_parameter()
    -- 保存原始函数
    self.original_send_ncsi_cmd = ncsi_protocol_intf.send_ncsi_cmd
    self.original_cmd_ctrl = ncsi_utils.ncsi_cmd_ctrl
    self.original_get_ncsi_parameter = ncsi_parameter.get_instance().get_ncsi_parameter
    self.original_htonl = core.htonl
    self.original_ntohl = core.ntohl

    -- 使用模拟函数替换原始函数
    ncsi_protocol_intf.send_ncsi_cmd = mock_send_ncsi_cmd
    core.htonl = mock_htonl
    core.ntohl = mock_ntohl

    -- 初始化测试变量
    self.last_req_data = nil
    self.last_len = nil
    self.last_eth_name = nil

    -- 模拟NCSI参数
    self.mock_ncsi_parameter = {
        current_channel = 0,
        iid = 1,  -- 添加iid字段，这是NCSI协议需要的包ID
        channel_cap = {
            [0] = {
                [0] = {
                    vlan_mode = 0x02,
                    mul_filter_cnt = 16,
                    mix_filter_cnt = 16
                }
            }
        }
    }
    ncsi_parameter.get_instance().get_ncsi_parameter = function() 
        return self.mock_ncsi_parameter
    end

    -- 模拟cmd_ctrl函数以便测试
    ncsi_utils.ncsi_cmd_ctrl = function(_, _, req_packet, eth_name, cmd_process_table)
        -- 确保cmd_process_table存在
        assert(cmd_process_table, "cmd_process_table is nil")

        -- 调用请求处理函数
        if req_packet and req_packet.packet_head and req_packet.packet_head.packet_type and
           cmd_process_table[req_packet.packet_head.packet_type] then
            cmd_process_table[req_packet.packet_head.packet_type](req_packet, eth_name)
        end

        -- 返回成功
        return ncsi_def.NCSI_SUCCESS
    end
end

-- 清理函数，在每个测试用例后执行
function TestNCSIOemCommand:tearDown()
    -- 恢复原始函数
    ncsi_protocol_intf.send_ncsi_cmd = self.original_send_ncsi_cmd
    ncsi_utils.ncsi_cmd_ctrl = self.original_cmd_ctrl
    ncsi_parameter.get_instance().get_ncsi_parameter = self.original_get_ncsi_parameter
    core.htonl = self.original_htonl
    core.ntohl = self.original_ntohl
end

-- 测试获取日志功能
function TestNCSIOemCommand:test_get_specific_type_log()
    -- 测试参数
    local package_id = 0
    local eth_name = "eth0"
    local log_type = 1
    local total_frame = 2
    local base_offset = 0

    -- 执行测试
    local result = ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
        package_id, eth_name, log_type, total_frame, base_offset)

    -- 验证结果
    lu.assertEquals(result, ncsi_def.NCSI_SUCCESS)
    lu.assertNotNil(self.last_req_data)
    lu.assertEquals(self.last_eth_name, eth_name)

    -- 验证请求报文格式
    local parsed_packet = ncsi_utils.ncsi_packet_bs:unpack(self.last_req_data, true)
    lu.assertNotNil(parsed_packet.packet_head)
    lu.assertEquals(parsed_packet.packet_head.packet_type, OEM_COMMAND)
    lu.assertEquals(parsed_packet.packet_head.channel_id, 0)
    lu.assertEquals(parsed_packet.packet_head.package_id, package_id)
end

-- 测试响应处理
function TestNCSIOemCommand:test_response_processing()
    -- 模拟响应包
    local function create_mock_response(rsp_code, reason_code, manufacture_id, cmd_id, sub_cmd)
        local rsp = {packet_head = {}, payload = ''}
        rsp.packet_head.payload_len_hi = 0
        rsp.packet_head.payload_len_lo = 16
        rsp.packet_head.packet_type = OEM_COMMAND_RSP

        -- 创建响应payload
        local rsp_data = get_log_over_ncsi_rsp_bs:pack({
            rsp_code = rsp_code,
            reason_code= reason_code,
            manufacture_id= manufacture_id,
            cmd_rev = 0,
            cmd_id = cmd_id,
            sub_cmd = sub_cmd,
            reserved = 1,
            data = string.rep('\0', 1024),
            check_sum = 0
        })

        rsp.payload = rsp_data
        return rsp
    end

    -- 测试参数
    local package_id = 0
    local eth_name = "eth0"
    local log_type = 1
    local total_frame = 1
    local base_offset = 0

    -- 测试成功响应
    local success_rsp = create_mock_response(
        ncsi_def.CMD_COMPLETED, 0, MANUFACTURE_ID_HUAWEI, GET_LOG_CMD_ID, GET_LOG_SUB_CMD)
    
    local original_cmd_ctrl = ncsi_utils.ncsi_cmd_ctrl
    ncsi_utils.ncsi_cmd_ctrl = function(_, _, _, _, cmd_process_table)
        return cmd_process_table[OEM_COMMAND_RSP](success_rsp)
    end

    local result = ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
        package_id, eth_name, log_type, total_frame, base_offset)
    lu.assertEquals(result, ncsi_def.NCSI_SUCCESS)

    -- 测试失败响应
    local fail_rsp = create_mock_response(0x0123, 1, MANUFACTURE_ID_HUAWEI, GET_LOG_CMD_ID, GET_LOG_SUB_CMD)
    
    ncsi_utils.ncsi_cmd_ctrl = function(_, _, _, _, cmd_process_table)
        return cmd_process_table[OEM_COMMAND_RSP](fail_rsp)
    end

    result = ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
        package_id, eth_name, log_type, total_frame, base_offset)
    lu.assertEquals(result, ncsi_def.NCSI_FAIL)

    -- 恢复原始函数
    ncsi_utils.ncsi_cmd_ctrl = original_cmd_ctrl
end

-- 测试错误处理
function TestNCSIOemCommand:test_error_handling()
    -- 测试参数
    local package_id = 0
    local eth_name = "eth0"
    local log_type = 1
    local total_frame = 1
    local base_offset = 0

    -- 保存原始函数
    local original_cmd_ctrl = ncsi_utils.ncsi_cmd_ctrl

    -- 测试命令控制函数返回失败
    ncsi_utils.ncsi_cmd_ctrl = function(_, _, _, _, _)
        return ncsi_def.NCSI_FAIL
    end

    local result = ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
        package_id, eth_name, log_type, total_frame, base_offset)
    lu.assertEquals(result, ncsi_def.NCSI_FAIL)

    -- 测试无效响应包
    ncsi_utils.ncsi_cmd_ctrl = function(_, _, _, _, cmd_process_table)
        return cmd_process_table[OEM_COMMAND_RSP](nil)
    end

    result = ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
        package_id, eth_name, log_type, total_frame, base_offset)
    lu.assertEquals(result, ncsi_def.NCSI_FAIL)

    -- 测试无效厂商ID
    local invalid_manufacture_rsp = {
        packet_head = {
            payload_len_hi = 0,
            payload_len_lo = 16,
            channel_id = 0
        },
        payload = get_log_over_ncsi_rsp_bs:pack({
            rsp_code = ncsi_def.CMD_COMPLETED,
            reason_code = 0,
            manufacture_id = 0x12345678,  -- 无效的厂商ID
            cmd_rev = 0,
            cmd_id = GET_LOG_CMD_ID,
            sub_cmd = GET_LOG_SUB_CMD,
            reserved = 0,
            data = string.rep('\0', 1024),
            check_sum = 0
        })
    }

    ncsi_utils.ncsi_cmd_ctrl = function(_, _, _, _, cmd_process_table)
        return cmd_process_table[OEM_COMMAND_RSP](invalid_manufacture_rsp)
    end

    result = ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
        package_id, eth_name, log_type, total_frame, base_offset)
    lu.assertEquals(result, ncsi_def.NCSI_SUCCESS)

    -- 恢复原始函数
    ncsi_utils.ncsi_cmd_ctrl = original_cmd_ctrl
end

-- 测试日志处理相关函数
function TestNCSIOemCommand:test_log_processing_functions()
    -- 测试参数
    local package_id = 0
    local eth_name = "eth0"
    local log_type = 1
    local total_frame = 2
    local base_offset = 0

    -- 保存原始函数
    local original_cmd_ctrl = ncsi_utils.ncsi_cmd_ctrl

    -- 模拟文件操作
    local mock_file = {
        write = function(self, data)
            return true
        end,
        close = function(self)
            return true
        end
    }
    local original_io_open = io.open
    io.open = function(filename, mode)
        return mock_file
    end

    -- 测试控制帧处理
    local g_log_context = ncsi_oem_command.get_log_context()
    g_log_context.is_control_frame = 1
    g_log_context.sub_log_idx = 0
    g_log_context.sub_log_lens = {1, 1}
    local control_frame_rsp = {
        packet_head = {
            payload_len_hi = 0,
            payload_len_lo = 16,
            channel_id = 0
        },
        payload = get_log_over_ncsi_rsp_control_bs:pack({
            rsp_code = ncsi_def.CMD_COMPLETED,
            reason_code = 0,
            manufacture_id = MANUFACTURE_ID_HUAWEI,
            cmd_rev = 0,
            cmd_id = GET_LOG_CMD_ID,
            sub_cmd = GET_LOG_SUB_CMD_NEW,
            reserved = 0,
            total_len = 2048,
            sub_log_num = 2,
            reserved1 = 0,
            data = string.pack(">I2I2", 1, 1)  -- 两个子日志长度
        })
    }

    ncsi_utils.ncsi_cmd_ctrl = function(_, _, _, _, cmd_process_table)
        return cmd_process_table[OEM_COMMAND_RSP](control_frame_rsp)
    end
    ncsi_oem_command.parse_control_frame(control_frame_rsp)

    -- 测试数据帧处理
    g_log_context.is_control_frame = 0
    local data_frame_rsp = {
        packet_head = {
            payload_len_hi = 0,
            payload_len_lo = 16,
            channel_id = 0
        },
        payload = get_log_over_ncsi_rsp_data_bs:pack({
            rsp_code = ncsi_def.CMD_COMPLETED,
            reason_code = 0,
            manufacture_id = MANUFACTURE_ID_HUAWEI,
            cmd_rev = 0,
            cmd_id = GET_LOG_CMD_ID,
            sub_cmd = GET_LOG_SUB_CMD_NEW,
            reserved = 0,
            last_frame = 1,
            reserved1 = string.rep('/0', 3),
            data = string.rep('A', 1024)
        })
    }

    ncsi_utils.ncsi_cmd_ctrl = function(_, _, _, _, cmd_process_table)
        return cmd_process_table[OEM_COMMAND_RSP](data_frame_rsp)
    end

    local result = ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
        package_id, eth_name, log_type, total_frame, base_offset)
    lu.assertEquals(result, ncsi_def.NCSI_SUCCESS)

    -- 测试文件操作错误
    mock_file.write = function(self, data)
        return false, "Write error"
    end

    result = ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
        package_id, eth_name, log_type, total_frame, base_offset)
    lu.assertEquals(result, ncsi_def.NCSI_SUCCESS)

    -- 测试文件打开失败
    io.open = function(filename, mode)
        return nil
    end

    result = ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
        package_id, eth_name, log_type, total_frame, base_offset)
    lu.assertEquals(result, ncsi_def.NCSI_SUCCESS)

    -- 恢复原始函数
    ncsi_utils.ncsi_cmd_ctrl = original_cmd_ctrl
    io.open = original_io_open
end

-- 测试日志缓冲区处理
function TestNCSIOemCommand:test_log_buffer_handling()
    -- 测试参数
    local package_id = 0
    local eth_name = "eth0"
    local log_type = 1
    local total_frame = 2
    local base_offset = 0

    -- 保存原始函数
    local original_cmd_ctrl = ncsi_utils.ncsi_cmd_ctrl

    -- 模拟文件操作
    local mock_file = {
        write = function(self, data)
            return true
        end,
        close = function(self)
            return true
        end
    }
    local original_io_open = io.open
    io.open = function(filename, mode)
        return mock_file
    end

    -- 测试缓冲区满的情况
    local large_data_rsp = {
        packet_head = {
            payload_len_hi = 0,
            payload_len_lo = 16,
            channel_id = 0
        },
        payload = get_log_over_ncsi_rsp_data_bs:pack({
            rsp_code = ncsi_def.CMD_COMPLETED,
            reason_code = 0,
            manufacture_id = MANUFACTURE_ID_HUAWEI,
            cmd_rev = 0,
            cmd_id = GET_LOG_CMD_ID,
            sub_cmd = GET_LOG_SUB_CMD_NEW,
            reserved = 0,
            last_frame = 0,
            reserved1 = string.rep('/0', 3),
            data = string.rep('A', 2056)
        })
    }

    ncsi_utils.ncsi_cmd_ctrl = function(_, _, _, _, cmd_process_table)
        return cmd_process_table[OEM_COMMAND_RSP](large_data_rsp)
    end

    -- 发送多个数据包以填满缓冲区
    for i = 1, 65 do  -- MAX_BUFFER_LEN = 64 * 1024, 每个包1024字节
        local result = ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
            package_id, eth_name, log_type, total_frame, base_offset)
        lu.assertEquals(result, ncsi_def.NCSI_SUCCESS)
    end

    -- 测试eth_num
    ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
        package_id, 'eth16', log_type, total_frame, base_offset)
    ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
        package_id, 'eth', log_type, total_frame, base_offset)
    ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
        package_id, '', log_type, total_frame, base_offset)
    ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
        package_id, 'invalid', log_type, total_frame, base_offset)

    -- 恢复原始函数
    ncsi_utils.ncsi_cmd_ctrl = original_cmd_ctrl
    io.open = original_io_open
end


-- 测试OEM命令响应
function TestNCSIOemCommand:test_oem_command_responses()
    -- 测试参数
    local package_id = 0
    local eth_name = "eth0"

    -- 保存原始函数
    local original_cmd_ctrl = ncsi_utils.ncsi_cmd_ctrl

    -- 测试LLDP over NCSI状态响应
    local lldp_rsp = {
        packet_head = {
            payload_len_hi = 0,
            payload_len_lo = 16,
            channel_id = 0
        },
        payload = get_lldp_over_ncsi_rsp_bs:pack({
            rsp_code = ncsi_def.CMD_COMPLETED,
            reason_code = 0,
            manufacture_id = MANUFACTURE_ID_HUAWEI,
            cmd_rev = 0,
            cmd_id = GET_LLDP_OVER_NCSI_CMD_ID,
            sub_cmd = GET_LLDP_OVER_NCSI_STATUS,
            reserved = 0,
            status = 1,
            reserved1 = string.rep('\0', 3),
            check_sum = 0
        })
    }

    ncsi_utils.ncsi_cmd_ctrl = function(_, _, _, _, cmd_process_table)
        return cmd_process_table[OEM_COMMAND_RSP](lldp_rsp)
    end

    local result = ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
        package_id, eth_name, 1, 2, 0)
    lu.assertEquals(result, ncsi_def.NCSI_SUCCESS)

    -- 测试网卡温度响应
    local temp_rsp = {
        packet_head = {
            payload_len_hi = 0,
            payload_len_lo = 16,
            channel_id = 0
        },
        payload = get_netcard_temp_rsp_bs:pack({
            rsp_code = ncsi_def.CMD_COMPLETED,
            reason_code = 0,
            manufacture_id = MANUFACTURE_ID_HUAWEI,
            cmd_rev = 0,
            cmd_id = GET_NETCARD_TEMP_CMD_ID,
            sub_cmd = GET_NETCARD_TEMP_SUB_CMD,
            reserved = 0,
            temp = 0x1234,  -- 温度值
            reserved1 = 0,
            check_sum = 0
        })
    }

    ncsi_utils.ncsi_cmd_ctrl = function(_, _, _, _, cmd_process_table)
        return cmd_process_table[OEM_COMMAND_RSP](temp_rsp)
    end

    result = ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
        package_id, eth_name, 1, 2, 0)
    lu.assertEquals(result, ncsi_def.NCSI_SUCCESS)

    -- 测试OEM命令能力响应
    local cap_rsp = {
        packet_head = {
            payload_len_hi = 0,
            payload_len_lo = 16,
            channel_id = 0
        },
        payload = get_hw_oem_cmd_cap_rsp_bs:pack({
            rsp_code = ncsi_def.CMD_COMPLETED,
            reason_code = 0,
            manufacture_id = MANUFACTURE_ID_HUAWEI,
            cmd_rev = 0,
            cmd_id = GET_CONTROLLER_INFO_CMD_ID,
            sub_cmd = GET_HW_OEM_CMD_CAP_SUB_CMD,
            reserved = 0,
            capability = 0x0F,  -- 所有能力位都设置为1
            reserved1 = string.rep('\0', 52),
            check_sum = 0
        })
    }

    ncsi_utils.ncsi_cmd_ctrl = function(_, _, _, _, cmd_process_table)
        return cmd_process_table[OEM_COMMAND_RSP](cap_rsp)
    end

    result = ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
        package_id, eth_name, 1, 2, 0)
    lu.assertEquals(result, ncsi_def.NCSI_SUCCESS)

    -- 测试出厂默认MAC响应
    local mac_rsp = {
        packet_head = {
            payload_len_hi = 0,
            payload_len_lo = 16,
            channel_id = 0
        },
        payload = get_factory_default_mac_rsp_bs:pack({
            rsp_code = ncsi_def.CMD_COMPLETED,
            reason_code = 0,
            manufacture_id = MANUFACTURE_ID_HUAWEI,
            cmd_rev = 0,
            cmd_id = GET_FACTORY_DEFAULT_MAC_CMD_ID,
            sub_cmd = GET_FACTORY_DEFAULT_MAC_SUB_CMD,
            reserved = 0,
            mac_count = 1,
            reserved1 = string.rep('\0', 3),
            mac_addr = string.rep('\xAA', 6),  -- MAC地址
            check_sum = 0
        })
    }

    ncsi_utils.ncsi_cmd_ctrl = function(_, _, _, _, cmd_process_table)
        return cmd_process_table[OEM_COMMAND_RSP](mac_rsp)
    end

    result = ncsi_oem_command.get_specific_type_log_by_ncsi_hw(
        package_id, eth_name, 1, 2, 0)
    lu.assertEquals(result, ncsi_def.NCSI_SUCCESS)

    -- 恢复原始函数
    ncsi_utils.ncsi_cmd_ctrl = original_cmd_ctrl
end

-- 测试数据缓冲区处理
function TestNCSIOemCommand:test_data_buffer_functions()
    -- 保存原始函数
    local original_io_open = io.open

    -- 模拟文件操作
    local mock_file = {
        write = function(self, data)
            return true
        end,
        close = function(self)
            return true
        end
    }
    io.open = function(filename, mode)
        return mock_file
    end

    -- 测试场景1: 正常写入数据
    local log_context = ncsi_oem_command.get_log_context()
    log_context.data_buffer = string.rep('\0', 64 * 1024)  -- MAX_BUFFER_LEN
    log_context.data_buffer_content_size = 0
    log_context.cur_len = 0
    log_context.sub_cur_len = 0

    local test_data = {
        data = string.rep('A', 1024)  -- 1KB数据
    }
    local result = ncsi_oem_command.write_data_buffer(1024, mock_file, test_data)
    lu.assertEquals(result, true)

    -- 测试场景2: 处理最后一帧
    log_context.last_frame = 1
    log_context.sub_log_idx = 0
    log_context.sub_log_lens = {2}  -- 2KB的日志长度
    log_context.data_buffer_content_size = 1024
    log_context.sub_cur_len = 1024

    result = ncsi_oem_command.process_last_frame(mock_file)
    lu.assertEquals(result, true)

    -- 恢复原始函数
    io.open = original_io_open
end

-- 测试get_log_by_ncsi_hw_new函数
function TestNCSIOemCommand:test_get_log_by_ncsi_hw_new()
    -- 设置测试环境
    local package_id = 1
    local eth_name = "eth0"
    local log_dir = "/tmp/logs/"
    local time = "20250605"

    local g_log_context = ncsi_oem_command.get_log_context()
    g_log_context.total_length = 2048
    g_log_context.sub_log_num = 2
    g_log_context.sub_log_idx = 0
    g_log_context.cur_len = 0
    g_log_context.sub_log_lens = {1024, 1024} 
    
    -- 模拟成功情况
    ncsi_utils.ncsi_cmd_ctrl = function()
        return ncsi_def.NCSI_SUCCESS
    end
    
     -- 模拟文件操作
     local mock_file = {
        write = function(self, data)
            return true
        end,
        close = function(self)
            return true
        end
    }
    local original_io_open = io.open
    io.open = function(filename, mode)
        return mock_file
    end

    -- 测试成功场景
    local ret = ncsi_cmd.ncsi_get_log_new(package_id, eth_name, log_dir, time)
    lu.assertEquals(ret, ncsi_def.NCSI_SUCCESS)
    
    -- 模拟失败情况
    ncsi_utils.ncsi_cmd_ctrl = function()
        return ncsi_def.NCSI_FAIL
    end
    
    -- 测试失败场景
    ret = ncsi_cmd.ncsi_get_log_new(package_id, eth_name, log_dir, time)
    lu.assertEquals(ret, ncsi_def.NCSI_FAIL)

    io.open = original_io_open
end

-- 测试get_blackbox_by_ncsi_hw函数
function TestNCSIOemCommand:test_get_blackbox_by_ncsi_hw()
    -- 设置测试环境
    local package_id = 1
    local eth_name = "eth0"
    local log_name = "/tmp/logs/blackbox.bin"
    
    -- 模拟成功情况
    ncsi_utils.ncsi_cmd_ctrl = function()
        return ncsi_def.NCSI_SUCCESS
    end
    
    -- 测试成功场景
    local ret = ncsi_cmd.ncsi_get_blackbox(package_id, eth_name, log_name)
    lu.assertEquals(ret, ncsi_def.NCSI_SUCCESS)
    
    -- 模拟失败情况
    ncsi_utils.ncsi_cmd_ctrl = function()
        return ncsi_def.NCSI_FAIL
    end
    
    -- 测试失败场景
    ret = ncsi_cmd.ncsi_get_blackbox(package_id, eth_name, log_name)
    lu.assertEquals(ret, ncsi_def.NCSI_FAIL)
end

-- 测试get_log_by_ncsi_hw函数
function TestNCSIOemCommand:test_get_log_by_ncsi_hw()
    -- 设置测试环境
    local package_id = 1
    local eth_name = "eth0"
    local log_dir = "/tmp/logs/"
    local time = "20250605"
    
    -- 模拟成功情况
    ncsi_utils.ncsi_cmd_ctrl = function()
        return ncsi_def.NCSI_SUCCESS
    end
    
    -- 测试成功场景
    local ret = ncsi_cmd.ncsi_get_log(package_id, eth_name, log_dir, time)
    lu.assertEquals(ret, ncsi_def.NCSI_SUCCESS)
    
    -- 模拟失败情况 - mpu ucode日志获取失败
    ncsi_utils.ncsi_cmd_ctrl = function()
        return ncsi_def.NCSI_FAIL
    end
    
    -- 测试mpu ucode日志获取失败场景
    ret = ncsi_cmd.ncsi_get_log(package_id, eth_name, log_dir, time)
    lu.assertEquals(ret, ncsi_def.NCSI_FAIL)
    
    -- 模拟部分成功情况 - last_word日志获取失败
    local call_count = 0
    ncsi_utils.ncsi_cmd_ctrl = function()
        call_count = call_count + 1
        if call_count == 1 then
            return ncsi_def.NCSI_SUCCESS
        else
            return ncsi_def.NCSI_FAIL
        end
    end
    
    -- 测试last_word日志获取失败场景
    ret = ncsi_cmd.ncsi_get_log(package_id, eth_name, log_dir, time)
    lu.assertEquals(ret, ncsi_def.NCSI_FAIL)
end


-- 测试获取LLDP over NCSI状态
function TestNCSIOemCommand:test_get_lldp_over_ncsi_status()
    -- 测试参数
    local eth_name = "eth0"
    local package_id = 0
    local channel_id = 0

    -- 模拟响应包
    local function create_mock_response(status)
        local rsp = {packet_head = {}, payload = ''}
        rsp.packet_head.payload_len_hi = 0
        rsp.packet_head.payload_len_lo = 16
        rsp.packet_head.packet_type = OEM_COMMAND_RSP
        rsp.packet_head.channel_id = channel_id

        -- 创建响应payload
        local rsp_data = get_lldp_over_ncsi_rsp_bs:pack({
            rsp_code = ncsi_def.CMD_COMPLETED,
            reason_code = 0,
            manufacture_id = MANUFACTURE_ID_HUAWEI,
            cmd_rev = 0,
            cmd_id = GET_LLDP_OVER_NCSI_CMD_ID,
            sub_cmd = GET_LLDP_OVER_NCSI_STATUS,
            reserved = 0,
            status = status,
            reserved1 = string.rep('\0', 3),
            check_sum = 0
        })

        rsp.payload = rsp_data
        return rsp
    end

    -- 模拟cmd_ctrl函数
    local original_cmd_ctrl = ncsi_utils.ncsi_cmd_ctrl
    ncsi_utils.ncsi_cmd_ctrl = function(_, _, req_packet, eth_name, cmd_process_table)
        if req_packet.packet_head.packet_type == OEM_COMMAND then
            -- 调用请求处理函数
            cmd_process_table[OEM_COMMAND](req_packet, eth_name)
        elseif req_packet.packet_head.packet_type == OEM_COMMAND_RSP then
            -- 调用响应处理函数
            cmd_process_table[OEM_COMMAND_RSP](create_mock_response(1), eth_name)
        end
        return ncsi_def.NCSI_SUCCESS
    end

    -- 执行测试
    local ret = ncsi_cmd.ncsi_set_lldp_status(eth_name, package_id, channel_id, 1)

    -- 验证结果
    lu.assertEquals(ret, ncsi_def.NCSI_SUCCESS)

    -- 恢复原始函数
    ncsi_utils.ncsi_cmd_ctrl = original_cmd_ctrl
end

-- 测试设置LLDP over NCSI状态
function TestNCSIOemCommand:test_set_lldp_over_ncsi_status()
    -- 测试参数
    local eth_name = "eth0"
    local package_id = 0
    local channel_id = 0
    local status = 1

    -- 模拟响应包
    local function create_mock_response(rsp_code, status)
        local rsp = {packet_head = {}, payload = ''}
        rsp.packet_head.payload_len_hi = 0
        rsp.packet_head.payload_len_lo = 16
        rsp.packet_head.packet_type = OEM_COMMAND_RSP
        rsp.packet_head.channel_id = channel_id

        -- 创建响应payload
        local rsp_data = get_lldp_over_ncsi_rsp_bs:pack({
            rsp_code = rsp_code,
            reason_code = 0,
            manufacture_id = MANUFACTURE_ID_HUAWEI,
            cmd_rev = 0,
            cmd_id = GET_LLDP_OVER_NCSI_CMD_ID,
            sub_cmd = GET_LLDP_OVER_NCSI_STATUS,
            reserved = 0,
            status = status,
            reserved1 = string.rep('\0', 3),
            check_sum = 0
        })

        rsp.payload = rsp_data
        return rsp
    end

    -- 模拟cmd_ctrl函数
    local original_cmd_ctrl = ncsi_utils.ncsi_cmd_ctrl
    ncsi_utils.ncsi_cmd_ctrl = function(_, _, req_packet, eth_name, cmd_process_table)
        if req_packet.packet_head.packet_type == OEM_COMMAND then
            -- 调用请求处理函数
            cmd_process_table[OEM_COMMAND](req_packet, eth_name)
        elseif req_packet.packet_head.packet_type == OEM_COMMAND_RSP then
            -- 调用响应处理函数
            cmd_process_table[OEM_COMMAND_RSP](create_mock_response(ncsi_def.CMD_COMPLETED, status), eth_name)
        end
        return ncsi_def.NCSI_SUCCESS
    end

    -- 执行测试
    local ret = ncsi_oem_command.update_lldp_over_ncsi_status(eth_name, package_id, channel_id, status)

    -- 验证结果
    lu.assertEquals(ret, ncsi_def.NCSI_SUCCESS)

    -- 恢复原始函数
    ncsi_utils.ncsi_cmd_ctrl = original_cmd_ctrl
end

-- 测试标准LLDP转发功能
function TestNCSIOemCommand:test_std_lldp_forward()
    -- 测试参数
    local eth_name = "eth0"
    local package_id = 0
    local channel_id = 0

    -- 模拟NCSI参数
    self.mock_ncsi_parameter = {
        iid = 1,  -- 添加iid字段，这是NCSI协议需要的包ID
        channel_cap = {
            [package_id] = {
                [channel_id] = {
                    vlan_mode = 0x02,  -- VLAN_MODE_FIELD_VLAN_NON_VLAN
                    mul_filter_cnt = 1,
                    mix_filter_cnt = 1
                }
            }
        }
    }

    -- 模拟ncsi_mac.ncsi_set_multicast_mac_filter
    local original_set_multicast_mac_filter = ncsi_mac.ncsi_set_multicast_mac_filter
    ncsi_mac.ncsi_set_multicast_mac_filter = function(_, _, _, _, _)
        return ncsi_def.NCSI_SUCCESS
    end

    -- 模拟ncsi_vlan_mode.ncsi_enable_vlan_req
    local original_enable_vlan_req = ncsi_vlan_mode.ncsi_enable_vlan_req
    ncsi_vlan_mode.ncsi_enable_vlan_req = function(_, _, _, _)
        return ncsi_def.NCSI_SUCCESS
    end

    -- 测试启用LLDP转发
    local ret = ncsi_oem_command.update_lldp_over_ncsi_status(eth_name, package_id, channel_id, 1)
    lu.assertEquals(ret, ncsi_def.NCSI_SUCCESS)

    -- 测试禁用LLDP转发
    ret = ncsi_oem_command.update_lldp_over_ncsi_status(eth_name, package_id, channel_id, 0)
    lu.assertEquals(ret, ncsi_def.NCSI_SUCCESS)

    -- 模拟NCSI参数
    self.mock_ncsi_parameter = {
        iid = 1,  -- 添加iid字段，这是NCSI协议需要的包ID
        channel_cap = {
            [package_id] = {
                [channel_id] = {
                    vlan_mode = 0x04,  -- VLAN_MODE_FIELD_ANYVLAN_NON_VLAN
                    mul_filter_cnt = 1,
                    mix_filter_cnt = 1
                }
            }
        }
    }

    -- 测试启用LLDP转发
    ret = ncsi_oem_command.update_lldp_over_ncsi_status(eth_name, package_id, channel_id, 1)
    lu.assertEquals(ret, ncsi_def.NCSI_SUCCESS)

    -- 恢复原始函数
    ncsi_mac.ncsi_set_multicast_mac_filter = original_set_multicast_mac_filter
    ncsi_vlan_mode.ncsi_enable_vlan_req = original_enable_vlan_req
end

-- 测试无效的LLDP over NCSI状态
function TestNCSIOemCommand:test_invalid_lldp_over_ncsi_status()
    -- 测试参数
    local eth_name = "eth0"
    local package_id = 0
    local channel_id = 0
    local invalid_status = 2  -- 无效的状态值

    -- 执行测试
    local ret = ncsi_oem_command.update_lldp_over_ncsi_status(eth_name, package_id, channel_id, invalid_status)

    -- 验证结果
    lu.assertEquals(ret, ncsi_def.NCSI_FAIL)
end

-- 测试无效的网卡名称
function TestNCSIOemCommand:test_invalid_eth_name()
    -- 测试参数
    local invalid_eth_name = "invalid_eth"
    local package_id = 0
    local channel_id = 0
    local status = 0

    local original_set_multicast_mac_filter = ncsi_mac.ncsi_set_multicast_mac_filter
    ncsi_mac.ncsi_set_multicast_mac_filter = function(_, _, _, _, _)
        return ncsi_def.NCSI_FAIL
    end

    -- 执行测试
    local ret = ncsi_oem_command.update_lldp_over_ncsi_status(invalid_eth_name, package_id, channel_id, status)

    -- 验证结果
    lu.assertEquals(ret, ncsi_def.NCSI_FAIL)
    ncsi_mac.ncsi_set_multicast_mac_filter = original_set_multicast_mac_filter
end

-- 测试LLDP over NCSI状态设置
function TestNCSIOemCommand:test_set_port_lldp_over_ncsi_capability_hw()
    -- 保存原始函数
    local original_send_ncsi_cmd = ncsi_protocol_intf.send_ncsi_cmd
    self.original_cmd_ctrl = ncsi_utils.ncsi_cmd_ctrl

    -- 模拟send_ncsi_cmd函数
    local mock_send_ncsi_cmd = function(req_data, len, eth_name)
        return ncsi_def.NCSI_SUCCESS
    end
    
    -- 模拟cmd_ctrl函数
    local mock_cmd_ctrl = function(package_id, channel_id, req_packet, eth_name, cmd_process_table)
        if req_packet.packet_head.packet_type == OEM_COMMAND then
            -- 调用请求处理函数
            cmd_process_table[OEM_COMMAND](req_packet, eth_name)
        end
        return ncsi_def.NCSI_SUCCESS
    end

    -- 替换函数
    ncsi_protocol_intf.send_ncsi_cmd = mock_send_ncsi_cmd
    ncsi_utils.ncsi_cmd_ctrl = mock_cmd_ctrl

    -- 测试设置状态为启用
    local ret = ncsi_oem_command.set_port_lldp_over_ncsi_capability_hw("eth0", 0, 0, 1)
    lu.assertEquals(ret, ncsi_def.NCSI_SUCCESS)

    -- 测试设置状态为禁用
    ret = ncsi_oem_command.set_port_lldp_over_ncsi_capability_hw("eth0", 0, 0, 0)
    lu.assertEquals(ret, ncsi_def.NCSI_SUCCESS)

    -- 恢复原始函数
    ncsi_protocol_intf.send_ncsi_cmd = original_send_ncsi_cmd
    ncsi_utils.ncsi_cmd_ctrl = original_cmd_ctrl
end