-- 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 signal = require 'mc.signal'
local log = require 'mc.logging'
local utils = require 'mc.utils'
local vos = require 'utils.vos'
local file_sec = require 'utils.file'
local utils_core = require 'utils.core'
local log_collector = require 'device.class.log_collector'
local old_sig
local old_log
local old_utils
local old_vos
local old_file_sec
local old_utils_core
local old_log_collector

-- Mock dependencies
local mock_log = {
    notice = function(...) end,
    error = function(...) end,
    info = function(...) end
}

local mock_utils = {
    S_IRUSR = 256,
    S_IWUSR = 128,
    S_IRGRP = 32
}

local mock_vos = {
    get_file_accessible = function(path) return true end,
    check_before_system_s = function(...) return 0 end
}

local mock_file_sec = {
    open_s = function(path, mode)
        if string.find(path, 'fail') then
            return nil, 'mock error'
        end
        return {
            write = function(...) end,
            close = function() end
        }
    end,
    check_realpath_before_open_s = function(path)
        if string.find(path, 'illegal') then
            return -1
        end
        return 0
    end
}

local mock_utils_core = {
    chmod_s = function(...) end,
    is_dir = function(path)
        if string.find(path, 'nonexistent') then
            return false
        end
        return true
    end
}

local mock_log_collector = {
    create_dir = function(path)
        if string.find(path, 'fail_create') then
            return false
        end
        return true
    end
}

local mock_signal = {
    new = function()
        return {
            emit = function(...) end
        }
    end
}

-- Now require the module under test
local log_netcard_info = require 'device.class.log_netcard_info'

TEST_log_netcard_info = {}

function TEST_log_netcard_info:setUp()
    old_sig = signal
    signal = mock_signal
    old_log = log
    log = mock_log
    old_utils = utils
    utils = mock_utils
    old_vos = vos
    vos = mock_vos
    old_file_sec = file_sec
    file_sec = mock_file_sec
    old_utils_core = utils_core
    utils_core = mock_utils_core
    old_log_collector = log_collector
    log_collector = mock_log_collector  
end

function TEST_log_netcard_info:tearDown()
    signal = old_sig  
    log = old_log
    utils = old_utils
    vos = old_vos
    file_sec = old_file_sec
    utils_core = old_utils_core
    log_collector = old_log_collector  
end

function TEST_log_netcard_info:test_init()
    -- Test the init function
    log_netcard_info.init()
    
    -- Verify that the path is set correctly
    lu.assertEquals(log_netcard_info.net_card_info_path, '/var/log/netcard')
    
    -- Verify that the signal is created
    lu.assertNotNil(log_netcard_info.actual_mac_change_sig)
end

function TEST_log_netcard_info:test_collect_netcard_info_success()
    -- Initialize first
    log_netcard_info.init()
    
    -- Create mock network adapter collection
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1, -- Not virtual
                Name = 'Test Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            }
        },
        count = 1
    }
    
    -- Create mock network port collection
    local network_port_collection = {
        objects = {
            {
                NetworkAdapterId = 1,
                PortID = 1,
                BDF = '01:00.0',
                PermanentMACAddress = '00:11:22:33:44:55',
                MACAddress = '00:11:22:33:44:66',
                get_parent = function() return nil end
            }
        },
        count = 1,
        find = function(self, criteria)
            for _, obj in ipairs(self.objects) do
                if obj.NetworkAdapterId == criteria.ID then
                    return {
                        ID = criteria.ID,
                        NodeId = 1
                    }
                end
            end
            return nil
        end
    }
    
    -- Test successful collection
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    -- Should not throw any errors
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_collect_netcard_info_empty_collection()
    -- Initialize first
    log_netcard_info.init()
    
    -- Create empty collections
    local empty_network_adapter_collection = {
        objects = {},
        count = 0
    }
    
    local empty_network_port_collection = {
        objects = {},
        count = 0
    }
    
    -- Test with empty collections
    log_netcard_info.collect_netcard_info(empty_network_adapter_collection, empty_network_port_collection)
    
    -- Should not throw any errors
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_collect_netcard_info_nil_collection()
    -- Initialize first
    log_netcard_info.init()
    
    -- Create nil collections
    local nil_network_adapter_collection = {
        objects = nil,
        count = 0
    }
    
    local nil_network_port_collection = {
        objects = nil,
        count = 0
    }
    
    -- Test with nil collections
    log_netcard_info.collect_netcard_info(nil_network_adapter_collection, nil_network_port_collection)
    
    -- Should not throw any errors
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_collect_netcard_info_virtual_ports()
    -- Initialize first
    log_netcard_info.init()
    
    -- Create mock network adapter collection with virtual ports
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 6, -- Virtual port type
                Name = 'Virtual Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            },
            {
                ID = 2,
                NodeId = 1,
                Type = 7, -- Virtual port type
                Name = 'Virtual Adapter 2',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 2
            },
            {
                ID = 3,
                NodeId = 1,
                Type = 8, -- Virtual port type
                Name = 'Virtual Adapter 3',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 3
            }
        },
        count = 3
    }
    
    local network_port_collection = {
        objects = {},
        count = 0
    }
    
    -- Test with virtual ports (should be skipped)
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    -- Should not throw any errors
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_collect_netcard_info_mixed_ports()
    -- Initialize first
    log_netcard_info.init()
    
    -- Create mock network adapter collection with mixed port types
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1, -- Physical port
                Name = 'Physical Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            },
            {
                ID = 2,
                NodeId = 1,
                Type = 6, -- Virtual port (should be skipped)
                Name = 'Virtual Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 2
            }
        },
        count = 2
    }
    
    local network_port_collection = {
        objects = {
            {
                NetworkAdapterId = 1,
                PortID = 1,
                BDF = '01:00.0',
                PermanentMACAddress = '00:11:22:33:44:55',
                MACAddress = '00:11:22:33:44:66',
                get_parent = function() return nil end
            }
        },
        count = 1,
        find = function(self, criteria)
            return {
                ID = criteria.ID,
                NodeId = 1
            }
        end
    }
    
    -- Test with mixed port types
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    -- Should not throw any errors
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_collect_netcard_info_multiple_ports()
    -- Initialize first
    log_netcard_info.init()
    
    -- Create mock network adapter collection
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1,
                Name = 'Test Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            }
        },
        count = 1
    }
    
    -- Create mock network port collection with multiple ports
    local network_port_collection = {
        objects = {
            {
                NetworkAdapterId = 1,
                PortID = 2,
                BDF = '01:00.1',
                PermanentMACAddress = '00:11:22:33:44:77',
                MACAddress = '00:11:22:33:44:88',
                get_parent = function() return nil end
            },
            {
                NetworkAdapterId = 1,
                PortID = 1,
                BDF = '01:00.0',
                PermanentMACAddress = '00:11:22:33:44:55',
                MACAddress = '00:11:22:33:44:66',
                get_parent = function() return nil end
            }
        },
        count = 2,
        find = function(self, criteria)
            return {
                ID = criteria.ID,
                NodeId = 1
            }
        end
    }
    
    -- Test with multiple ports (should be sorted by PortID)
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    -- Should not throw any errors
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_collect_netcard_info_with_parent()
    -- Initialize first
    log_netcard_info.init()
    
    -- Create mock network adapter collection
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1,
                Name = 'Test Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            }
        },
        count = 1
    }
    
    -- Create mock network port collection with parent
    local network_port_collection = {
        objects = {
            {
                NetworkAdapterId = 1,
                PortID = 1,
                BDF = '01:00.0',
                PermanentMACAddress = '00:11:22:33:44:55',
                MACAddress = '00:11:22:33:44:66',
                get_parent = function() 
                    return {
                        ID = 1,
                        NodeId = 1
                    }
                end
            }
        },
        count = 1,
        find = function(self, criteria)
            return {
                ID = criteria.ID,
                NodeId = 1
            }
        end
    }
    
    -- Test with parent available
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    -- Should not throw any errors
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_collect_netcard_info_nil_values()
    -- Initialize first
    log_netcard_info.init()
    
    -- Create mock network adapter collection with nil values
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1,
                Name = nil,
                Manufacturer = nil,
                FirmwareVersion = nil,
                SlotNumber = nil
            }
        },
        count = 1
    }
    
    local network_port_collection = {
        objects = {},
        count = 0
    }
    
    -- Test with nil values
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    -- Should not throw any errors
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_collect_netcard_info_file_creation_failure()
    -- Initialize first
    log_netcard_info.init()
    
    -- Override the path to trigger directory creation failure
    log_netcard_info.net_card_info_path = '/var/log/fail_create'
    
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1,
                Name = 'Test Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            }
        },
        count = 1
    }
    
    local network_port_collection = {
        objects = {},
        count = 0
    }
    
    -- Test with directory creation failure
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    -- Should not throw any errors
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_collect_netcard_info_file_open_failure()
    -- Initialize first
    log_netcard_info.init()
    
    -- Override the path to trigger file open failure
    log_netcard_info.net_card_info_path = '/var/log/fail'
    
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1,
                Name = 'Test Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            }
        },
        count = 1
    }
    
    local network_port_collection = {
        objects = {},
        count = 0
    }
    
    -- Test with file open failure
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    -- Should not throw any errors
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_collect_netcard_info_busy_status()
    -- Initialize first
    log_netcard_info.init()
    
    -- Create a simple collection
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1,
                Name = 'Test Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            }
        },
        count = 1
    }
    
    local network_port_collection = {
        objects = {},
        count = 0
    }
    
    -- Simulate busy status by calling collect multiple times rapidly
    -- The first call should set status to busy, second call should detect busy status
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    -- Should not throw any errors
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_log_dump_cb_success()
    -- Initialize first
    log_netcard_info.init()
    
    local test_path = '/tmp/test_path'
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1,
                Name = 'Test Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            }
        },
        count = 1
    }
    
    local network_port_collection = {
        objects = {},
        count = 0
    }
    
    -- Test successful log dump callback
    log_netcard_info.log_dump_cb(test_path, network_adapter_collection, network_port_collection)
    
    -- Should not throw any errors
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_log_dump_cb_nonexistent_path()
    -- Initialize first
    log_netcard_info.init()
    
    local test_path = '/tmp/nonexistent_path'
    local network_adapter_collection = {
        objects = {},
        count = 0
    }
    
    local network_port_collection = {
        objects = {},
        count = 0
    }
    
    -- Test with nonexistent path
    log_netcard_info.log_dump_cb(test_path, network_adapter_collection, network_port_collection)
    
    -- Should not throw any errors
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_log_dump_cb_illegal_path()
    -- Initialize first
    log_netcard_info.init()
    
    local test_path = '/tmp/illegal_path'
    local network_adapter_collection = {
        objects = {},
        count = 0
    }
    
    local network_port_collection = {
        objects = {},
        count = 0
    }
    
    -- Test with illegal path
    log_netcard_info.log_dump_cb(test_path, network_adapter_collection, network_port_collection)
    
    -- Should not throw any errors
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_log_dump_cb_file_not_accessible()
    -- Initialize first
    log_netcard_info.init()
    
    -- Override mock to return false for file accessibility
    local original_get_file_accessible = mock_vos.get_file_accessible
    mock_vos.get_file_accessible = function(path) return false end
    
    local test_path = '/tmp/test_path'
    local network_adapter_collection = {
        objects = {},
        count = 0
    }
    
    local network_port_collection = {
        objects = {},
        count = 0
    }
    
    -- Test with file not accessible
    log_netcard_info.log_dump_cb(test_path, network_adapter_collection, network_port_collection)
    
    -- Restore original function
    mock_vos.get_file_accessible = original_get_file_accessible
    
    -- Should not throw any errors
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_error_handling_in_collect()
    -- Initialize first
    log_netcard_info.init()
    
    -- Create a collection that will cause an error in processing
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1,
                Name = 'Test Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            }
        },
        count = 1
    }
    
    -- Create a malformed port collection that might cause errors
    local network_port_collection = {
        objects = {
            {
                -- Missing required fields to test error handling
                NetworkAdapterId = 1,
                get_parent = function() 
                    error('Test error') -- Force an error
                end
            }
        },
        count = 1,
        find = function(self, criteria)
            return {
                ID = criteria.ID,
                NodeId = 1
            }
        end
    }
    
    -- Test error handling
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    -- Should not throw any errors (errors should be caught and logged)
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_time_format()
    -- Test that the time format function works
    -- We can't easily test the exact output without mocking os.time and os.date,
    -- but we can test that it doesn't crash
    
    -- This tests the get_time_utc function indirectly through collect_netcard_info
    log_netcard_info.init()
    
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1,
                Name = 'Test Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            }
        },
        count = 1
    }
    
    local network_port_collection = {
        objects = {},
        count = 0
    }
    
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_port_sorting()
    -- Test that ports are sorted correctly by PortID
    log_netcard_info.init()
    
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1,
                Name = 'Test Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            }
        },
        count = 1
    }
    
    -- Create ports with different PortIDs to test sorting
    local network_port_collection = {
        objects = {
            {
                NetworkAdapterId = 1,
                PortID = 3,
                BDF = '01:00.2',
                PermanentMACAddress = '00:11:22:33:44:99',
                MACAddress = '00:11:22:33:44:AA',
                get_parent = function() return nil end
            },
            {
                NetworkAdapterId = 1,
                PortID = 1,
                BDF = '01:00.0',
                PermanentMACAddress = '00:11:22:33:44:55',
                MACAddress = '00:11:22:33:44:66',
                get_parent = function() return nil end
            },
            {
                NetworkAdapterId = 1,
                PortID = 2,
                BDF = '01:00.1',
                PermanentMACAddress = '00:11:22:33:44:77',
                MACAddress = '00:11:22:33:44:88',
                get_parent = function() return nil end
            }
        },
        count = 3,
        find = function(self, criteria)
            return {
                ID = criteria.ID,
                NodeId = 1
            }
        end
    }
    
    -- Test port sorting
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_port_with_nil_port_id()
    -- Test handling of ports with nil PortID
    log_netcard_info.init()
    
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1,
                Name = 'Test Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            }
        },
        count = 1
    }
    
    local network_port_collection = {
        objects = {
            {
                NetworkAdapterId = 1,
                PortID = nil,
                BDF = '01:00.0',
                PermanentMACAddress = '00:11:22:33:44:55',
                MACAddress = '00:11:22:33:44:66',
                get_parent = function() return nil end
            }
        },
        count = 1,
        find = function(self, criteria)
            return {
                ID = criteria.ID,
                NodeId = 1
            }
        end
    }
    
    -- Test with nil PortID
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_is_virtual_port_edge_cases()
    -- Test the is_virtual_port function with edge cases
    log_netcard_info.init()
    
    -- Test with non-virtual port types
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1, -- Non-virtual
                Name = 'Physical Adapter 1',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            },
            {
                ID = 2,
                NodeId = 1,
                Type = 5, -- Non-virtual
                Name = 'Physical Adapter 2',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 2
            },
            {
                ID = 3,
                NodeId = 1,
                Type = 0, -- Edge case: zero type
                Name = 'Zero Type Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 3
            }
        },
        count = 3
    }
    
    local network_port_collection = {
        objects = {},
        count = 0
    }
    
    -- Test with various port types
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_port_parent_not_found()
    -- Test case where port parent is not found in collection
    log_netcard_info.init()
    
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1,
                Name = 'Test Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            }
        },
        count = 1
    }
    
    local network_port_collection = {
        objects = {
            {
                NetworkAdapterId = 999, -- Non-existent adapter ID
                PortID = 1,
                BDF = '01:00.0',
                PermanentMACAddress = '00:11:22:33:44:55',
                MACAddress = '00:11:22:33:44:66',
                get_parent = function() return nil end
            }
        },
        count = 1,
        find = function(self, criteria)
            -- Return nil to simulate parent not found
            return nil
        end
    }
    
    -- Test with parent not found
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_port_parent_id_mismatch()
    -- Test case where port parent ID doesn't match adapter
    log_netcard_info.init()
    
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1,
                Name = 'Test Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            }
        },
        count = 1
    }
    
    local network_port_collection = {
        objects = {
            {
                NetworkAdapterId = 1,
                PortID = 1,
                BDF = '01:00.0',
                PermanentMACAddress = '00:11:22:33:44:55',
                MACAddress = '00:11:22:33:44:66',
                get_parent = function() return nil end
            }
        },
        count = 1,
        find = function(self, criteria)
            -- Return parent with different ID/NodeId
            return {
                ID = 999,
                NodeId = 999
            }
        end
    }
    
    -- Test with parent ID mismatch
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_collect_twice_rapid_succession()
    -- Test calling collect twice in rapid succession to test busy status
    log_netcard_info.init()
    
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1,
                Name = 'Test Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            }
        },
        count = 1
    }
    
    local network_port_collection = {
        objects = {},
        count = 0
    }
    
    -- First call should succeed
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    -- Second call should also succeed (since the first one completed quickly)
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_get_time_utc_format()
    -- Test the time format by mocking os functions
    local original_os_time = os.time
    local original_os_date = os.date
    
    -- Mock os.time and os.date
    os.time = function() return 1640995200 end -- Fixed timestamp
    os.date = function(format, timestamp) 
        if format == "%Y-%m-%d %H:%M:%S UTC" and timestamp == 1640995200 then
            return "2022-01-01 00:00:00 UTC"
        end
        return original_os_date(format, timestamp)
    end
    
    -- Initialize and test
    log_netcard_info.init()
    
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1,
                Name = 'Test Adapter',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            }
        },
        count = 1
    }
    
    local network_port_collection = {
        objects = {},
        count = 0
    }
    
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    -- Restore original functions
    os.time = original_os_time
    os.date = original_os_date
    
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_multiple_adapters_different_node_ids()
    -- Test with multiple adapters having different NodeIds
    log_netcard_info.init()
    
    local network_adapter_collection = {
        objects = {
            {
                ID = 1,
                NodeId = 1,
                Type = 1,
                Name = 'Test Adapter 1',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '1.0.0',
                SlotNumber = 1
            },
            {
                ID = 2,
                NodeId = 2,
                Type = 1,
                Name = 'Test Adapter 2',
                Manufacturer = 'Test Manufacturer',
                FirmwareVersion = '2.0.0',
                SlotNumber = 2
            }
        },
        count = 2
    }
    
    local network_port_collection = {
        objects = {
            {
                NetworkAdapterId = 1,
                PortID = 1,
                BDF = '01:00.0',
                PermanentMACAddress = '00:11:22:33:44:55',
                MACAddress = '00:11:22:33:44:66',
                get_parent = function() return nil end
            },
            {
                NetworkAdapterId = 2,
                PortID = 1,
                BDF = '02:00.0',
                PermanentMACAddress = '00:11:22:33:44:77',
                MACAddress = '00:11:22:33:44:88',
                get_parent = function() return nil end
            }
        },
        count = 2,
        find = function(self, criteria)
            if criteria.ID == 1 then
                return { ID = 1, NodeId = 1 }
            elseif criteria.ID == 2 then
                return { ID = 2, NodeId = 2 }
            end
            return nil
        end
    }
    
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    lu.assertTrue(true)
end

function TEST_log_netcard_info:test_large_dataset()
    -- Test with a larger dataset to ensure performance
    log_netcard_info.init()
    
    local adapters = {}
    local ports = {}
    
    -- Create 10 adapters with 4 ports each
    for i = 1, 10 do
        table.insert(adapters, {
            ID = i,
            NodeId = 1,
            Type = 1,
            Name = 'Test Adapter ' .. i,
            Manufacturer = 'Test Manufacturer ' .. i,
            FirmwareVersion = '1.0.' .. i,
            SlotNumber = i
        })
        
        for j = 1, 4 do
            table.insert(ports, {
                NetworkAdapterId = i,
                PortID = j,
                BDF = string.format('%02d:00.%d', i, j-1),
                PermanentMACAddress = string.format('00:11:22:33:44:%02X', i*4+j),
                MACAddress = string.format('00:11:22:33:55:%02X', i*4+j),
                get_parent = function() return nil end
            })
        end
    end
    
    local network_adapter_collection = {
        objects = adapters,
        count = #adapters
    }
    
    local network_port_collection = {
        objects = ports,
        count = #ports,
        find = function(self, criteria)
            return {
                ID = criteria.ID,
                NodeId = 1
            }
        end
    }
    
    log_netcard_info.collect_netcard_info(network_adapter_collection, network_port_collection)
    
    lu.assertTrue(true)
end

return TEST_log_netcard_info