-- 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: fructrl object 单个host对象，管理对应host的所有上下电功能

local powerapi = require 'powerapi'
local pwr_restore = require 'pwr_restore'
local pwr_mutation = require 'routine_test.pwr_mutation'
local class = require 'mc.class'
local log = require 'mc.logging'
local utils = require 'types.utils'
local fructrl = require 'fructrl.fructrl'
local syslock = require 'sys_lockdown'
local pwr_action = require 'pwr_action'
local hotswap = require 'state_machine.hotswap_state'
local ctrlstate = require 'state_machine.ctrl_state'
local pwr_cycle = require 'pwr_cycle'

local fructrl_obj = class()

function fructrl_obj:ctor(db, bus, id)
    self.db = db
    self.bus = bus
    self.system_id = id
    self.fructrl = fructrl.new(self.db, self.system_id)
end

function fructrl_obj:init()
    -- 上电必须分发到资源的对象
    self.objs_bef_init = {
        ['flag'] = false,
        ['FruCtrl'] = 'NA',
        ['PGSignal'] = 'NA',
        ['PowerButton'] = 'NA',
        ['ThermTrip'] = 'NA',
        ['RecordFault'] = 'NA',
    }
end

function fructrl_obj:add_object_callback(class_name, object, power_on_lock_info, position)
    if class_name == 'SystemLockDown' then
        self.syslock = syslock.new(self.db, object, self.system_id)
    elseif class_name == 'PowerAction' then
        self.pwr_action = pwr_action.new(self.db, object, self.system_id)
    elseif class_name == 'FruCtrl' then
        self.fructrl:set_fru_obj(object, power_on_lock_info)
    else
        -- 此处分发的对象名为：Nmi/ForceReset/PowerButton/ThermTrip/RecordFault/PGSignal/SysReset
        self.fructrl:create_obj_callback(class_name, object, position)
    end

    -- 从列表中删除已分发的对象
    if self.objs_bef_init[class_name] == 'NA' then
        self.objs_bef_init[class_name] = 'Added'
    end
end

function fructrl_obj:update_chassis_poweron_strategy(value)
    self.fructrl:update_chassis_poweron_strategy(value)
end

function fructrl_obj:add_fruobj_complete_callback()
    if self.objs_bef_init['flag'] then
        return
    end
    for k, v in pairs(self.objs_bef_init) do
        if v == 'NA' then
            log:error('Objects [%s] in objs_bef_init distribute failed.', k)
            return
        end
    end
    self.objs_bef_init['flag'] = true
    log:notice('===== Host %s fructrl objects distribution completed. uptime:%s =====', self.system_id, utils.uptime())

    -- 初始化创建对象
    self.hotswap = hotswap.new(self.fructrl, self.system_id)
    self.ctrlstate = ctrlstate.new(self.hotswap, self.fructrl, self.system_id)
    self.pwr_cycle = pwr_cycle.new(self.fructrl, self.ctrlstate, self.system_id)
    self.powerapi = powerapi.new(self.ctrlstate, self.fructrl, self.pwr_cycle, self.system_id)
    self.pwr_restore = pwr_restore.new(self.ctrlstate, self.fructrl, self.system_id)
    self.pwr_mutation = pwr_mutation.new(self)
    log:notice('========= Host %s create other objects completed. uptime:%s =========', self.system_id, utils.uptime())
end

return fructrl_obj