-- 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 smc_firmware_status = require 'release_command.smc_firmware_status'
local MCU_ENUMS = require 'mcu.enum.mcu_enums'

TestReleaseCommand = {}

-- 测试MCU字段处理
function TestReleaseCommand:test_mcu_processing()
    local interface = {
        get_subcomp_upgrade_cnt = function() return { cnt = 1 } end,
        get_upgrade_detail = function(index)
            if (type(index) == "number" and index == 0) or type(index) == "table" then
                return {
                    type = MCU_ENUMS.SUB_COMPONENT_TYPE.T_MCU,
                    no = 123,
                    vendor = "TestVendor",
                    sku = "TestModel",
                    major_version = 1,
                    minor_version = 2,
                    revision = 3,
                    delay = 10
                }
            end
            return nil
        end,
        query_upgrade_status = function() return "Active" end
    }

    local obj = {
        mcu = { Id = "MCU001", Protocol = MCU_ENUMS.SMC_CHANNEL },
        interface = interface
    }

    local result = smc_firmware_status:get_update_details(
        { mcu_collection = { obj } }, { smc_ind_vrd_collection = {} }, "MCU")

    lu.assertIsTable(result)
    lu.assertEquals(result[1].ObjectId, "MCU001")
    lu.assertEquals(result[1].ChipType, "0")
    lu.assertEquals(result[1].ChipIndex, "123")
    lu.assertEquals(result[1].ChipVendor, "TestVendor")
    lu.assertEquals(result[1].TansmissionIntervalMilliseconds, "1000") -- 10 * 100
end

-- 测试VRD字段处理
function TestReleaseCommand:test_vrd_processing()
    local interface = {
        get_subcomp_upgrade_cnt = function() return { cnt = 1 } end,
        get_upgrade_detail = function(index)
            if (type(index) == "number" and index == 0) or type(index) == "table" then
                return {
                    type = MCU_ENUMS.SUB_COMPONENT_TYPE.T_VRD,
                    no = 456,
                    vendor = "VRDVendor",
                    sku = "VRDModel",
                    major_version = 2,
                    minor_version = 1,
                    revision = 0,
                    delay = 15
                }
            end
            return nil
        end,
        query_upgrade_status = function() return "Ready" end
    }

    local obj = {
        mcu = { Id = "VRD001", Protocol = MCU_ENUMS.SMC_CHANNEL },
        interface = interface
    }

    local result = smc_firmware_status:get_update_details(
        { mcu_collection = { obj } }, { smc_ind_vrd_collection = {} }, "VRD")

    lu.assertIsTable(result)
    lu.assertEquals(result[1].ObjectId, "VRD001")
    lu.assertEquals(result[1].ChipType, "2")
    lu.assertEquals(result[1].ChipIndex, "456")
    lu.assertEquals(result[1].ChipVendor, "VRDVendor")
    lu.assertEquals(result[1].TansmissionIntervalMilliseconds, "1500") -- 15 * 100
end

-- 测试SMBus通道
function TestReleaseCommand:test_smbus()
    local interface = {
        get_vendor_id = function() return "SMBusVendor" end,
        get_version = function() return 1, 2, 3 end,
        query_upgrade_status = function() return "Ready" end
    }

    local obj = {
        mcu = { Id = "SMB001", Protocol = MCU_ENUMS.SMBUS_CHANNEL },
        interface = interface
    }

    local result = smc_firmware_status:get_update_details(
        { mcu_collection = { obj } }, { smc_ind_vrd_collection = {} }, "MCU")

    lu.assertEquals(#result, 1)
    lu.assertEquals(result[1].ObjectId, "SMB001")
    lu.assertEquals(result[1].ChipVendor, "SMBusVendor")
end

-- 测试独立VRD服务
function TestReleaseCommand:test_independent_vrd()
    local interface = {
        get_subcomp_upgrade_cnt = function() return { cnt = 1 } end,
        get_upgrade_detail = function(index)
            if (type(index) == "number" and index == 0) or type(index) == "table" then
                return {
                    type = MCU_ENUMS.SUB_COMPONENT_TYPE.T_VRD,
                    no = 0,
                    vendor = "IndVRD",
                    sku = "IndModel"
                }
            end
            return nil
        end,
        query_upgrade_status = function() return "Processing" end
    }

    local obj = {
        mcu = { Id = "INDVRD001", Protocol = MCU_ENUMS.SMC_CHANNEL },
        interface = interface
    }

    local result = smc_firmware_status:get_update_details(
        { mcu_collection = {} }, { smc_ind_vrd_collection = { obj } }, "VRD")

    lu.assertEquals(result[1].ChipVendor, "IndVRD")
    lu.assertIsTable(result)
end

-- 测试类型过滤
function TestReleaseCommand:test_type_filtering()
    local interface = {
        get_subcomp_upgrade_cnt = function() return { cnt = 1 } end,
        get_upgrade_detail = function(index)
            if (type(index) == "number" and index == 0) or type(index) == "table" then
                return {
                    type = MCU_ENUMS.SUB_COMPONENT_TYPE.T_MCU,
                    vendor = "ShouldBeFiltered"
                }
            end
            return nil
        end,
        query_upgrade_status = function() return "Status" end
    }

    local obj = {
        mcu = { Id = "FILTER001", Protocol = MCU_ENUMS.SMC_CHANNEL },
        interface = interface
    }

    -- 请求VRD但组件是MCU类型，应该被过滤
    local result = smc_firmware_status:get_update_details(
        { mcu_collection = { obj } }, { smc_ind_vrd_collection = {} }, "VRD")

    lu.assertIsTable(result)
    lu.assertEquals(#result, 0)
end

-- 测试空集合
function TestReleaseCommand:test_empty()
    local result = smc_firmware_status:get_update_details(
        { mcu_collection = {} }, { smc_ind_vrd_collection = {} }, "MCU")
    lu.assertEquals(#result, 0)
end

-- 测试失败情况
function TestReleaseCommand:test_failure()
    local interface = {
        get_subcomp_upgrade_cnt = function() return nil end
    }

    local obj = {
        mcu = { Id = "FAIL001", Protocol = MCU_ENUMS.SMC_CHANNEL },
        interface = interface
    }

    local result = smc_firmware_status:get_update_details(
        { mcu_collection = { obj } }, { smc_ind_vrd_collection = {} }, "MCU")

    lu.assertEquals(#result, 0)
end