-- Copyright (c) 2025 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 ncsi_demo = require 'hardware_config.ncsi_demo'

TestNCSIDemo = {}

-- 测试是否可以创建protocol
function TestNCSIDemo:test_can_create_protocol()
    local p = ncsi_demo.new({
        endpoint = {
            Request = function() end
        }
    })
    lu.assertNotNil(p)
end

local validate_testcases<const> = {
    {
        {
            channel_id = 0,
            package_id = 0,
            cmd1 = 1,
            cmd2 = 2,
            cmd3 = 3,
            cmd4 = 4,
            data = 5
        }, 
        true
    },
    {
        {
            channel_id = 0,
            package_id = 0,
            some_random_cmd = 0
        },
        false
    }
}

function TestNCSIDemo:test_can_validate_request_params()
    local p = ncsi_demo.new({
        endpoint = {
            Request = function() end
        }
    })
    for _, case in ipairs(validate_testcases) do
        lu.assertEquals(p:validate_request_params(case[1]), case[2])
    end
end

local construct_request_data_testcases<const> = {
    {
        name = 'can_construct_normal_request',
        request = {
            channel_id = 1,
            package_id = 2,
            cmd1 = 3,
            cmd2 = 4,
            cmd3 = 5,
            cmd4 = 6,
            data = 'some data'
        },
        expect_req_ctx = {
            PacketType = tostring(0x50),
            ChannelId = tostring(0x01),
            PackageId = tostring(0x02),
        },
        expect_rsp_ctx = {
            PacketType = tostring(0xD0)
        },
        expect_data = '\x00\x00\x66\x66\x03\x04\x05\x06' .. 'some data'
    }
}

function TestNCSIDemo:test_can_construct_request_data()
    for _, case in ipairs(construct_request_data_testcases) do
        local p = ncsi_demo.new({
            endpoint = {
                Request = function() end
            }
        })
        local ctx = {}
        local req_ctx, rsp_ctx, request_data = p:construct_request_data(ctx, case.request)
        lu.assertEquals(req_ctx, case.expect_req_ctx)
        lu.assertEquals(rsp_ctx, case.expect_rsp_ctx)
        lu.assertEquals(request_data, case.expect_data)
    end

end

local function pack(t)
    local r = ''
    for _, v in ipairs(t) do
        r = r .. v
    end
    return r
end

local can_unpack_rsp_data_testcases<const> = {
    {
        name = 'can_unpack_normal_rsp_data',
        ctx = {
            manufacture_id = 0x6666,
        },
        data = pack({
            '\x00\x00', -- rsp_code,
            '\x00\x00', -- reason_code,
            '\x00\x00\x66\x66', -- manu_id
            '\x01', -- cmd1
            '\x02', -- cmd2
            '\x03', -- cmd3
            '\x04', -- cmd4,
            '\x01some data' -- data
        }),
        expect = '\x01some data'
    }
}

function TestNCSIDemo:test_can_unpack_response_data()
    for _, case in ipairs(can_unpack_rsp_data_testcases) do
        local p = ncsi_demo.new({
            endpoint = {
                Request = function() end
            }
        })
        local data = p:unpack_response_data(case.ctx, case.data)
        lu.assertEquals(data, case.expect)
    end
end

local send_request_testcases<const> = {
    {
        name = 'cand_send_normal_request',
        request = {
            channel_id = 1,
            package_id = 2,
            cmd1 = 3,
            cmd2 = 4,
            cmd3 = 5,
            cmd4 = 6,
            data = 'some data'
        },
        mock_request_func = function(...)
            return pack({
                '\x00\x00', -- rsp_code,
                '\x00\x00', -- reason_code,
                '\x00\x00\x66\x66', -- manu_id
                '\x03', -- cmd1
                '\x04', -- cmd2
                '\x05', -- cmd3
                '\x06', -- cmd4,
                '\x01some data' -- data
            })
        end,
        expect = '\x01some data'
    }
}

function TestNCSIDemo:test_can_send_request()
    for _, case in ipairs(send_request_testcases) do
        local p = ncsi_demo.new({
            endpoint = {
                Request = case.mock_request_func
            }
        })
        lu.assertEquals(p:send_request(case.request), case.expect)
    end

end