-- 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: 后电电源信号

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

local c_pg_signal = class()

function c_pg_signal:ctor(fructrl, object)
    self.fructrl = fructrl
    self.obj = object
    self.system_id = fructrl.system_id
    self.poweron_fault = false -- 电源故障标记
    self.poweroff_fault = false
    log:notice("[System:%s]set pg_signal object successfully, uptime: %s.", self.system_id, utils.uptime())
end

function c_pg_signal:init()
    -- 私有属性属性变更监听
    self.obj.property_changed:on(function(name, value)
        if name == 'PowerGDState' then
            if self.obj.FruID ~= 0 then
                log:notice_easy('==== [System:%s]FRU %s PowerGDStatus changed to %s ====', self.system_id,
                    self.obj.FruID, value == 1 and 'ON' or 'OFF')
                return
            end
            self:dealwith_power_gd_status(value)
        end
    end)
end

function c_pg_signal:get_PGSignal()
    -- 关联Scanner的私有属性
    return self.obj.PowerGDState
end

function c_pg_signal:set_poweron_fault_flag(val)
    self.poweron_fault = val
end

function c_pg_signal:set_poweroff_fault_flag(val)
    self.poweroff_fault = val
end

function c_pg_signal:check_poweroff_fault()
    -- 检查ACPI是否为上电，下电失败则说明发生电源故障，设置下电故障标记为true
    local acpi_on = 1
    if self:get_PGSignal() == acpi_on then
        self.poweroff_fault = true
        log:error_easy('[System:%s]Power off fail', self.system_id)
    else
        self.poweroff_fault = false
    end
end

function c_pg_signal:dealwith_power_gd_status(val)
    if val == 0 then
        log:notice_easy('==== [System:%s]PowerGDStatus changed to power off ====', self.system_id)
        if self.fructrl:get_PowerState() == enums.PowerStatus.OFFING then
            -- 调南向接口下的电，成功后记录到数据库
            log:notice_easy('[System:%s]bmc execute poweroff set PwrStateBeforeACLost to false', self.system_id)
            self.fructrl:set_PwrStateBeforeACLost(false)
        end
        self.fructrl:set_PowerState(enums.PowerStatus.OFF)
    elseif val == 1 then
        log:notice_easy('==== [System:%s]PowerGDStatus changed to power on ====', self.system_id)
        if self.fructrl:get_PowerState() == enums.PowerStatus.ONING then
            -- 调南向接口上的电，成功后记录到数据库
            log:notice_easy('[System:%s]bmc execute poweron set PwrStateBeforeACLost to true', self.system_id)
            self.fructrl:set_PwrStateBeforeACLost(true)
        end
        self.fructrl:set_PowerState(enums.PowerStatus.ON)
        self.fructrl:finish_poweron()
    else
        log:notice_easy('==== [System:%s]PowerGDStatus detected invalid value(%s) ====', self.system_id, val)
    end
end

function c_pg_signal:set_powerstate_init_value()
    local stat = self:get_PGSignal()
    log:notice_easy("[System:%s]Init PowerGDStatus is (%d).", self.system_id, stat)

    -- 设置PowerState初始值
    if stat == 0 then
        self.fructrl:set_PowerState(tostring(enums.PowerStatus.OFF))
    elseif stat == 1 then
        self.fructrl:set_PowerState(tostring(enums.PowerStatus.ON))
    end
end

return c_pg_signal