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

TestVrdChipService = {}

function TestVrdChipService:setUp()
    -- 存储测试实例引用用于闭包
    local test_self = self

    self.mock_mcu_service = {
        get_instance = function()
            return {
                vrd_info_changed = {
                    on = function(callback)
                        test_self.mcu_vrd_callback = callback
                    end
                }
            }
        end
    }

    self.mock_ind_vrd_service = {
        get_instance = function()
            return {
                vrd_info_changed = {
                    on = function(callback)
                        test_self.ind_vrd_callback = callback
                    end
                }
            }
        end
    }

    package.loaded['mc.singleton'] = function(class)
        return class
    end

    package.loaded['mc.logging'] = {
        notice = function(format, ...)
        end,
        info = function(format, ...)
        end
    }

    package.loaded['vrd.chip.vrd_chip_obj'] = {
        new = function(object, position)
            return {
                update_vrd_info = function(self, vrd_info)
                end
            }
        end
    }

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

    package.loaded['mcu.mcu_service'] = self.mock_mcu_service
    package.loaded['independent_vrd.ind_vrd_service'] = self.mock_ind_vrd_service

    package.loaded['vrd.chip.vrd_chip_service'] = nil

    -- 加载服务
    local vrd_chip_service = require 'vrd.chip.vrd_chip_service'
    self.service = vrd_chip_service.new()
end

function TestVrdChipService:test_init_registers_callbacks()
    self.service:init()

    lu.assertNotNil(self.mcu_vrd_callback)
    lu.assertNotNil(self.ind_vrd_callback)

    local mcu_is_valid = type(self.mcu_vrd_callback) == "function" or
        (type(self.mcu_vrd_callback) == "table" and self.mcu_vrd_callback.on ~= nil)
    local ind_is_valid = type(self.ind_vrd_callback) == "function" or
        (type(self.ind_vrd_callback) == "table" and self.ind_vrd_callback.on ~= nil)

    lu.assertTrue(mcu_is_valid)
    lu.assertTrue(ind_is_valid)

    lu.assertNotNil(self.service.vrd_chips)
    lu.assertNotNil(self.service.vrd_info)
end

function TestVrdChipService:test_mcu_vrd_info_callback()
    self.service:init()

    local test_vrd_info = {
        { id = "vrd1", name = "VRD1" },
        { id = "vrd2", name = "VRD2" }
    }

    if type(self.mcu_vrd_callback) == "function" then
        self.mcu_vrd_callback(test_vrd_info)
    elseif type(self.mcu_vrd_callback) == "table" and self.mcu_vrd_callback.on ~= nil then
        lu.assertTrue(true)
    else
        lu.fail("mcu_vrd_callback should be a function or signal object, got: " .. type(self.mcu_vrd_callback))
    end

    lu.assertTrue(true)
end

function TestVrdChipService:test_ind_vrd_info_callback()
    -- ind_vrd_service vrd_info_changed回调
    self.service:init()

    local test_vrd_info = {
        { id = "ind_vrd1", name = "IndVRD1" },
        { id = "ind_vrd2", name = "IndVRD2" }
    }

    if type(self.ind_vrd_callback) == "function" then
        self.ind_vrd_callback(test_vrd_info)
    elseif type(self.ind_vrd_callback) == "table" and self.ind_vrd_callback.on ~= nil then
        lu.assertTrue(true)
    else
        lu.fail("ind_vrd_callback should be a function or signal object, got: " .. type(self.ind_vrd_callback))
    end

    lu.assertTrue(true)
end

function TestVrdChipService:test_init_multiple_calls()
    -- 测试多次init调用不会导致问题
    self.service:init()
    local first_callback = self.mcu_vrd_callback

    self.service:init()
    local second_callback = self.mcu_vrd_callback

    lu.assertNotNil(first_callback)
    lu.assertNotNil(second_callback)
end

function TestVrdChipService:tearDown()
    package.loaded['mcu.mcu_service'] = nil
    package.loaded['independent_vrd.ind_vrd_service'] = nil
    package.loaded['vrd.chip.vrd_chip_service'] = nil
    package.loaded['mc.singleton'] = nil
    package.loaded['mc.logging'] = nil
    package.loaded['vrd.chip.vrd_chip_obj'] = nil
    package.loaded['common'] = nil
end
