-- Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
-- 
-- this file licensed under the 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 class = require 'mc.class'
local log = require 'mc.logging'
local protocol = require 'protocol_open.protocol.protocol'
local ctx = require 'mc.context'

local pldm_standard = class(protocol)

local request_params_template<const> = {
    pldm_type = true,
    command_code = true
}

-- 只检查是否含有request_params_template以外的参数
function pldm_standard:validate_request_params(req)
    for key in pairs(req) do
        if not self.request_params_template[key] then
            return false
        end
    end
    return true
end

function pldm_standard:construct_request_data(_, request)
    local req_ctx = {
        PldmType = tostring(request.pldm_type),
        CommandCode = tostring(request.command_code)
    }
    local rsp_ctx = {
        CommandCode = tostring(request.rsp_command_code)
    }
    return req_ctx, rsp_ctx, request.data or ''
end

function pldm_standard:unpack_response_data(_, rsp_bin)
    return rsp_bin
end

function pldm_standard:send_request(request)
    local para_ctx = {}
    local req_ctx, rsp_ctx, request_bin = self:construct_request_data(para_ctx, request)
    local ok, rsp_data_bin = pcall(self.endpoint.Request, self.endpoint, ctx.get_context_or_default(),
        request_bin, 0, req_ctx, rsp_ctx)
    if not ok or not rsp_data_bin then
        log:debug('unable to send pldm request to endpoint: %s, error: %s',
            self.endpoint.TargetPhyAddr, rsp_data_bin)
        return nil
    end

    return self:unpack_response_data(para_ctx, rsp_data_bin)
end

function pldm_standard:ctor(params)
    if not params or not params.endpoint then
        log:raise('unable to create pldm protocol with invalid params')
    end
    self.name = 'pldm_standard'
    self.endpoint = params.endpoint
    self.request_params_template = request_params_template

end

return pldm_standard
