-- 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 hardware_config = require 'hardware_config.CTCloud11JA4'
local skynet = require 'skynet'

TEST_oem_smbus_network_adapter_CTCloud11JA4 = {}

local chip_data = {
    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
    '\xAE','\xBC','\xCF','\x1A','\x25','\x01','\xAC','\x1C','\xCD','\x15','\x25','\x02','\xff','\xff','\xff','\xff',
    '\x12','\xBE','\xC2','\x34','\x2E','\x01','\xA2','\x1B','\xEF','\x31','\x67','\x02','\xff','\xff','\xff','\xff',
}

local chip = {
    WriteRead = true,
    Read = function(self, ctx, read_offset, read_len)
        local rsp_data = {}
        for i = read_offset + 1, read_offset + read_len do
            rsp_data[#rsp_data + 1] = chip_data[i]
        end
        return table.concat(rsp_data)
    end
}

local function deepCopy(origin, seen)
    seen = seen or {}

    if seen[origin] then
        return seen[origin]
    end

    local copy
    if type(origin) == 'table' then
        copy = {}
        seen[origin] = copy

        for orig_key, orig_value in pairs(origin) do
            copy[deepCopy(orig_key, seen)] = deepCopy(orig_value, seen)
        end

        setmetatable(copy, deepCopy(getmetatable(origin), seen))
    else
        copy = origin
    end

    return copy
end

local adapter_origin = require 'device.class.network_adapter'
local adapter

function TEST_oem_smbus_network_adapter_CTCloud11JA4:setUp()
    self.position = '0001010104123'
    self.uuid = 'testuid'
    self.port_count = 4

    adapter = deepCopy(adapter_origin)
    adapter.BoardID = 32786
    adapter.DeviceLocator = 'some locator'
    adapter.Name = "Zijin-DPU2.5"
    adapter.Position = '0001010104123'
    adapter.Model = "CTCloud11JA4"
    adapter.VendorID = "0x1af4"
    adapter.DeviceID = "0x1041"
    adapter.NetworkPortCount = 4
    adapter.SupportedLLDP = false
    adapter.RefChip = chip
end

function TEST_oem_smbus_network_adapter_CTCloud11JA4:InitRefChip(input)
    input.oem_smbus_config_obj = hardware_config.oem_smbus:new(input.RefChip)
    input.oem_smbus_config_obj.chip = chip
    hardware_config.chip = chip
end

function TEST_oem_smbus_network_adapter_CTCloud11JA4:tearDown()
    adapter = nil
end

local function create_port(port_origin, op_origin, port_id)
    local port = deepCopy(port_origin)
    local op = deepCopy(op_origin)
    port.PortID = port_id
    port.t_port_prop_without_bma = {}
    op.PortID = port_id
    port.get_optical_module = function ()
        return op
    end
    return port, op
end

function TEST_oem_smbus_network_adapter_CTCloud11JA4:test_can_get_ports_info_power_on()
    skynet.sleep(3000)
    adapter.RefChip = chip
    self:InitRefChip(adapter)
    local port_origin = require 'device.class.network_port'
    local op_origin = require 'device.class.optical_module'
    local port0 = create_port(port_origin, op_origin, 0)
    local port1 = create_port(port_origin, op_origin, 1)
    local port2 = create_port(port_origin, op_origin, 2)
    local port3 = create_port(port_origin, op_origin, 3)

    local ports = {port0, port1, port2, port3}
    adapter:update_oem_smbus_port_properties_power_on(ports)

    lu.assertEquals(port0.MACAddress, 'AE:BC:CF:1A:25:01')
    lu.assertEquals(port0.PermanentMACAddress, 'AE:BC:CF:1A:25:01')

    lu.assertEquals(port1.MACAddress, 'AC:1C:CD:15:25:02')
    lu.assertEquals(port1.PermanentMACAddress, 'AC:1C:CD:15:25:02')

    lu.assertEquals(port2.MACAddress, '12:BE:C2:34:2E:01')
    lu.assertEquals(port2.PermanentMACAddress, '12:BE:C2:34:2E:01')

    lu.assertEquals(port3.MACAddress, 'A2:1B:EF:31:67:02')
    lu.assertEquals(port3.PermanentMACAddress, 'A2:1B:EF:31:67:02')
end