-- Copyright (c) 2025 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'
local MCU_ENUMS = require 'mcu.enum.mcu_enums'

local smc_firmware_status = {}
smc_firmware_status.__index = smc_firmware_status

local function get_smc_detail(all, obj, type)
    local upgrade_cnt = obj.interface:get_subcomp_upgrade_cnt()
    if not upgrade_cnt then
        log:error('get %s upgrade cnt failed', obj.mcu.Id)
        return
    end
    local tab = {}
    local detail, id
    for i = 0, upgrade_cnt.cnt - 1 do
        detail = obj.interface:get_upgrade_detail(i)
        if not detail then
            log:error('get %s upgrade detail failed', obj.mcu.Id)
            goto continue
        end
        if (type == 'VRD' and detail.type ~= MCU_ENUMS.SUB_COMPONENT_TYPE.T_VRD) or
        (type == 'MCU' and detail.type ~= MCU_ENUMS.SUB_COMPONENT_TYPE.T_MCU) then
            goto continue
        end
        id = obj.mcu.Id
        if type == 'VRD' and detail.type == MCU_ENUMS.SUB_COMPONENT_TYPE.T_VRD then
            id = 'VRD' .. string.sub(obj.mcu.Id, 4)
        end
        tab.ObjectId = tostring(id)
        tab.ChipType = tostring(detail.type or 'N/A')
        tab.ChipIndex = tostring(detail.no or 'N/A')
        tab.ChipVendor = tostring(detail.vendor or 'N/A')
        tab.ChipModel = tostring(detail.sku or 'N/A')
        tab.MajorVersion = tostring(detail.major_version or 'N/A')
        tab.MinorVersion = tostring(detail.minor_version or 'N/A')
        tab.Revision = tostring(detail.revision or 'N/A')
        tab.TansmissionIntervalMilliseconds = tostring(detail.delay and detail.delay * 100 or 'N/A')
        tab.UpgradeStatus = tostring(obj.interface:query_upgrade_status() or 'N/A')
        table.insert(all, tab)
        ::continue::
    end
end

local function get_smbus_detail(all, obj)
    local tab = {}
    tab.ObjectId = tostring(obj.mcu.Id)
    tab.ChipType = 'N/A'
    tab.ChipIndex = 'N/A'
    tab.ChipVendor = tostring(obj.interface:get_vendor_id() or 'N/A')
    tab.ChipModel = 'N/A'
    local maj, min, rev = obj.interface:get_version()
    tab.MajorVersion = tostring(maj or 'N/A')
    tab.MinorVersion = tostring(min or 'N/A')
    tab.Revision = tostring(rev or 'N/A')
    tab.TansmissionIntervalMilliseconds = 'N/A'
    tab.UpgradeStatus = tostring(obj.interface:query_upgrade_status() or 'N/A')
    table.insert(all, tab)
end

function smc_firmware_status:get_update_details(mcu_service, ind_vrd_service, type)
    local all = {}
    for _, obj in pairs(mcu_service.mcu_collection) do
        if obj.mcu.Protocol == MCU_ENUMS.SMC_CHANNEL then
            get_smc_detail(all, obj, type)
        end
        if obj.mcu.Protocol == MCU_ENUMS.SMBUS_CHANNEL or obj.mcu.Protocol == '' and type == 'MCU' then
            get_smbus_detail(all, obj)
        end
    end
    for _, obj in pairs(ind_vrd_service.ind_vrd_collection) do
        if obj.mcu.Protocol == MCU_ENUMS.SMC_CHANNEL then
            get_smc_detail(all, obj, type)
        end
    end
    return all
end

return smc_firmware_status
