-- 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 smbios_service = require 'service.smbios_service'
local bios_service = require 'service.bios_service'
local bios_enum = require 'bios.types.enums'
local bios_factory = require 'factory.bios_factory'
local test_common = require 'test_common.utils'
local bus = test_common.dbus_launch('../.dbus', nil, true)

TestSmbiosWriteData = {}

function TestSmbiosWriteData:test_bean()
    local smbios_ser = smbios_service.new()
    local bios_ser = bios_service.new(bus, {})

    bios_factory.register_bean('bios_service', bios_ser)
    bios_factory.register_bean('smbios_service', smbios_ser)

    smbios_ser:set_smbios_prop('FileName', '../test_data/SMBIOS_CONF')
    smbios_ser:set_smbios_prop('DiffFileName', '../test_data/SMBIOS_DIFF')

    assert(smbios_ser ~= nil)
    assert(bios_ser ~= nil)
end

function TestSmbiosWriteData:test_z_clear()
    local smbios_ser = smbios_service.get_instance(bus)

    os.execute('rm -rf ../test_data/SMBIOS_CONF')
    os.execute('rm -rf ../test_data/SMBIOS_DIFF')

    smbios_ser:set_smbios_prop('FileName', '/data/opt/SMBIOS_CONF')
    smbios_ser:set_smbios_prop('DiffFileName', '/data/opt/SMBIOS_DIFF')
end

function TestSmbiosWriteData:test_judge_req()
    local req = nil
    local ctx = {ChanType = 'CT_ME'}

    local data = smbios_service.judge_req(req, ctx)

    assert(data ~= nil)
    assert(data.CompletionCode == bios_enum.SmbiosErrCode.SMBIOS_ERR_INVALID_FIELD:value())

    local req = {ManufactureId = 0}
    local data = smbios_service.judge_req(req, ctx)
    assert(data ~= nil)
    assert(data.CompletionCode == bios_enum.SmbiosErrCode.SMBIOS_ERR_IV_LEN:value())

    local req = {ManufactureId = 1, BiosId = 2, Operation = 3}
    local data = smbios_service.judge_req(req, ctx)
    assert(data == nil)
end

function TestSmbiosWriteData:test_judge_manu_id_valid()
    local req = {
        ManufactureId = 0,
        BiosId = 2,
        Operation = 3,
        DataChecksum = 4,
        OffsetToWrite = 5,
        data = 6
    }

    local err_code = smbios_service.judge_manu_id_valid(req, nil)
    assert(err_code == -1)

    local err_code = smbios_service.judge_manu_id_valid(req, 1)
    assert(err_code == -1)

    local err_code = smbios_service.judge_manu_id_valid(req, 0)
    assert(err_code == 1)
end

function TestSmbiosWriteData:test_judge_bios_id()
    local req = {
        ManufactureId = 0,
        BiosId = 1,
        Operation = 3,
        DataChecksum = 4,
        OffsetToWrite = 5,
        data = 6
    }
    local ctx = {ChanType = 'CT_ME'}

    local data = smbios_service.judge_bios_id(req, ctx, 0, 0)

    assert(data ~= nil)
    assert(data.CompletionCode == bios_enum.SmbiosErrCode.SMBIOS_ERR_INVALID_STATUS:value())

    local data = smbios_service.judge_bios_id(req, ctx, 2, 0)
    assert(data == nil)
end

function TestSmbiosWriteData:test_validate()
    local req = {
        ManufactureId = 0xDB0700,
        BiosId = 0,
        Operation = 3,
        DataChecksum = 4,
        OffsetToWrite = 5,
        data = 6
    }
    local ctx = {ChanType = 'CT_ME'}

    local data = smbios_service.validate(req, ctx, 0, 0xDB0700)
    assert(data == nil)

    local req = {
        ManufactureId = 0,
        BiosId = 1,
        Operation = 3,
        DataChecksum = 4,
        OffsetToWrite = 5,
        data = 6
    }

    local data = smbios_service.validate(req, ctx, 0, 0)

    assert(data ~= nil)
    assert(data.CompletionCode == bios_enum.SmbiosErrCode.SMBIOS_ERR_INVALID_STATUS:value())

    local req = {
        ManufactureId = 0,
        BiosId = 2,
        Operation = 3,
        DataChecksum = 4,
        OffsetToWrite = 5,
        data = 6
    }

    local data = smbios_service.validate(req, ctx, 0, 0)

    assert(data ~= nil)
    assert(data.CompletionCode == bios_enum.SmbiosErrCode.SMBIOS_ERR_INVALID_STATUS:value())

    local req = nil

    local data = smbios_service.validate(req, ctx, 0, 0)

    assert(data ~= nil)
    assert(data.CompletionCode == bios_enum.SmbiosErrCode.SMBIOS_ERR_INVALID_FIELD:value())
end

function TestSmbiosWriteData:test_default_write()
    local smbios_ser = smbios_service.new()

    local data = smbios_ser:default_write()
    assert(data ~= nil)
    assert(data.CompletionCode == bios_enum.SmbiosErrCode.SMBIOS_ERR_INVALID_STATUS:value())
    assert(data.ManufactureId == 0x0007DB)
    assert(data.RequiredOffset == '')
end

function TestSmbiosWriteData:test_get_manu_id()
    local smbios_ser = smbios_service.new()

    local data = smbios_ser:get_manu_id()
    assert(data ~= nil)
    assert(data == 0x0007DB)
end

function TestSmbiosWriteData:test_get_bios_id()
    local smbios_ser = smbios_service.new()

    local data = smbios_ser:get_bios_id()
    assert(data ~= nil)
    assert(data == 0)
end

function TestSmbiosWriteData:test_smbios_write_prepare()
    local smbios_ser = smbios_service.new()
    local req = nil
    local ctx = {ChanType = 'CT_ME'}

    local data = smbios_ser:smbios_write_prepare(req, ctx)
    assert(data ~= nil)
    assert(data.CompletionCode == bios_enum.SmbiosErrCode.SMBIOS_ERR_INVALID_FIELD:value())
    assert(data.ManufactureId == 0x0007DB)
    assert(data.RequiredOffset == '')

    local req = {ManufactureId = 0, BiosId = 1, Operation = 3}
    local data = smbios_ser:smbios_write_prepare(req, ctx)
    assert(data ~= nil)
    assert(data.CompletionCode == bios_enum.SmbiosErrCode.SMBIOS_ERR_NORMALLY:value())
    assert(data.ManufactureId == 0x0007DB)
    assert(data.RequiredOffset == '')
end

function TestSmbiosWriteData:test_write_data()
    local smbios_ser = smbios_service.new()

    local info = {DataChecksum = 4, OffsetToWrite = 5, FileData = '6'}
    local ctx = {ChanType = 'CT_ME'}

    local data = smbios_ser:write_data(ctx, info)
    assert(data ~= nil)
    assert(data.CompletionCode == bios_enum.SmbiosErrCode.SMBIOS_ERR_WRONG_OFFSET:value())
    assert(data.ManufactureId == 0x0007DB)
    assert(data.RequiredOffset == '0')

    local info = {DataChecksum = 4, OffsetToWrite = 0, FileData = ''}
    local ctx = {ChanType = 'CT_ME'}

    local data = smbios_ser:write_data(ctx, info)
    assert(data ~= nil)
    assert(data.CompletionCode == bios_enum.SmbiosErrCode.SMBIOS_ERR_IV_LEN:value())
    assert(data.ManufactureId == 0x0007DB)
    assert(data.RequiredOffset == '')

    local info = {DataChecksum = 0, OffsetToWrite = 0, FileData = '0'}
    local ctx = {ChanType = 'CT_ME'}

    local data = smbios_ser:write_data(ctx, info)
    assert(data ~= nil)
    assert(data.CompletionCode == bios_enum.SmbiosErrCode.SMBIOS_ERR_INVALID_CHKSUM:value())
    assert(data.ManufactureId == 0x0007DB)
    assert(data.RequiredOffset == '')

    local info = {DataChecksum = 48, OffsetToWrite = 0, FileData = '0'}
    local ctx = {ChanType = 'CT_ME'}

    local data = smbios_ser:write_data(ctx, info)
    assert(data ~= nil)
    assert(data.CompletionCode == bios_enum.SmbiosErrCode.SMBIOS_ERR_NORMALLY:value())
    assert(data.ManufactureId == 0x0007DB)
    assert(data.RequiredOffset == '')
end

function TestSmbiosWriteData:test_smbios_write_data()
    local smbios_ser = smbios_service.new()
    local req = {ManufactureId = 0, BiosId = 2, Operation = 3, Srcdata = '1234'}
    local ctx = {ChanType = 'CT_ME'}

    local data = smbios_ser:smbios_write_data(req, ctx)
    assert(data ~= nil)
    assert(data.CompletionCode == bios_enum.SmbiosErrCode.SMBIOS_ERR_INVALID_FIELD:value())
    assert(data.ManufactureId == 0x0007DB)
    assert(data.RequiredOffset == '')
end

function TestSmbiosWriteData:test_smbios_write_finish()
    local smbios_ser = smbios_service.new()
    local req = {ManufactureId = 0, BiosId = 0, Operation = 0, Srcdata = ''}
    local ctx = {ChanType = 'CT_ME'}

    local data = smbios_ser:smbios_write_data(req, ctx)
    assert(data ~= nil)
    assert(data.CompletionCode == bios_enum.SmbiosErrCode.SMBIOS_ERR_INVALID_FIELD:value())
    assert(data.ManufactureId == 0x0007DB)
    assert(data.RequiredOffset == '')
end
