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

-- Description: test the external IPMI interfaces of sensor.
local log = require 'mc.logging'
local ipmi = require 'sensor.ipmi.ipmi'
local bs = require 'mc.bitstring'
local common = require 'test_sensor_common'

local ipmi_interface = {}
ipmi_interface.__index = ipmi_interface

function ipmi_interface.test_ipmi_set_pef_postpone(bus)
    log:info('== Testing set pef postpone timeout ...')

    -- ipmi command: 'ipmitool raw 0x04 0x11 <timeout>'
    local netfn = 0x04
    local cmd = 0x11

    local req = ipmi.SetPEFPostponeTimer.req.new(10)
    local payload = bs.new(ipmi.SetPEFPostponeTimer.decode):pack(req)
    local ok, ret = common.call_ipmi(bus, netfn, cmd, payload)
    assert(ok)
    local rsp = bs.new(ipmi.SetPEFPostponeTimer.encode):unpack(ret)
    assert(rsp.CompletionCode == 0x00, 'actual: ' .. rsp.CompletionCode)
    assert(rsp.Timeout == 10, 'actual: ' .. rsp.Timeout)
end

function ipmi_interface.test_ipmi_set_pef_last_event(bus)
    log:info('== Testing set pef last event ...')

    -- ipmi command: 'ipmitool raw 0x04 0x14 <bmc> <recordid>'
    local netfn = 0x04
    local cmd = 0x14

    local req = ipmi.SetPEFLastEventId.req.new(0, 0, 111)
    local payload = bs.new(ipmi.SetPEFLastEventId.decode):pack(req)
    local ok, ret = common.call_ipmi(bus, netfn, cmd, payload)
    assert(ok)
    local rsp = bs.new(ipmi.SetPEFLastEventId.encode):unpack(ret)
    assert(rsp.CompletionCode == 0x00, 'actual: ' .. rsp.CompletionCode)
end

function ipmi_interface.test_ipmi_get_pef_last_event(bus)
    log:info('== Testing get pef last event ...')

    -- ipmi command: 'ipmitool raw 0x04 0x15'
    local netfn = 0x04
    local cmd = 0x15

    local payload = ''
    local ok, ret = common.call_ipmi(bus, netfn, cmd, payload)
    assert(ok)
    local rsp = bs.new(ipmi.GetPEFLastEventId.encode):unpack(ret)
    assert(rsp.CompletionCode == 0x00, 'actual: ' .. rsp.CompletionCode)
    assert(rsp.SMSId == 111)
end

function ipmi_interface.test_ipmi_get_pef_capabitilies(bus)
    log:info('== Testing get pef capabilities ...')

    -- ipmi command: 'ipmitool raw 0x04 0x10'
    local netfn = 0x04
    local cmd = 0x10

    local payload = ''
    local ok, ret = common.call_ipmi(bus, netfn, cmd, payload)
    assert(ok)
    local rsp = bs.new(ipmi.GetPEFCapabilities.encode):unpack(ret)
    assert(rsp.CompletionCode == 0x00, 'actual: ' .. rsp.CompletionCode)
    assert(rsp.Alert == 0, 'actual: ' .. rsp.Alert)
    assert(rsp.Reset == 1, 'actual: ' .. rsp.Reset)
end

function ipmi_interface.test_ipmi_set_pef_parameters(bus)
    log:info('== Testing set pef parameters ...')

    -- ipmi command: 'ipmitool raw 0x04 0x12 <datas>'
    -- datas: <selector> <params>
    local netfn = 0x04
    local cmd = 0x12

    local sc = string.char
    local datas = {sc(0x01), sc(0x01)}
    local req = ipmi.SetPEFParameters.req.new(table.concat(datas, ''))
    local payload = bs.new(ipmi.SetPEFParameters.decode):pack(req)
    local ok, ret = common.call_ipmi(bus, netfn, cmd, payload)
    assert(ok)
    local rsp = bs.new(ipmi.SetPEFParameters.encode):unpack(ret)
    assert(rsp.CompletionCode == 0x00, 'actual: ' .. rsp.CompletionCode)
end

function ipmi_interface.test_ipmi_get_pef_parameters(bus)
    log:info('== Testing get pef parameters ...')

    -- ipmi command: 'ipmitool raw 0x04 0x13 <selector> <set_selector> <block_selector>'
    local netfn = 0x04
    local cmd = 0x13

    local req = ipmi.GetPEFParameters.req.new(1, 0, 1, 0)
    local payload = bs.new(ipmi.GetPEFParameters.decode):pack(req)
    local ok, ret = common.call_ipmi(bus, netfn, cmd, payload)
    assert(ok)
    local rsp = bs.new(ipmi.GetPEFParameters.encode):unpack(ret)
    assert(rsp.CompletionCode == 0x00, 'actual: ' .. rsp.CompletionCode)
    assert(rsp.Revision == 17, 'actual: ' .. rsp.Revision)
end

function ipmi_interface.test_entry(bus)
    log:info('================ test pef ipmi interface start ================')

    ipmi_interface.test_ipmi_set_pef_postpone(bus)
    ipmi_interface.test_ipmi_set_pef_last_event(bus)
    ipmi_interface.test_ipmi_get_pef_last_event(bus)
    ipmi_interface.test_ipmi_get_pef_capabitilies(bus)
    ipmi_interface.test_ipmi_set_pef_parameters(bus)
    ipmi_interface.test_ipmi_get_pef_parameters(bus)

    log:info('================ test pef ipmi interface complete ================')
end

return ipmi_interface