-- 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 abstract_cfg = require "pojo.boot.abstract_boot_option"
local boot_def = require "macros.boot_def"
local log = require "mc.logging"

local boot_initiator_mailbox = class(abstract_cfg)

function boot_initiator_mailbox:ctor(option_db_obj, system_id)
    local prop = boot_def.BOOT_INITIATOR_MAILBOX
    boot_def.BOOT_LEN_TBL[prop] = boot_def.BIOS_BOOT_INIT_MAILBOX_NUM
    boot_initiator_mailbox.super.init_db_info(self, option_db_obj,
        prop, boot_def.BOOT_INITIATOR_MAILBOX_LOG, system_id)
    boot_def.BOOT_LEN_TBL[prop] = boot_def.BIOS_BOOT_MAIBOX_SEG_LEN
end

-- 设置启动参数
function boot_initiator_mailbox:operate_info(config_data)
    local seg_num = string.sub(config_data, 1, 1):byte()
    if seg_num >= boot_def.BIOS_MAILBOX_SEG_MAX_NUM then
        log:error("[bios]boot_initiator_mailbox: operate_info seg_num(%d) out of range.", seg_num)
        return boot_def.COMP_CODE_OUTOF_RANGE
    end

    local len = #config_data - boot_def.BIOS_BOOT_MAIBOX_SEG_LEN
    if len == 0 then
        log:error("[bios]boot_initiator_mailbox: operate_info len(0) invalid.")
        return boot_def.COMP_CODE_INVALID_FIELD
    end

    if len > boot_def.BIOS_BOOT_VALID_SEG_NUM then
        log:error("[bios]boot_initiator_mailbox: operate_info len(%d) out of range.", len)
        return boot_def.COMP_CODE_OUTOF_RANGE
    end

    if len >= boot_def.BIOS_BOOT_SEG_MIN_NUM and len <= boot_def.BIOS_BOOT_VALID_SEG_NUM then
        local mailbox_data = string.sub(config_data, 2, -1)
        local mailbox_len = #mailbox_data
        local index = boot_def.BIOS_BOOT_VALID_SEG_NUM * seg_num
        for i = 1, mailbox_len do
            local bin_byte = string.sub(mailbox_data, i, i):byte()
            self.data[index] = bin_byte
            log:info("[bios]operate_info boot_initiator_mailbox[%d]: %d", index, bin_byte)
            index = index + 1
        end
    end

    return boot_def.COMP_CODE_SUCCESS
end

-- 获取启动参数
function boot_initiator_mailbox:get_info(config_data)
    local data = self.data
    if not data or not config_data or #config_data < boot_def.BIOS_BOOT_MAIBOX_SEG_LEN then
        return nil
    end

    local seg_num = string.sub(config_data, 1, 1):byte()
    if seg_num >= boot_def.BIOS_MAILBOX_SEG_MAX_NUM then
        log:error("boot_initiator_mailbox: get_info seg_num(%d) out of range.", seg_num)
        return nil
    end

    local option_data = {}
    option_data[0] = seg_num

    local mailbox_len = boot_def.BIOS_BOOT_VALID_SEG_NUM
    local index = boot_def.BIOS_BOOT_VALID_SEG_NUM * seg_num
    for i = 0, mailbox_len - 1 do
        local data_i = data[index + i]
        if not data_i then
            data_i = 0
        end
        option_data[i + 1] = data_i
        log:info("get_info boot_initiator_mailbox[%d]: %d", index + i, data[index + i])
    end

    return option_data
end

return boot_initiator_mailbox