-- 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 class = require 'mc.class'
local parser = require 'libmgmt_protocol'
local utils = require 'mc.utils'
local log = require 'mc.logging'
local lu = require 'luaunit'
local config_file = require 'test_data.test_netcard_data'

local TestNetcard = class()

local function pack(obj)
    local result = ''
    for _, v in ipairs(obj) do
        result = result .. v
    end
    return result
end

local expect_called_and_return<const> = {
    {
        Write = {
            0, pack({
                '\x00\x00', -- lun
                '\x04\x04', -- opcode
                '\x00\x00\x00\x00', -- offset
                '\x30\x00\x00\x00', -- length
                '\x1e\xa1\x83\x2c' -- crc32
            })
        },
        Read = pack({
            '\x00\x00', -- error_code
            '\x04\x04', -- opcode
            '\x24\x00\x00\x00', -- total_length
            '\x24\x00\x00\x00', -- length
            '\x00\x00\x00\x04\x8C\x16\x59\xC8\x6D' .. -- data
            '\x01\x00\x01\x04\x8C\x16\x59\xC8\x6E' .. '\x02\x00\x02\x04\x8C\x16\x59\xC8\x6F' ..
                '\x03\x00\x03\x04\x8C\x16\x59\xC8\x70', string.rep('\x00', 12), -- fill
            '\x74\x51\xB0\x1E' -- crc32
        })
    }, {
        Write = {
            0, pack({
                '\x00\x00', -- lun
                '\x03\x00', -- opcode
                '\x00\x00\x00\x00', -- offset
                '\x02\x00\x00\x00', -- length
                '\x38\x2A\x95\xC6' -- crc32
            })
        },
        Read = pack({
            '\x00\x00', -- error_code
            '\x03\x00', -- opcode
            '\x02\x00\x00\x00', -- total_length
            '\x02\x00\x00\x00', -- length
            '\x2F\x00', '\x72\x96\x70\x59', -- crc32
            string.rep('\xFF', 46) -- fill
        })
    }
}

function TestNetcard:test_mac_address()
    log:info('-------------------test get mac address start-------------------')

    local expect_mac_addr<const> = {
        mac_addr = {
            {port = 0, PF_VF = 0, addr = '04:8C:16:59:C8:6D'},
            {port = 1, PF_VF = 0x100, addr = '04:8C:16:59:C8:6E'},
            {port = 2, PF_VF = 0x200, addr = '04:8C:16:59:C8:6F'},
            {port = 3, PF_VF = 0x300, addr = '04:8C:16:59:C8:70'}
        }
    }

    local mac_addr = self.obj:MacAddr()
    lu.assertNotNil(mac_addr)

    for i, addr in ipairs(mac_addr) do
        lu.assertEquals(addr.port, expect_mac_addr.mac_addr[i].port)
        lu.assertEquals(addr.PF_VF, expect_mac_addr.mac_addr[i].PF_VF)
        lu.assertEquals(addr.addr, expect_mac_addr.mac_addr[i].addr)
    end

    log:info('-------------------test get mac address end-------------------')
end

function TestNetcard:test_chip_temp()
    log:info('-------------------test get chip temperature start-------------------')

    local chip_temp = self.obj:ChipTemp()
    lu.assertNotNil(chip_temp)

    lu.assertEquals(chip_temp:get(), 0x2F)

    chip_temp:deconstruct()

    log:info('-------------------test get chip temperature end-------------------')
end
local expect_call_count = {}
function TestNetcard:ctor()
    config_file.protocol_dependencies.smbus.ref_chip = {
        WriteRead = function(chip, _, ...)
            for i, expect in ipairs(expect_called_and_return) do
                if utils.table_compare({...}, expect.Write) then
                    expect_call_count[i] = (expect_call_count[i] or 0) + 1
                    return expect.Read
                end
            end
            assert(false, 'no matched call')
        end

    }
    self.obj = parser.device_spec_parser(config_file)
    lu.assertNotNil(self.obj)
end

return TestNetcard
