-- 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 bs = require 'mc.bitstring'
local ipmi = require 'ipmi'
require 'ipmi'
local context = require 'mc.context'
local lu = require 'luaunit'
local comp_code = ipmi.types.Cc
local log = require 'mc.logging'

local test_ipmi = {}

-- 测试发送ipmi命令
local function send_ipmi_cmd(bus, ipmi_req)
    ipmi_req.Payload = ipmi_req.Payload .. '\x00'
    local ipmi_package = bs.new('<<_,_:2,DestNetFn:6,_:3/unit:8,Cmd,Payload/string>>')
    local req = ipmi_package:pack(ipmi_req)
    -- ctx打桩
    local channel_type = require 'ipmi.enums'.ChannelType
    local cjson = require 'cjson'
    local ctx = cjson.encode({
        ChanType = channel_type.CT_ME:value(),
        Instance = 0,
        session = {
            user = {
                name = 'test'
            }
        },
        from = '\x11\x11\x11\x4B\xFF\x14\xB5' -- 前三个字节是端口, 后四个字节是ip地址
    })
    local rsp = bus:call('bmc.kepler.ipmi_core', '/bmc/kepler/IpmiCore',
        'bmc.kepler.IpmiCore', 'Route', 'a{ss}ayay', require 'mc.context'.new(), req, ctx)
    return rsp
end

function test_ipmi.test_get_device(bus)
    -- Devices长度非法(0)
    local req = {DestNetFn = 0x30, Cmd = 0x92, Payload = '\xdb\x07\x00\x4E\x00\x00\x00\x00'}
    local resp = send_ipmi_cmd(bus, req)
    local completion_code = string.unpack('B', resp)
    lu.assertEquals(completion_code, comp_code.ReqDataLenInvalid)

    -- DeviceNum不等于Devices长度
    req = {DestNetFn = 0x30, Cmd = 0x92, Payload = '\xdb\x07\x00\x4E\x01\x00\x00\x00\x01\x02'}
    resp = send_ipmi_cmd(bus, req)
    completion_code = string.unpack('B', resp)
    lu.assertEquals(completion_code, comp_code.InvalidFieldRequest)

    -- Devices字段非法
    req = {DestNetFn = 0x30, Cmd = 0x92, Payload = '\xdb\x07\x00\x4E\x02\x02\x00\x00\x00\x02'}
    resp = send_ipmi_cmd(bus, req)
    completion_code = string.unpack('B', resp)
    lu.assertEquals(completion_code, comp_code.InvalidFieldRequest)

    -- Devices字段合法
    req = {DestNetFn = 0x30, Cmd = 0x92, Payload = '\xdb\x07\x00\x4E\x02\x02\x00\x00\x01\x02'}
    resp = send_ipmi_cmd(bus, req)
    completion_code = string.unpack('B', resp)
    lu.assertEquals(completion_code, comp_code.Success)

    -- Devices字段合法
    req = {DestNetFn = 0x30, Cmd = 0x92, Payload = '\xdb\x07\x00\x4E\x02\x02\x00\x00\x01\x0D'}
    resp = send_ipmi_cmd(bus, req)
    completion_code = string.unpack('B', resp)
    lu.assertEquals(completion_code, comp_code.Success)

    -- 获取所有Devices字段
    req = {DestNetFn = 0x30, Cmd = 0x92, Payload = '\xdb\x07\x00\x4E\xff\x00\x00\x00\x00'}
    resp = send_ipmi_cmd(bus, req)
    completion_code = string.unpack('B', resp)
    lu.assertEquals(completion_code, comp_code.Success)
end

function test_ipmi.test_chassis_identify(bus)
    -- 参数数量过多
    local req = {DestNetFn = 0x00, Cmd = 0x04, Payload = '\x01\x01\x01'}
    local resp = send_ipmi_cmd(bus, req)
    local completion_code = string.unpack('B', resp)
    lu.assertEquals(completion_code, ipmi.types.Cc.UnspecifiedError)
    -- 1个参数
    req = {DestNetFn = 0x00, Cmd = 0x04, Payload = '\x01'}
    resp = send_ipmi_cmd(bus, req)
    completion_code = string.unpack('B', resp)
    lu.assertEquals(completion_code, ipmi.types.Cc.UnspecifiedError)
    -- 2个参数
    req = {DestNetFn = 0x00, Cmd = 0x04, Payload = '\x01\x01'}
    resp = send_ipmi_cmd(bus, req)
    completion_code = string.unpack('B', resp)
    lu.assertEquals(completion_code, ipmi.types.Cc.UnspecifiedError)
end

function test_ipmi.test_get_superpod_label_info(bus)
    local req = {DestNetFn = 0x30, Cmd = 0x94, Payload = '\xdb\x07\x00\x6A\x04\x00\x00\x00\x08'}
    local resp = send_ipmi_cmd(bus, req)
    local completion_code, manufacture_id, end_flag, data = string.unpack('BI3BI8', resp)
    lu.assertEquals(completion_code, ipmi.types.Cc.Success)
    lu.assertEquals(manufacture_id, 0x0007db)
    lu.assertEquals(end_flag, 0)
    lu.assertEquals(data, 0x0180FFFFFFFFFFFF)
end
 
 
function test_ipmi.test_set_superpod_label_info(bus)
    -- 设置三个属性都为1
    local req = {
        DestNetFn = 0x30,
        Cmd = 0x94,
        Payload = '\xdb\x07\x00\x6B\x04\x00\x00\x00\x00\x09\x00\x01\x00\x00\x00\x01\x00\x01\x00'
    }
    local resp = send_ipmi_cmd(bus, req)
    local completion_code = string.unpack('B', resp)
    lu.assertEquals(completion_code, ipmi.types.Cc.Success)
    -- 长度异常
    req = {
        DestNetFn = 0x30,
        Cmd = 0x94,
        Payload = '\xdb\x07\x00\x6B\x04\x00\x00\x00\x00\x0A\x00\x01\x00\x00\x00\x01\x00\x01\x00\x00'
    }
    local resp = send_ipmi_cmd(bus, req)
    local completion_code = string.unpack('B', resp)
    lu.assertEquals(completion_code, ipmi.types.Cc.InvalidCommand)
    -- 设置SuperPodId为2
    req = {DestNetFn = 0x30, Cmd = 0x94, Payload = '\xdb\x07\x00\x6B\x04\x00\x00\x00\x00\x05\x01\x02\x00\x00\x00'}
    resp = send_ipmi_cmd(bus, req)
    completion_code = string.unpack('B', resp)
    lu.assertEquals(completion_code, ipmi.types.Cc.Success)
    -- 设置ServerIndex为2
    req = {DestNetFn = 0x30, Cmd = 0x94, Payload = '\xdb\x07\x00\x6B\x04\x00\x00\x00\x00\x03\x02\x02\x00'}
    resp = send_ipmi_cmd(bus, req)
    completion_code = string.unpack('B', resp)
    lu.assertEquals(completion_code, ipmi.types.Cc.Success)
    -- 设置SuperPodSize为2
    req = {DestNetFn = 0x30, Cmd = 0x94, Payload = '\xdb\x07\x00\x6B\x04\x00\x00\x00\x00\x03\x03\x02\x00'}
    resp = send_ipmi_cmd(bus, req)
    completion_code = string.unpack('B', resp)
    lu.assertEquals(completion_code, ipmi.types.Cc.Success)
    -- 长度异常
    req = {DestNetFn = 0x30, Cmd = 0x94, Payload = '\xdb\x07\x00\x6B\x04\x00\x00\x00\x00\x04\x03\x00\xff\x00'}
    resp = send_ipmi_cmd(bus, req)
    completion_code = string.unpack('B', resp)
    lu.assertEquals(completion_code, ipmi.types.Cc.InvalidCommand)
    -- 设置SuperPodSize为0xffff
    req = {DestNetFn = 0x30, Cmd = 0x94, Payload = '\xdb\x07\x00\x6B\x04\x00\x00\x00\x00\x03\x03\xff\xff'}
    resp = send_ipmi_cmd(bus, req)
    completion_code = string.unpack('B', resp)
    lu.assertEquals(completion_code, ipmi.types.Cc.ParmOutOfRange)
end
 

function test_ipmi.main(bus)
    log:info('================ test device capabilities start ================')
    test_ipmi.test_get_superpod_label_info(bus)
    test_ipmi.test_get_device(bus)
    test_ipmi.test_chassis_identify(bus)
    log:info('================ test device capabilities end ================')
end

return test_ipmi