-- 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 bs = require 'mc.bitstring'
local log = require 'mc.logging'
local core = require 'network.core'
local ncsi_utils = require 'ncsi.ncsi_protocol.ncsi_utils'
local ncsi_def = require 'ncsi.ncsi_protocol.ncsi_def'

local ncsi_oem_response = {}

-- 厂商ID常量
local MANUFACTURE_ID_HUAWEI = 0x000007DB

-- OEM命令响应结构定义
local oem_command_rsp_bs = bs.new([[<<
    rsp_code:16,
    reason_code:16,
    manufacture_id:32,
    cmd_rev:8,
    cmd_id:8,
    sub_cmd:8,
    reserved:8
>>]])

local oem_rsp_bs = bs.new([[<<
    rsp_code:16,
    reason_code:16,
    manufacture_id:32,
    data:22/string,
    fcs:32
>>]])

-- 处理华为OEM命令响应
local function process_hw_oem_rsp(rsp_data, rsp, callback_table)
    local result = rsp_data.rsp_code
    if result ~= ncsi_def.CMD_COMPLETED then
        -- 原因码和响应码解析
        ncsi_utils.common_respcode_parse(result)
        ncsi_utils.common_reasoncode_parse(rsp_data.reason_code)
        return ncsi_def.NCSI_FAIL
    end

    -- 使用传入的回调表
    if callback_table then
        for _, callback in ipairs(callback_table) do
            if rsp_data.sub_cmd == callback.sub_cmd and rsp_data.cmd_id == callback.cmd_id then
                if callback.func then
                    callback.func(rsp)
                    return ncsi_def.NCSI_SUCCESS
                end
            end
        end
    end

    -- 如果没有找到对应的回调函数，记录日志
    log:debug('No callback found for HW OEM command: cmd_id=%u, sub_cmd=%u',
        rsp_data.cmd_id, rsp_data.sub_cmd)

    return ncsi_def.NCSI_SUCCESS
end

-- 处理通用OEM命令响应
local function process_common_oem_rsp(rsp)
    local rsp_data = oem_rsp_bs:unpack(rsp.payload, true)
    local result = rsp_data.rsp_code

    if result ~= ncsi_def.CMD_COMPLETED then
        -- 原因码和响应码解析
        ncsi_utils.common_respcode_parse(result)
        ncsi_utils.common_reasoncode_parse(rsp_data.reason_code)
        return ncsi_def.NCSI_FAIL
    end

    return ncsi_def.NCSI_SUCCESS
end

-- 主要的响应处理函数
local function process_rsp(rsp, callback_table)
    local rsp_data = oem_command_rsp_bs:unpack(rsp.payload, true)
    if not rsp_data then
        log:error('Failed to unpack OEM command response payload')
        return ncsi_def.NCSI_FAIL
    end
    local manufacture_id = core.ntohl(rsp_data.manufacture_id)
    if manufacture_id == MANUFACTURE_ID_HUAWEI then
        return process_hw_oem_rsp(rsp_data, rsp, callback_table)
    else
        return process_common_oem_rsp(rsp)
    end
end

-- 标准的OEM命令响应处理函数
function ncsi_oem_response.read_oem_command_rsp(rsp, callback_table)
    if not rsp then
        log:error('read oem command rsp: rsp is nil')
        return ncsi_def.NCSI_FAIL
    end

    if not rsp.payload then
        log:error('read oem command rsp: rsp.payload is nil')
        return ncsi_def.NCSI_FAIL
    end

    return process_rsp(rsp, callback_table)
end

-- 创建回调函数
function ncsi_oem_response.create_callback_entry(cmd_id, sub_cmd, func)
    return {
        cmd_id = cmd_id,
        sub_cmd = sub_cmd,
        func = func
    }
end

-- 导出常量供其他模块使用
ncsi_oem_response.MANUFACTURE_ID_HUAWEI = MANUFACTURE_ID_HUAWEI

return ncsi_oem_response