-- 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: 强制重启(热复位)，cpu不下电复位

local log = require 'mc.logging'
local class = require 'mc.class'
local enums = require 'types.enums'
local utils = require 'types.utils'

local c_force_reset = class()

function c_force_reset:ctor(fructrl)
    self.fructrl = fructrl
    self.system_id = fructrl.system_id
    self.objs = {}
end

local function set_prop(objs, prop, val, system_id)
    local ok, err
    for _, obj in pairs(objs) do
        ok, err = pcall(function()
            obj[prop] = val
        end)
        if not ok then
            log:error_easy('[System:%s]Execute force restart, set prop failed. prop=[%s], err=[%s]',
                system_id, prop, err)
            return ok
        end
    end
    return ok
end

function c_force_reset:insert_obj(object)
    self.objs[object.FruID] = self.objs[object.FruID] or {}
    table.insert(self.objs[object.FruID], object)
    log:notice_easy("[System:%s]insert force_reset fru%s object successfully, uptime: %s.",
        self.system_id, object.FruID, utils.uptime())
end

function c_force_reset:force_restart(fruid)
    self.fructrl.sys_reset_queue(function()
        local ok = set_prop(self.objs[fruid], 'ForceRst', 1, self.system_id)
        if not ok then
            log:notice_easy('[System:%s]execute force restart failed, and fruid is %s', self.system_id, fruid)
            return enums.RetValue.ERR
        end
        log:notice_easy('[System:%s]execute force restart successfully, and fruid is %s', self.system_id, fruid)
        self.fructrl:set_sys_reset_flag(true)
    end)
    return enums.RetValue.OK
end

return c_force_reset