-- 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 LPe32002_AP = require 'hardware_config.XE501'
local LPe35002_AP = require 'hardware_config.XE601'
local emulex = LPe32002_AP.mctp_pldm()
local utils = require 'mc.utils'


-- 测试套件
TestPldmLpe32002AP = {}

-- 测试获取芯片温度
function TestPldmLpe32002AP:test_get_chiptemp()
    lu.assertEquals(utils.table_compare(LPe32002_AP, LPe35002_AP), true)
    -- 测试正常情况 - operational_state = 0x00, sensor_data_size = 0
    local data = string.char(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e)
    local result = emulex.properties.ChipTemp.response(data)
    lu.assertEquals(result, 0x4e)

    -- 测试operational_state非使能状态
    data = string.char(0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e)
    result = emulex.properties.ChipTemp.response(data)
    lu.assertEquals(result, 0xff)

    -- 测试sensor_data_size不为0的情况
    data = string.char(0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e)
    result = emulex.properties.ChipTemp.response(data)
    lu.assertEquals(result, 0xff)

    -- 测试极端温度值
    data = string.char(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
    result = emulex.properties.ChipTemp.response(data)
    lu.assertEquals(result, 0x00)

    data = string.char(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff)
    result = emulex.properties.ChipTemp.response(data)
    lu.assertEquals(result, 0xff)
end

-- 测试获取端口0链路速度
function TestPldmLpe32002AP:test_get_port0_linkspeed()
    -- 测试正常情况 - operational_state = 0x00, sensor_data_size = 2
    local data = string.char(0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00)
    local result = emulex.properties.Port0LinkSpeed.response(data)
    lu.assertEquals(result, 0x4e)

    -- 测试operational_state非使能状态
    data = string.char(0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00)
    result = emulex.properties.Port0LinkSpeed.response(data)
    lu.assertEquals(result, 0)

    -- 测试sensor_data_size不为2的情况
    data = string.char(0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e)
    result = emulex.properties.Port0LinkSpeed.response(data)
    lu.assertEquals(result, 0)

    -- 测试高速度值（16位数据）
    data = string.char(0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff)
    result = emulex.properties.Port0LinkSpeed.response(data)
    lu.assertEquals(result, 0xffff)

    -- 测试零速度
    data = string.char(0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
    result = emulex.properties.Port0LinkSpeed.response(data)
    lu.assertEquals(result, 0x00)
end

-- 测试获取端口1链路速度
function TestPldmLpe32002AP:test_get_port1_linkspeed()
    -- 测试正常情况
    local data = string.char(0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x01)
    local result = emulex.properties.Port1LinkSpeed.response(data)
    lu.assertEquals(result, 0x0132)

    -- 测试operational_state非使能状态
    data = string.char(0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x32, 0x01)
    result = emulex.properties.Port1LinkSpeed.response(data)
    lu.assertEquals(result, 0)

    -- 测试错误的sensor_data_size
    data = string.char(0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x01, 0x00)
    result = emulex.properties.Port1LinkSpeed.response(data)
    lu.assertEquals(result, 0)
end

-- 测试获取端口0链路状态
function TestPldmLpe32002AP:test_get_port0_linkstatus()
    -- 测试连接状态 - operational_state = 0x00, present_state = 0x01
    local data = string.char(0x00, 0x00, 0x01, 0x00, 0x00)
    local result = emulex.properties.Port0LinkStatus.response(data)
    lu.assertEquals(result, 'Connected')

    -- 测试断开状态 - operational_state = 0x00, present_state = 0x00
    data = string.char(0x00, 0x00, 0x00, 0x00, 0x00)
    result = emulex.properties.Port0LinkStatus.response(data)
    lu.assertEquals(result, 'Disconnected')

    -- 测试operational_state非使能状态
    data = string.char(0x00, 0x01, 0x01, 0x00, 0x00)
    result = emulex.properties.Port0LinkStatus.response(data)
    lu.assertEquals(result, 'N/A')

    -- 测试其他present_state值
    data = string.char(0x00, 0x00, 0x02, 0x00, 0x00)
    result = emulex.properties.Port0LinkStatus.response(data)
    lu.assertEquals(result, 'Disconnected')
end

-- 测试获取端口1链路状态
function TestPldmLpe32002AP:test_get_port1_linkstatus()
    -- 测试连接状态
    local data = string.char(0x00, 0x00, 0x01, 0x00, 0x00)
    local result = emulex.properties.Port1LinkStatus.response(data)
    lu.assertEquals(result, 'Connected')

    -- 测试断开状态
    data = string.char(0x00, 0x00, 0x00, 0x00, 0x00)
    result = emulex.properties.Port1LinkStatus.response(data)
    lu.assertEquals(result, 'Disconnected')

    -- 测试operational_state非使能状态
    data = string.char(0x00, 0x01, 0x00, 0x00, 0x00)
    result = emulex.properties.Port1LinkStatus.response(data)
    lu.assertEquals(result, 'N/A')
end

-- 测试获取固件版本
function TestPldmLpe32002AP:test_get_firmware_version()
    -- 测试正常固件版本格式
    local data = {
        {type = 0x02, value = "FW Version:12.8.340.44"},
        {type = 0x01, value = "other data"}
    }
    local result = emulex.properties.FirmwareVersion.response(data)
    lu.assertEquals(result, '12.8.340.44')

    -- 测试不同的固件版本格式
    data = {
        {type = 0x02, value = "FW Version:1.0"},
        {type = 0x03, value = "other data"}
    }
    result = emulex.properties.FirmwareVersion.response(data)
    lu.assertEquals(result, '1.0')

    -- 测试单一版本号
    data = {
        {type = 0x02, value = "FW Version:5"},
        {type = 0x03, value = "other data"}
    }
    result = emulex.properties.FirmwareVersion.response(data)
    lu.assertEquals(result, '5')

    -- 测试没有固件版本类型
    data = {
        {type = 0x01, value = "other data"},
        {type = 0x03, value = "more data"}
    }
    result = emulex.properties.FirmwareVersion.response(data)
    lu.assertEquals(result, 'N/A')

    -- 测试空数据
    result = emulex.properties.FirmwareVersion.response(nil)
    lu.assertEquals(result, 'N/A')

    -- 测试格式不匹配的固件版本 - string.match不匹配时返回nil
    data = {
        {type = 0x02, value = "Firmware:12.8.340.44"},  -- 不是 "FW Version:" 格式
        {type = 0x01, value = "other data"}
    }
    result = emulex.properties.FirmwareVersion.response(data)
    lu.assertEquals(result, nil)  -- 修改期望值为nil

    -- 测试完全不包含版本信息的字符串
    data = {
        {type = 0x02, value = "Some other text"},
        {type = 0x01, value = "other data"}
    }
    result = emulex.properties.FirmwareVersion.response(data)
    lu.assertEquals(result, nil)  -- string.match不匹配返回nil

    -- 测试空字符串value
    data = {
        {type = 0x02, value = ""},
        {type = 0x01, value = "other data"}
    }
    result = emulex.properties.FirmwareVersion.response(data)
    lu.assertEquals(result, nil)  -- 空字符串匹配返回nil
end

-- 测试获取部件号
function TestPldmLpe32002AP:test_get_part_number()
    -- 测试正常部件号
    local data = {
        {type = 0x03, value = "LPe32002-AP"},
        {type = 0x01, value = "other data"}
    }
    local result = emulex.properties.PartNumber.response(data)
    lu.assertEquals(result, 'LPe32002-AP')

    -- 测试没有部件号类型
    data = {
        {type = 0x01, value = "other data"},
        {type = 0x02, value = "more data"}
    }
    result = emulex.properties.PartNumber.response(data)
    lu.assertEquals(result, 'N/A')

    -- 测试空数据
    result = emulex.properties.PartNumber.response(nil)
    lu.assertEquals(result, 'N/A')

    -- 测试空字符串部件号
    data = {
        {type = 0x03, value = ""},
        {type = 0x01, value = "other data"}
    }
    result = emulex.properties.PartNumber.response(data)
    lu.assertEquals(result, '')
end

-- 测试获取序列号
function TestPldmLpe32002AP:test_get_serial_number()
    -- 测试正常序列号
    local data = {
        {type = 0x04, value = "SN123456789"},
        {type = 0x01, value = "other data"}
    }
    local result = emulex.properties.SerialNumber.response(data)
    lu.assertEquals(result, 'SN123456789')

    -- 测试没有序列号类型
    data = {
        {type = 0x01, value = "other data"},
        {type = 0x02, value = "more data"}
    }
    result = emulex.properties.SerialNumber.response(data)
    lu.assertEquals(result, 'N/A')

    -- 测试空数据
    result = emulex.properties.SerialNumber.response(nil)
    lu.assertEquals(result, 'N/A')

    -- 测试多个相同类型，应该返回第一个
    data = {
        {type = 0x04, value = "SN123"},
        {type = 0x04, value = "SN456"},
        {type = 0x01, value = "other data"}
    }
    result = emulex.properties.SerialNumber.response(data)
    lu.assertEquals(result, 'SN123')
end

-- 测试获取端口0工作WWNN
function TestPldmLpe32002AP:test_get_port0_work_wwnn()
    -- 测试正常WWNN格式
    local data = {
        {type = 0x83, value = "WWNN:1234567890ABCDEF"},
        {type = 0x01, value = "other data"}
    }
    local result = emulex.properties.Port0WorkWWNN.response(data)
    lu.assertEquals(result, '12:34:56:78:90:AB:CD:EF')

    -- 测试没有WWNN类型
    data = {
        {type = 0x01, value = "other data"},
        {type = 0x02, value = "more data"}
    }
    result = emulex.properties.Port0WorkWWNN.response(data)
    lu.assertEquals(result, nil)

    -- 测试空数据
    result = emulex.properties.Port0WorkWWNN.response(nil)
    lu.assertEquals(result, '')

    -- 测试错误的WWNN格式（前缀不匹配）
    data = {
        {type = 0x83, value = "WWPN:1234567890ABCDEF"},
        {type = 0x01, value = "other data"}
    }
    result = emulex.properties.Port0WorkWWNN.response(data)
    lu.assertEquals(result, nil)

    -- 测试错误的WWNN格式（长度不足）
    data = {
        {type = 0x83, value = "WWNN:1234567890ABCD"},
        {type = 0x01, value = "other data"}
    }
    result = emulex.properties.Port0WorkWWNN.response(data)
    lu.assertEquals(result, nil)

    -- 测试错误的WWNN格式（包含非十六进制字符）
    data = {
        {type = 0x83, value = "WWNN:1234567890ABCDGH"},
        {type = 0x01, value = "other data"}
    }
    result = emulex.properties.Port0WorkWWNN.response(data)
    lu.assertEquals(result, nil)
end

-- 测试获取端口1工作WWNN
function TestPldmLpe32002AP:test_get_port1_work_wwnn()
    -- 测试正常WWNN格式
    local data = {
        {type = 0x83, value = "WWNN:FEDCBA0987654321"},
        {type = 0x01, value = "other data"}
    }
    local result = emulex.properties.Port1WorkWWNN.response(data)
    lu.assertEquals(result, 'FE:DC:BA:09:87:65:43:21')

    -- 测试没有WWNN类型
    data = {
        {type = 0x01, value = "other data"}
    }
    result = emulex.properties.Port1WorkWWNN.response(data)
    lu.assertEquals(result, nil)

    -- 测试空数据
    result = emulex.properties.Port1WorkWWNN.response(nil)
    lu.assertEquals(result, '')
end

-- 测试获取端口0工作WWPN
function TestPldmLpe32002AP:test_get_port0_work_wwpn()
    -- 测试正常WWPN格式
    local data = {
        {type = 0x84, value = "WWPN:1122334455667788"},
        {type = 0x01, value = "other data"}
    }
    local result = emulex.properties.Port0WorkWWPN.response(data)
    lu.assertEquals(result, '11:22:33:44:55:66:77:88')

    -- 测试没有WWPN类型
    data = {
        {type = 0x01, value = "other data"},
        {type = 0x83, value = "WWNN:1234567890ABCDEF"}
    }
    result = emulex.properties.Port0WorkWWPN.response(data)
    lu.assertEquals(result, nil)

    -- 测试空数据
    result = emulex.properties.Port0WorkWWPN.response(nil)
    lu.assertEquals(result, '')

    -- 测试错误的WWPN格式（前缀不匹配）
    data = {
        {type = 0x84, value = "WWNN:1122334455667788"},
        {type = 0x01, value = "other data"}
    }
    result = emulex.properties.Port0WorkWWPN.response(data)
    lu.assertEquals(result, nil)
end

-- 测试获取端口1工作WWPN
function TestPldmLpe32002AP:test_get_port1_work_wwpn()
    -- 测试正常WWPN格式
    local data = {
        {type = 0x84, value = "WWPN:AABBCCDDEEFF0011"},
        {type = 0x01, value = "other data"}
    }
    local result = emulex.properties.Port1WorkWWPN.response(data)
    lu.assertEquals(result, 'AA:BB:CC:DD:EE:FF:00:11')

    -- 测试没有WWPN类型
    data = {
        {type = 0x01, value = "other data"}
    }
    result = emulex.properties.Port1WorkWWPN.response(data)
    lu.assertEquals(result, nil)

    -- 测试空数据
    result = emulex.properties.Port1WorkWWPN.response(nil)
    lu.assertEquals(result, '')
end

-- 测试AllInfo属性（空函数）
function TestPldmLpe32002AP:test_all_info()
    -- AllInfo的response函数为空，测试调用不会出错
    local result = emulex.properties.AllInfo.response()
    lu.assertEquals(result, nil)
    
    -- 测试传入参数也不会出错
    result = emulex.properties.AllInfo.response("some data")
    lu.assertEquals(result, nil)
end

-- 测试WWNN/WWPN格式化函数的边界条件
function TestPldmLpe32002AP:test_get_wwnn_wwpn_edge_cases()
    -- 由于get_wwnn_wwpn是内部函数，我们通过调用使用它的函数来测试
    
    -- 测试空输入
    local data = {
        {type = 0x83, value = nil}
    }
    local result = emulex.properties.Port0WorkWWNN.response(data)
    lu.assertEquals(result, nil)

    -- 测试过长的十六进制字符串
    data = {
        {type = 0x83, value = "WWNN:1234567890ABCDEF00"}
    }
    result = emulex.properties.Port0WorkWWNN.response(data)
    lu.assertEquals(result, nil)

    -- 测试过短的十六进制字符串
    data = {
        {type = 0x83, value = "WWNN:1234567890ABCD"}
    }
    result = emulex.properties.Port0WorkWWNN.response(data)
    lu.assertEquals(result, nil)

    -- 测试包含小写字母（应该失败，因为只匹配大写）
    data = {
        {type = 0x83, value = "WWNN:1234567890abcdef"}
    }
    result = emulex.properties.Port0WorkWWNN.response(data)
    lu.assertEquals(result, nil)

    -- 测试正确的全大写格式
    data = {
        {type = 0x83, value = "WWNN:1234567890ABCDEF"}
    }
    result = emulex.properties.Port0WorkWWNN.response(data)
    lu.assertEquals(result, '12:34:56:78:90:AB:CD:EF')
end

-- 测试协议配置
function TestPldmLpe32002AP:test_protocol_configuration()
    -- 验证mctp_pldm函数返回正确的对象结构
    local test_endpoint = "test_endpoint"
    local obj = LPe32002_AP.mctp_pldm(test_endpoint)
    
    -- 验证协议依赖设置正确
    lu.assertEquals(obj.protocol_dependencies.pldm_sensor.endpoint, test_endpoint)
    lu.assertEquals(obj.protocol_dependencies.pldm_emulex_fru.endpoint, test_endpoint)
    
    -- 验证所有属性都存在
    lu.assertNotNil(obj.properties.ChipTemp)
    lu.assertNotNil(obj.properties.Port0LinkSpeed)
    lu.assertNotNil(obj.properties.Port1LinkSpeed)
    lu.assertNotNil(obj.properties.Port0LinkStatus)
    lu.assertNotNil(obj.properties.Port1LinkStatus)
    lu.assertNotNil(obj.properties.FirmwareVersion)
    lu.assertNotNil(obj.properties.PartNumber)
    lu.assertNotNil(obj.properties.SerialNumber)
    lu.assertNotNil(obj.properties.Port0WorkWWNN)
    lu.assertNotNil(obj.properties.Port1WorkWWNN)
    lu.assertNotNil(obj.properties.Port0WorkWWPN)
    lu.assertNotNil(obj.properties.Port1WorkWWPN)
    lu.assertNotNil(obj.properties.AllInfo)
    
    -- 验证请求参数配置正确
    lu.assertEquals(obj.properties.ChipTemp.request.sensor_id, 0x21)
    lu.assertEquals(obj.properties.Port0LinkSpeed.request.sensor_id, 0x31)
    lu.assertEquals(obj.properties.Port1LinkSpeed.request.sensor_id, 0x32)
    lu.assertEquals(obj.properties.Port0LinkStatus.request.sensor_id, 0x81)
    lu.assertEquals(obj.properties.Port1LinkStatus.request.sensor_id, 0x82)
    
    -- 验证周期配置
    lu.assertEquals(obj.properties.ChipTemp.period_in_sec, 5)
    lu.assertEquals(obj.properties.Port0LinkSpeed.period_in_sec, 10)
    lu.assertEquals(obj.properties.Port1LinkSpeed.period_in_sec, 10)
    lu.assertEquals(obj.properties.Port0LinkStatus.period_in_sec, 2)
    lu.assertEquals(obj.properties.Port1LinkStatus.period_in_sec, 2)
    lu.assertEquals(obj.properties.FirmwareVersion.period_in_sec, 60)
end