-- 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 log = require 'mc.logging'

-- 固件升级的process阶段，使用该模块保存本次升级流程中执行了升级动作的固件信息，以及升级后的新版本信息
-- 固件升级的finish阶段，从该模块中取出保存的信息注册给firmware组件
-- 如果环境上有待生效的固件而bmc发生复位，则复位启动后firmware组件自动从持久化数据库中恢复之前注册的生效任务，无需使用该模块
local fw_info_collector = {}

function fw_info_collector:clean(firmware_type)
    if not self[firmware_type] then
        self[firmware_type] = {}
    end

    self[firmware_type].fw_info_list = {}
    self[firmware_type].hpm_version = ''
    log:notice('clean fw_info_collector [%s] ok', firmware_type)
end

function fw_info_collector:insert_fw_info(firmware_type, component_id, component_id_ex, uid)
    if not self[firmware_type] then
        log:warn('insert_uid [%s] not init', firmware_type)
        self[firmware_type] = {}
        self[firmware_type].fw_info_list = {}
        self[firmware_type].hpm_version = ''
    end

    table.insert(self[firmware_type].fw_info_list, {component_id = component_id, component_id_ex = component_id_ex, uid = uid})

    log:notice('insert_uid [%s] %s ok', firmware_type, uid)
end

function fw_info_collector:insert_hpm_version(firmware_type, hpm_version)
    if not self[firmware_type] then
        log:warn('insert_uid [%s] not init', firmware_type)
        self[firmware_type] = {}
        self[firmware_type].fw_info_list = {}
        self[firmware_type].hpm_version = ''
    end
    self[firmware_type].hpm_version = hpm_version

    log:notice('insert_hpm_version [%s] %s ok', firmware_type, hpm_version)
end

function fw_info_collector:get_register_info_from_fw_info_list(firmware_type)
    if not self[firmware_type] or not next(self[firmware_type].fw_info_list) then
        log:error('get_register_info_from_fw_info_list [%s] not init', firmware_type)
        return '', '', ''
    end

    -- 去重
    local seen = {}
    local seen_key = ''
    local component_id_table = {}
    local component_id_ex_table = {}
    local uid_table = {}

    for _, fw_info in ipairs(self[firmware_type].fw_info_list) do
        seen_key = fw_info.component_id .. fw_info.component_id_ex .. fw_info.uid
        if not seen[seen_key] then
            seen[seen_key] = true
            table.insert(component_id_table, fw_info.component_id)
            table.insert(component_id_ex_table, fw_info.component_id_ex)
            table.insert(uid_table, fw_info.uid)
        end
    end

    return table.concat(component_id_table, ","), table.concat(component_id_ex_table, ","), table.concat(uid_table, ",")
end

function fw_info_collector:get_hpm_version(firmware_type)
    if self[firmware_type] and self[firmware_type].hpm_version then
        return self[firmware_type].hpm_version
    else
        log:error('get_hpm_version [%s] failed, hpm_version is empty', firmware_type)
        return ''
    end
end

return fw_info_collector