-- 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 c_seu = require 'unit_manager.class.unit.seu.seu'
local cmn = require 'common'
local log = require 'mc.logging'
local skynet = require 'skynet'
local drive_start_slot_helper = require 'unit_manager.drive_start_slot_helper'

---@class M2TransferCard: SEU @M.2转接卡
local c_m2_transform_card = class(c_seu)

local UNAVAILABLE = 'N/A'

function c_m2_transform_card:update_mcu_status()
    if not self.mcu_obj or not self.mcu_obj.interface then
        return
    end

    local state = self.mcu_obj.interface:query_upgrade_status()
    if state then
        self:set_prop('Count', 0)        -- 通信成功次数重置成0
        self:set_prop('CpldStatus', 0)   -- 默认配置成0, 表示没有告警
        return
    end

    local count = self:get_prop('Count')
    if count < 3 then   -- 三次防抖, 前两次失败后只计数
        self:set_prop('Count', count + 1)
        return
    end

    -- 连续三次失败后则表示通信失败，更新CpldStatus状态触发告警
    if count == 3 then
        log:error('[M2TransferCard] Mcu communication test failed.')
        -- 防止错误日志刷屏，将Count设置为4后不会再进此分支
        self:set_prop('Count', count + 1)
    end
    self:set_prop('CpldStatus', 1)
end

function c_m2_transform_card:task_update_mcu_status()
    if self:get_prop('MCUVersion') == UNAVAILABLE then
        return
    end

    skynet.fork_loop({count = 0}, function()
        cmn.skynet.sleep(12000) -- 启动阶段等待2分钟后更新MCU状态
        while true do
            cmn.skynet.sleep(500)
            self:update_mcu_status()
        end
    end)
end

function c_m2_transform_card:update_slot()
    -- M.2转接卡的slot是在最后一位，如果继承c_unit中的update_slot接口，slot会一直被置为2
    local device_name = self:get_prop('DeviceName')
    if not device_name or #device_name <= 1 then
        return
    end
    local slot = tonumber(device_name:match('%d+$'))
    if slot then
        -- Slot在SR文件中为固定值或未配置, 暂不支持引用
        self:set_prop('Slot', slot)
    end
end

function c_m2_transform_card:task_update()
    self:task_update_mcu_version()
    self:task_update_mcu_status()
end

---时机2：M.2 转接卡添加时，根据 DriveStartSlotConfig 更新 StartSlot
---@param drive_start_slot_configs table DriveStartSlotConfig 对象列表
---@param psr_add_object_complete_fired boolean add_object_complete 是否已触发
---@param parent_unit table 上一级单板对象
function c_m2_transform_card:update_start_slot_from_drive_config(drive_start_slot_configs,
    psr_add_object_complete_fired, parent_unit)
    drive_start_slot_helper.update_backplane_start_slot_if_pending(self, drive_start_slot_configs,
        psr_add_object_complete_fired, parent_unit)
end

return c_m2_transform_card