-- 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 log = require "mc.logging"
local boot_def = require "macros.boot_def"
local bs_util = require 'util.base_util'
local _, client = pcall(require, 'bios.client')

local poweroff_timeout = class(abstract_cfg)

local function get_fructrl_object(sys_id)
    local ok, obj = pcall(client.GetFruCtrlFruCtrlObject, client, {SystemId = sys_id, Id = ':Id'})
    if not ok or not obj then
        log:error('[bios] Bios cannot get FruCtrl object!')
        return
    end

    return obj
end

function poweroff_timeout:set_info(config_data, ctx)
    local sys_id = bs_util.get_system_id(ctx)
    local obj = get_fructrl_object(sys_id)
    if not obj then
        return boot_def.COMP_CODE_UNKNOWN
    end

    if #config_data ~= 2 then
        log:error("[bios] Set boot_option[poweroff_timeout]: data len invalid.")
        return boot_def.COMP_CODE_LEN_INVALID
    end

    local data_1 = string.sub(config_data, 1, 1):byte()
    local data_2 = string.sub(config_data, 2, 2):byte()

    local pwr_off_timeout = data_2 * 256 + data_1
    -- 为了兼容老的SMM板,ipmi上来的消息的单位还是按100ms处理，所以这里要除以10
    pwr_off_timeout = pwr_off_timeout / 10;

    obj.GracefulShutdownTimeoutSeconds = pwr_off_timeout

    return boot_def.COMP_CODE_SUCCESS
end

function poweroff_timeout:get_info(config_data, sys_id)
    local obj = get_fructrl_object(sys_id)
    if obj == nil then
        return nil
    end

    if #config_data ~= 2 then
        log:error("[bios] Get boot_option[poweroff_timeout]: data len invalid.")
        return nil
    end

    local set_selector = string.sub(config_data, 1, 1):byte()
    local block_selector = string.sub(config_data, 2, 2):byte()

    if set_selector ~= 0x00 or block_selector ~= 0x00 then
        return nil, 0xcc
    end

    -- 为了兼容老的SMM板,ipmi上来的消息的单位还是按100ms处理，所以这里要乘以10
    local pwr_off_timeout = obj.GracefulShutdownTimeoutSeconds * 10;

    local rsp = {}
    rsp[0] = (pwr_off_timeout >> 8) & 0xff
    rsp[1] = pwr_off_timeout & 0xff
    return rsp
end

return poweroff_timeout