-- 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'

TestIndVrdService = {}

function TestIndVrdService:setUp()
    self.mock_signal = {
        new = function()
            return {
                on = function() end
            }
        end
    }

    self.mock_upgrade_subject = {
        get_instance = function()
            return {
                register_upgrade_observer = function() end,
                register_active_observer = function() end
            }
        end
    }

    self.mock_vrd_upgrade = {
        new = function(bus, db, collection)
            return {
                test = "upgrade_obj"
            }
        end
    }

    self.mock_chip_obj = {
        new = function(params, position, signal)
            return {
                register_firmware_info = function() end,
                test_params = params,
                test_position = position
            }
        end
    }

    package.loaded['mc.signal'] = self.mock_signal
    package.loaded['upgrade_subject.upgrade_subject'] = self.mock_upgrade_subject
    package.loaded['independent_vrd.chip.vrd_upgrade'] = self.mock_vrd_upgrade
    package.loaded['independent_vrd.chip.mp2882'] = self.mock_chip_obj
    package.loaded['independent_vrd.chip.test_chip'] = self.mock_chip_obj

    package.loaded['common'] = {
        remove_ele_by_position = function(collection, position)
        end
    }

    package.loaded['independent_vrd.ind_vrd_service'] = nil

    -- 加载服务
    local ind_vrd_service = require 'independent_vrd.ind_vrd_service'
    self.service = ind_vrd_service.new()
end

function TestIndVrdService:test_on_add_object_vrd_firmware_valid_chip()
    local mock_object = {
        ChipType = "MP2882",
        BoardType = "TestBoard",
        RefChip = "test_ref",
        UID = "test-uid",
        SoftwareId = "test-sw-id"
    }

    local register_called = false
    local inserted_obj = nil

    self.mock_chip_obj.new = function(params, position, signal)
        return {
            register_firmware_info = function(bus)
                register_called = true
            end,
            test_params = params,
            test_position = position
        }
    end

    local original_insert = table.insert
    table.insert = function(t, obj)
        inserted_obj = obj
        original_insert(t, obj)
    end

    self.service:on_add_object("VRDFirmware", mock_object, 1)

    table.insert = original_insert
    table.insert = original_insert

    lu.assertTrue(register_called)
    lu.assertNotNil(inserted_obj)
    lu.assertEquals(#self.service.ind_vrd_collection, 1)
end

function TestIndVrdService:test_on_add_object_invalid_chip_type()
    local mock_object = {
        ChipType = "INVALID_CHIP",
        BoardType = "TestBoard",
        RefChip = "test_ref",
        UID = "test-uid",
        SoftwareId = "test-sw-id"
    }

    package.loaded['independent_vrd.chip.invalid_chip'] = nil

    self.service:on_add_object("VRDFirmware", mock_object, 1)

    lu.assertEquals(#self.service.ind_vrd_collection, 0)
end

function TestIndVrdService:test_on_add_object_non_vrd_firmware()
    -- 测试class_name不是VRDFirmware的情况
    local mock_object = {
        ChipType = "MP2882",
        BoardType = "TestBoard"
    }

    self.service:on_add_object("OTHER_CLASS", mock_object, 1)

    lu.assertEquals(#self.service.ind_vrd_collection, 0)
end

function TestIndVrdService:test_on_delete_object_vrd_firmware()
    local remove_called = false
    local removed_position = nil

    package.loaded['common'].remove_ele_by_position = function(collection, position)
        remove_called = true
        removed_position = position
    end

    local mock_object = {
        ChipType = "MP2882",
        BoardType = "TestBoard"
    }

    self.service:on_delete_object("VRDFirmware", mock_object, 5)

    lu.assertTrue(remove_called)
    lu.assertEquals(removed_position, 5)
end

function TestIndVrdService:test_on_delete_object_non_vrd_firmware()
    local remove_called = false

    package.loaded['common'].remove_ele_by_position = function(collection, position)
        remove_called = true
    end

    local mock_object = {
        ChipType = "MP2882",
        BoardType = "TestBoard"
    }

    self.service:on_delete_object("OTHER_CLASS", mock_object, 5)

    lu.assertFalse(remove_called)
end

function TestIndVrdService:tearDown()
    package.loaded['mc.signal'] = nil
    package.loaded['upgrade_subject.upgrade_subject'] = nil
    package.loaded['independent_vrd.chip.vrd_upgrade'] = nil
    package.loaded['independent_vrd.chip.mp2882'] = nil
    package.loaded['independent_vrd.chip.test_chip'] = nil
    package.loaded['common'] = nil
    package.loaded['independent_vrd.ind_vrd_service'] = nil
end
