-- Copyright (c) 2026 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: MCU升级策略配置
-- 包含：发送参数配置策略、文件发送流程控制策略

local MCU_ENUMS = require 'mcu.enum.mcu_enums'

local upgrade_strategies = {}

--- 厂商发送参数配置表
local VENDOR_SEND_PARAMS_STRATEGIES = {
    {
        -- ST基础板的MCU升级硬件建议等待0.5s
        match = function(vendor, fw_type, board_type)
            return vendor == 0 and fw_type == 0 and board_type == 'BCU'
        end,
        params = {
            delay = 50,
            subsection_size = 2304
        }
    },
    {
        -- 写入flash为等待4s, 硬件建议每2304B等待
        -- MCU:每次传包有效数据长度是96Byte，设置为2304Byte为96Byte的倍数，方便MCU将传入的数据写入内部flash
        match = function(vendor, fw_type, board_type)
            return vendor == 1 and fw_type == 0 and board_type ~= 'ACU'
        end,
        params = {
            delay = 400,           -- 写入flash为等待4s
            subsection_size = 2304 -- 每次传包96Byte的倍数，方便MCU写入内部flash
        }
    },
    {
        -- 该类型写入flash为等待400ms, 硬件建议每2304B等待
        match = function(vendor, fw_type, board_type)
            return vendor == 2 and fw_type == 2 and board_type == 'BCU'
        end,
        params = {
            delay = 40, -- VRD写入flash为等待400ms
            subsection_size = 2304
        }
    },
}

--- 板型特定参数配置
local BOARD_TYPE_PARAMS_CONFIGS = {
    {
        -- NPU模组每次写入240字节
        match = function(board_type)
            return board_type == 'ACU'
        end,
        params = {
            smc_data_len = MCU_ENUMS.NPU_SMC_FILE_DATA_LEN
        }
    },
}

function upgrade_strategies.apply_send_params_strategy(params_table, vendor, fw_type, board_type)
    -- 1. 应用厂商特定配置
    for _, strategy in ipairs(VENDOR_SEND_PARAMS_STRATEGIES) do
        if strategy.match(vendor, fw_type, board_type) then
            for key, value in pairs(strategy.params) do
                params_table[key] = value
            end
        end
    end

    -- 2. 应用板型特定配置（优先级更高，会覆盖厂商配置）
    for _, config in ipairs(BOARD_TYPE_PARAMS_CONFIGS) do
        if config.match(board_type) then
            for key, value in pairs(config.params) do
                params_table[key] = value
            end
        end
    end
end

-- 需要传包的策略列表
local FILE_SEND_FLOW_STRATEGIES = {
    -- 策略1：vendor 2的comp_no 0需要传包
    {
        match = function(context)
            return context.vendor == 2 and context.fw_type == 2
                and context.board_type == 'BCU' and context.comp_no == 0
        end
    },
    -- 策略2：传包没有成功过需要传包
    {
        match = function(context)
            return context.upgrade_details.ever_send_file_success == 0
        end
    },
    -- 策略3：只有特殊厂商才只传一次包，其他的每次都需要传
    {
        match = function(context)
            return not (context.vendor == 2 and context.fw_type == 2 and context.board_type == 'BCU')
        end
    },
}

function upgrade_strategies.should_send_file(context)
    -- 遍历所有策略，满足任一策略就需要传包
    for _, strategy in pairs(FILE_SEND_FLOW_STRATEGIES) do
        if strategy.match(context) then
            return true -- 满足策略，需要传包
        end
    end

    return false -- 不满足任何策略，不传包
end

return upgrade_strategies