-- 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.

-- Description: SMC独立vrd升级
local log = require 'mc.logging'
local utils = require 'mc.utils'
local context = require 'mc.context'
local utils_core = require 'utils.core'
local vos = require 'utils.vos'
local fw_mgmt = require 'general_hardware.client'
local cmn = require 'common'
local defs = require 'mcu.upgrade.defs'
local ind_vrd_defs = require 'independent_vrd.ind_vrd_defs'
local fw_vrd_valid = require 'mcu.upgrade.valid'
local upgrade_service_comm = require 'mcu.upgrade.upgrade_service.upgrade_service_comm'
local upgrade_service_vrd = require 'mcu.upgrade.upgrade_service.upgrade_service_vrd'

local smc_vrd_upgrade = {}
smc_vrd_upgrade.__index = smc_vrd_upgrade

local smc_type_map = {
    [ind_vrd_defs.FIRMWARE_TYPE.SMC_ACTIVE] = ind_vrd_defs.FIRMWARE_TYPE.ACTIVE
}

function smc_vrd_upgrade.new(bus, db, vrd_collection)
    return setmetatable({
        bus = bus,
        db = db,
        is_activing = false,
        vrd_collection = vrd_collection,
        _upgrade_service = upgrade_service_vrd.new(bus, db, vrd_collection)
    }, smc_vrd_upgrade)
end

function smc_vrd_upgrade:on_upgrade_prepare(_, system_id, firmware_type, cfg_path, hpm_path, parameters)
    return self._upgrade_service:on_upgrade_prepare(system_id, firmware_type, cfg_path, hpm_path, parameters)
end

function smc_vrd_upgrade:on_upgrade_process(_, system_id, firmware_type, file_path, parameters)
    return self._upgrade_service:on_upgrade_process(system_id, firmware_type, file_path, parameters)
end

function smc_vrd_upgrade:on_upgrade_finish(_, system_id, firmware_type, parameters)
    return self._upgrade_service:on_upgrade_finish(system_id, firmware_type, parameters)
end

function smc_vrd_upgrade:on_active_process(_, system_id, firmware_type)
    if self:is_upgrading_or_activing() then
        log:notice('[Ind_Vrd] is_activing = %s or Ind_Vrd is Upgrading', self.is_activing)
        fw_mgmt:FirmwareActiveFirmwareActiveActiveProcessReply(context.new(), system_id, firmware_type, defs.RET.ERR)
        return
    end

    local type = smc_type_map[firmware_type]
    log:notice('[Ind_Vrd] active %s start', type)

    upgrade_service_comm.update_active_status(type, type, 'Apply')

    local fw_type = firmware_type == ind_vrd_defs.FIRMWARE_TYPE.SMC_ACTIVE and
        ind_vrd_defs.FIRMWARE_TYPE.UPGRADE or firmware_type
    local file_path, file_tab, sys_id
    self.is_activing = true
    if vos.get_file_accessible(defs.FW_VALID_FILE_DIR[fw_type]) then
        for _, file_name in pairs(utils_core.dir(defs.FW_VALID_FILE_DIR[fw_type])) do
            -- file_name be like: HOST_<sys_id>_Independent_Vrd.hpm
            file_tab = utils.string_split(file_name, '_', true)
            sys_id = tonumber(file_tab[2]) or 1
            file_path = defs.FW_VALID_FILE_DIR[fw_type] .. file_name
            fw_vrd_valid.vrd_valid_task(self._upgrade_service, sys_id, file_path)
        end
    else
        log:error('[Ind_Vrd] cache upgrade file not exist')
    end

    log:notice('[Ind_Vrd] active vrd finish')
    self.is_activing = false
    -- 等待10s，防止相应过快firmware_mgmt没有收到回应
    cmn.skynet.sleep(1000)
    fw_mgmt:FirmwareActiveFirmwareActiveActiveProcessReply(context.new(), system_id, type, defs.RET.OK)
end

function smc_vrd_upgrade:get_vrd_load()
    return self._upgrade_service:get_vrd_load()
end

function smc_vrd_upgrade:register_vrd_active_action(firmware_type)
    return self._upgrade_service:register_vrd_active_action(firmware_type)
end

function smc_vrd_upgrade:is_upgrading_or_activing()
    if self.is_activing then
        log:debug('find firmware is activing')
        return true
    end
    if self._upgrade_service.is_vrd_upgrading then
        log:debug('find firmware is upgrading')
        return true
    end
    return false
end

return smc_vrd_upgrade