/**
 * @brief This file will be depricated soon. Currently it exists as a patch.
 * This code is to be upstreamed in C, however to build it within this repo,
 * this code is extracted as a cpp file here.
 * There were some functionalities that were not working as a C file hence
 * extracted to a cpp file
 */
#include "pldm_rde.hpp"

#include "libpldm/base.h"

#include <endian.h>

#include <stdplus/print.hpp>

#include <cstdlib>
#include <cstring>

int encode_negotiate_redfish_parameters_req(uint8_t instance_id,
                                            uint8_t concurrency_support,
                                            bitfield16_t* feature_support,
                                            struct pldm_msg* msg)
{
    if ((msg == NULL) || (feature_support == NULL) ||
        (concurrency_support == 0))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    struct pldm_header_info header;
    header.instance = instance_id;
    header.pldm_type = PLDM_RDE;
    header.msg_type = PLDM_REQUEST;
    header.command = PLDM_NEGOTIATE_REDFISH_PARAMETERS;
    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
    if (rc != PLDM_SUCCESS)
    {
        return rc;
    }
    struct pldm_rde_negotiate_redfish_parameters_req* req =
        (struct pldm_rde_negotiate_redfish_parameters_req*)msg->payload;
    req->mc_concurrency_support = concurrency_support;
    req->mc_feature_support.value = htole16(feature_support->value);
    return PLDM_SUCCESS;
}

int encode_negotiate_redfish_parameters_resp(
    uint8_t instance_id, uint8_t completion_code,
    uint8_t device_concurrency_support, bitfield8_t device_capabilities_flags,
    bitfield16_t device_feature_support,
    uint32_t device_configuration_signature, const char* device_provider_name,
    enum pldm_rde_varstring_format name_format, struct pldm_msg* msg)
{
    if ((NULL == msg) || (NULL == device_provider_name))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    struct pldm_header_info header;
    header.msg_type = PLDM_RESPONSE;
    header.instance = instance_id;
    header.pldm_type = PLDM_RDE;
    header.command = PLDM_NEGOTIATE_REDFISH_PARAMETERS;
    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
    if (rc != PLDM_SUCCESS)
    {
        return rc;
    }
    struct pldm_rde_negotiate_redfish_parameters_resp* response =
        (struct pldm_rde_negotiate_redfish_parameters_resp*)msg->payload;
    response->completion_code = completion_code;
    if (response->completion_code != PLDM_SUCCESS)
    {
        return PLDM_SUCCESS;
    }
    response->device_concurrency_support = device_concurrency_support;
    response->device_capabilities_flags.byte = device_capabilities_flags.byte;
    response->device_feature_support.value =
        htole16(device_feature_support.value);
    response->device_configuration_signature =
        htole32(device_configuration_signature);
    response->device_provider_name.string_format = name_format;
    // length should include NULL terminator.
    response->device_provider_name.string_length_bytes =
        strlen(device_provider_name) + 1;
    // Copy including NULL terminator.
    memcpy(response->device_provider_name.string_data, device_provider_name,
           response->device_provider_name.string_length_bytes);
    return PLDM_SUCCESS;
}

int decode_negotiate_redfish_parameters_req(const struct pldm_msg* msg,
                                            size_t payload_length,
                                            uint8_t* mc_concurrency_support,
                                            bitfield16_t* mc_feature_support)
{
    if ((msg == NULL) || (mc_concurrency_support == NULL) ||
        (mc_feature_support == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    if (payload_length !=
        sizeof(struct pldm_rde_negotiate_redfish_parameters_req))
    {
        return PLDM_ERROR_INVALID_LENGTH;
    }
    struct pldm_rde_negotiate_redfish_parameters_req* request =
        (struct pldm_rde_negotiate_redfish_parameters_req*)msg->payload;
    if (request->mc_concurrency_support == 0)
    {
        stdplus::print(stderr, "Concurrency support is 0\n");
        return PLDM_ERROR_INVALID_DATA;
    }
    *mc_concurrency_support = request->mc_concurrency_support;
    mc_feature_support->value = le16toh(request->mc_feature_support.value);
    return PLDM_SUCCESS;
}

int encode_negotiate_medium_parameters_resp(
    uint8_t instance_id, uint8_t completion_code,
    uint32_t device_maximum_transfer_bytes, struct pldm_msg* msg)
{
    if (NULL == msg)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    struct pldm_header_info header;
    header.msg_type = PLDM_RESPONSE;
    header.instance = instance_id;
    header.pldm_type = PLDM_RDE;
    header.command = PLDM_NEGOTIATE_MEDIUM_PARAMETERS;
    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
    if (rc != PLDM_SUCCESS)
    {
        return rc;
    }
    struct pldm_rde_negotiate_medium_parameters_resp* response =
        (struct pldm_rde_negotiate_medium_parameters_resp*)msg->payload;
    response->completion_code = completion_code;
    if (response->completion_code != PLDM_SUCCESS)
    {
        return PLDM_SUCCESS;
    }
    response->device_maximum_transfer_chunk_size_bytes =
        htole32(device_maximum_transfer_bytes);
    return PLDM_SUCCESS;
}

int decode_negotiate_redfish_parameters_resp(
    const struct pldm_msg* msg, size_t payload_length, uint8_t* completion_code,
    struct pldm_rde_device_info* device)
{
    if ((msg == NULL) || (device == NULL) || (completion_code == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }

    *completion_code = msg->payload[0];

    if (PLDM_SUCCESS != *completion_code)
    {
        stdplus::print(
            stderr,
            "Unsuccessful completion code received in neg. params: {}\n",
            static_cast<uint8_t>(*completion_code));
        return PLDM_SUCCESS;
    }

    if (payload_length < RDE_NEGOTIATE_REDFISH_PARAMETERS_RESP_BYTES)
    {
        return PLDM_ERROR_INVALID_LENGTH;
    }

    struct pldm_rde_negotiate_redfish_parameters_resp* response =
        (struct pldm_rde_negotiate_redfish_parameters_resp*)msg->payload;

    device->device_concurrency = response->device_concurrency_support;
    device->device_capabilities_flag = response->device_capabilities_flags;
    device->device_configuration_signature =
        le32toh(response->device_configuration_signature);
    device->device_feature_support.value =
        le16toh(response->device_feature_support.value);
    device->device_provider_name = response->device_provider_name;
    return PLDM_SUCCESS;
}

int decode_negotiate_medium_parameters_resp(
    const struct pldm_msg* msg, size_t payload_length, uint8_t* completion_code,
    uint32_t* device_maximum_transfer_bytes)
{
    if ((msg == NULL) || (device_maximum_transfer_bytes == NULL) ||
        (completion_code == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }

    *completion_code = msg->payload[0];

    if (PLDM_SUCCESS != *completion_code)
    {
        stdplus::print(
            stderr,
            "Unsuccessful completion code received in neg med params: {}\n",
            static_cast<uint8_t>(*completion_code));
        return PLDM_SUCCESS;
    }

    if (payload_length < RDE_NEGOTIATE_MEDIUM_PARAMETERS_RESP_BYTES)
    {
        return PLDM_ERROR_INVALID_LENGTH;
    }

    struct pldm_rde_negotiate_medium_parameters_resp* response =
        (struct pldm_rde_negotiate_medium_parameters_resp*)msg->payload;

    *device_maximum_transfer_bytes =
        le32toh(response->device_maximum_transfer_chunk_size_bytes);

    return PLDM_SUCCESS;
}

int encode_negotiate_medium_parameters_req(uint8_t instance_id,
                                           uint32_t maximum_transfer_size,
                                           struct pldm_msg* msg)
{
    if (msg == NULL)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    struct pldm_header_info header;
    header.instance = instance_id;
    header.pldm_type = PLDM_RDE;
    header.msg_type = PLDM_REQUEST;
    header.command = PLDM_NEGOTIATE_MEDIUM_PARAMETERS;
    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
    if (rc != PLDM_SUCCESS)
    {
        return rc;
    }
    struct pldm_rde_negotiate_medium_parameters_req* req =
        (struct pldm_rde_negotiate_medium_parameters_req*)msg->payload;
    req->mc_maximum_transfer_chunk_size_bytes = htole32(maximum_transfer_size);
    return PLDM_SUCCESS;
}

int decode_negotiate_medium_parameters_req(const struct pldm_msg* msg,
                                           size_t payload_length,
                                           uint32_t* mc_maximum_transfer_size)
{
    if ((msg == NULL) || (mc_maximum_transfer_size == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    if (payload_length !=
        sizeof(struct pldm_rde_negotiate_medium_parameters_req))
    {
        return PLDM_ERROR_INVALID_LENGTH;
    }
    struct pldm_rde_negotiate_medium_parameters_req* request =
        (struct pldm_rde_negotiate_medium_parameters_req*)msg->payload;
    *mc_maximum_transfer_size =
        le32toh(request->mc_maximum_transfer_chunk_size_bytes);
    if (*mc_maximum_transfer_size < PLDM_RDE_MIN_TRANSFER_SIZE_BYTES)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    return PLDM_SUCCESS;
}

int encode_get_schema_dictionary_req(uint8_t instance_id, uint32_t resource_id,
                                     uint8_t schema_class, struct pldm_msg* msg)
{
    if (msg == NULL)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    struct pldm_header_info header;
    header.instance = instance_id;
    header.pldm_type = PLDM_RDE;
    header.msg_type = PLDM_REQUEST;
    header.command = PLDM_GET_SCHEMA_DICTIONARY;
    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
    if (rc != PLDM_SUCCESS)
    {
        return rc;
    }
    struct pldm_rde_get_schema_dictionary_req* req =
        (struct pldm_rde_get_schema_dictionary_req*)msg->payload;
    req->resource_id = htole32(resource_id);
    req->requested_schema_class = schema_class;
    return PLDM_SUCCESS;
}

int decode_get_schema_dictionary_req(const struct pldm_msg* msg,
                                     size_t payload_length,
                                     uint32_t* resource_id,
                                     uint8_t* requested_schema_class)
{
    if ((msg == NULL) || (resource_id == NULL) ||
        (requested_schema_class == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    if (payload_length != sizeof(struct pldm_rde_get_schema_dictionary_req))
    {
        return PLDM_ERROR_INVALID_LENGTH;
    }
    struct pldm_rde_get_schema_dictionary_req* request =
        (struct pldm_rde_get_schema_dictionary_req*)msg->payload;
    *resource_id = le32toh(request->resource_id);
    *requested_schema_class = request->requested_schema_class;
    if (*requested_schema_class > PLDM_RDE_SCHEMA_REGISTRY)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    return PLDM_SUCCESS;
}

int encode_get_schema_dictionary_resp(uint8_t instance_id,
                                      uint8_t completion_code,
                                      uint8_t dictionary_format,
                                      uint32_t transfer_handle,
                                      struct pldm_msg* msg)
{
    if (NULL == msg)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    struct pldm_header_info header;
    header.msg_type = PLDM_RESPONSE;
    header.instance = instance_id;
    header.pldm_type = PLDM_RDE;
    header.command = PLDM_GET_SCHEMA_DICTIONARY;
    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
    if (rc != PLDM_SUCCESS)
    {
        return rc;
    }
    struct pldm_rde_get_schema_dictionary_resp* response =
        (struct pldm_rde_get_schema_dictionary_resp*)msg->payload;
    response->completion_code = completion_code;
    if (response->completion_code != PLDM_SUCCESS)
    {
        return PLDM_SUCCESS;
    }
    response->dictionary_format = dictionary_format;
    response->transfer_handle = htole32(transfer_handle);
    return PLDM_SUCCESS;
}

int decode_get_schema_dictionary_resp(const struct pldm_msg* msg,
                                      size_t payload_length,
                                      uint8_t* completion_code,
                                      uint8_t* dictionary_format,
                                      uint32_t* transfer_handle)
{
    if ((msg == NULL) || (dictionary_format == NULL) ||
        (completion_code == NULL) || (transfer_handle == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }

    *completion_code = msg->payload[0];

    if (PLDM_SUCCESS != *completion_code)
    {
        stdplus::print(stderr,
                       "Unsuccessful completion code received in schema: {}\n",
                       static_cast<uint8_t>(*completion_code));
        return PLDM_SUCCESS;
    }

    if (payload_length < RDE_GET_DICTIONARY_SCHEMA_RESP_BYTES)
    {
        fprintf(stderr, "Unsuccessful completion code received %x",
                (uint8_t)(*completion_code));
        return PLDM_ERROR_INVALID_LENGTH;
    }

    struct pldm_rde_get_schema_dictionary_resp* response =
        (struct pldm_rde_get_schema_dictionary_resp*)msg->payload;
    *dictionary_format = response->dictionary_format;
    *transfer_handle = le32toh(response->transfer_handle);
    return PLDM_SUCCESS;
}

int encode_rde_multipart_receive_req(uint8_t instance_id,
                                     uint32_t data_transfer_handle,
                                     uint16_t operation_id,
                                     uint8_t transfer_operation,
                                     struct pldm_msg* msg)
{
    if (msg == NULL)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    struct pldm_header_info header;
    header.instance = instance_id;
    header.pldm_type = PLDM_RDE;
    header.msg_type = PLDM_REQUEST;
    header.command = PLDM_RDE_MULTIPART_RECEIVE;
    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
    if (rc != PLDM_SUCCESS)
    {
        return rc;
    }
    struct pldm_rde_multipart_receive_req* req =
        (struct pldm_rde_multipart_receive_req*)msg->payload;
    req->data_transfer_handle = htole32(data_transfer_handle);
    req->operation_id = htole16(operation_id);
    req->transfer_operation = transfer_operation;
    return PLDM_SUCCESS;
}

int decode_rde_multipart_receive_req(const struct pldm_msg* msg,
                                     size_t payload_length,
                                     uint32_t* data_transfer_handle,
                                     uint16_t* operation_id,
                                     uint8_t* transfer_operation)
{
    if ((msg == NULL) || (data_transfer_handle == NULL) ||
        (operation_id == NULL) || (transfer_operation == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    if (payload_length != sizeof(struct pldm_rde_multipart_receive_req))
    {
        return PLDM_ERROR_INVALID_LENGTH;
    }
    struct pldm_rde_multipart_receive_req* request =
        (struct pldm_rde_multipart_receive_req*)msg->payload;
    *data_transfer_handle = le32toh(request->data_transfer_handle);
    *operation_id = le16toh(request->operation_id);
    *transfer_operation = request->transfer_operation;
    if (*transfer_operation > PLDM_RDE_XFER_ABORT)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    return PLDM_SUCCESS;
}

int encode_rde_multipart_receive_resp(
    uint8_t instance_id, uint8_t completion_code, uint8_t transfer_flag,
    uint32_t next_data_transfer_handle, uint32_t data_length_bytes,
    bool add_checksum, uint32_t checksum, const uint8_t* payload,
    struct pldm_msg* msg)
{
    if (NULL == msg)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    struct pldm_header_info header;
    header.msg_type = PLDM_RESPONSE;
    header.instance = instance_id;
    header.pldm_type = PLDM_RDE;
    header.command = PLDM_RDE_MULTIPART_RECEIVE;
    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
    if (rc != PLDM_SUCCESS)
    {
        return rc;
    }
    struct pldm_rde_multipart_receive_resp* response =
        (struct pldm_rde_multipart_receive_resp*)msg->payload;
    response->completion_code = completion_code;
    if (response->completion_code != PLDM_SUCCESS)
    {
        return PLDM_SUCCESS;
    }
    response->transfer_flag = transfer_flag;
    response->next_data_transfer_handle = htole32(next_data_transfer_handle);
    memcpy(response->payload, (uint8_t*)payload, data_length_bytes);
    uint32_t tot_length = data_length_bytes;
    if (add_checksum)
    {
        tot_length += 4;
        checksum = htole32(checksum);
        memcpy(response->payload + data_length_bytes, &checksum,
               sizeof(uint32_t));
    }
    response->data_length_bytes = htole32(tot_length);
    return PLDM_SUCCESS;
}

int decode_rde_multipart_receive_resp(
    const struct pldm_msg* msg, size_t payload_length, uint8_t* completion_code,
    uint8_t* ret_transfer_flag, uint32_t* ret_data_transfer_handle,
    uint32_t* data_length_bytes, uint8_t** payload)
{
    if ((msg == NULL) || (completion_code == NULL) ||
        (ret_transfer_flag == NULL) || (ret_data_transfer_handle == NULL) ||
        (data_length_bytes == NULL) || (payload == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }

    *completion_code = msg->payload[0];

    if (PLDM_SUCCESS != *completion_code)
    {
        stdplus::print(
            stderr, "Unsuccessful completion code received in multipart: {}\n",
            static_cast<uint8_t>(*completion_code));
        return PLDM_ERROR;
    }

    if (payload_length < RDE_MULTIPART_RECV_MINIMUM_RESP_BYTES)
    {
        stdplus::print(
            stderr,
            "Decoded successfully with failed payload length in multipart"
            " with payload length: {} and expected: {}\n",
            payload_length, RDE_MULTIPART_RECV_MINIMUM_RESP_BYTES);
        return PLDM_ERROR_INVALID_LENGTH;
    }

    struct pldm_rde_multipart_receive_resp* response =
        (struct pldm_rde_multipart_receive_resp*)msg->payload;
    *ret_transfer_flag = response->transfer_flag;
    *ret_data_transfer_handle = le32toh(response->next_data_transfer_handle);
    *data_length_bytes = le32toh(response->data_length_bytes);
    *payload = &response->payload[0];
    return PLDM_SUCCESS;
}

int encode_rde_operation_init_req(
    uint8_t instance_id, uint32_t resource_id, uint16_t operation_id,
    uint8_t operation_type,
    const union pldm_rde_operation_flags* operation_flags,
    uint32_t send_data_transfer_handle, uint8_t operation_locator_length,
    uint32_t request_payload_length, const uint8_t* operation_locator,
    uint8_t* request_payload, struct pldm_msg* msg)
{
    if ((msg == NULL) || (operation_flags == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    if ((operation_locator_length > 0) && (operation_locator == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    if ((request_payload_length > 0) && (request_payload == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    struct pldm_header_info header;
    header.instance = instance_id;
    header.pldm_type = PLDM_RDE;
    header.msg_type = PLDM_REQUEST;
    header.command = PLDM_RDE_OPERATION_INIT;
    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
    if (rc != PLDM_SUCCESS)
    {
        return rc;
    }
    struct pldm_rde_operation_init_req* req =
        (struct pldm_rde_operation_init_req*)msg->payload;
    req->resource_id = htole32(resource_id);
    req->operation_id = htole16(operation_id);
    req->operation_type = operation_type;
    req->operation_flags.byte = operation_flags->byte;
    req->send_data_transfer_handle = htole32(send_data_transfer_handle);
    req->operation_locator_length = operation_locator_length;
    req->request_payload_length = htole32(request_payload_length);
    if (operation_locator_length > 0)
    {
        memcpy(req->var_data, (uint8_t*)operation_locator,
               operation_locator_length);
    }
    if (request_payload_length > 0)
    {
        memcpy(req->var_data + operation_locator_length,
               (uint8_t*)request_payload, request_payload_length);
        request_payload = NULL;
    }
    return PLDM_SUCCESS;
}

static bool pldm_rde_is_valid_mc_op_id(uint16_t operation_id)
{
    // Operation identifiers with the MSBit set are reserved for use by the
    // MC. Operation identifiers with the MSBit clear are reserved for use
    // by the RDE Device. The value 0x0000 is reserved to indicate no
    // Operation.
    if ((operation_id == 0) || ((operation_id >> 15) == 0))
    {
        return false;
    }
    return true;
}

int decode_rde_operation_init_req(
    const struct pldm_msg* msg, size_t payload_length, uint32_t* resource_id,
    uint16_t* operation_id, uint8_t* operation_type,
    union pldm_rde_operation_flags* operation_flags,
    uint32_t* send_data_transfer_handle, uint8_t* operation_locator_length,
    uint32_t* request_payload_length, uint8_t** operation_locator,
    uint8_t** request_payload)
{
    if ((msg == NULL) || (resource_id == NULL) || (operation_id == NULL) ||
        (operation_type == NULL) || (operation_flags == NULL) ||
        (send_data_transfer_handle == NULL) ||
        (operation_locator_length == NULL) || (request_payload_length == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    if (payload_length < PLDM_RDE_OPERATION_INIT_REQ_HDR_SIZE)
    {
        return PLDM_ERROR_INVALID_LENGTH;
    }
    struct pldm_rde_operation_init_req* request =
        (struct pldm_rde_operation_init_req*)msg->payload;
    *operation_id = le16toh(request->operation_id);
    if (!pldm_rde_is_valid_mc_op_id(*operation_id))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    *resource_id = le32toh(request->resource_id);
    *operation_type = request->operation_type;
    operation_flags->byte = request->operation_flags.byte;
    *send_data_transfer_handle = le32toh(request->send_data_transfer_handle);
    *operation_locator_length = request->operation_locator_length;
    *request_payload_length = le32toh(request->request_payload_length);
    if (*operation_locator_length > 0)
    {
        *operation_locator = request->var_data;
    }
    else
    {
        *operation_locator = NULL;
    }
    if (*request_payload_length > 0)
    {
        *request_payload = request->var_data + *operation_locator_length;
    }
    else
    {
        *request_payload = NULL;
    }
    return PLDM_SUCCESS;
}

int encode_rde_operation_init_resp(
    uint8_t instance_id, uint8_t completion_code, uint8_t operation_status,
    uint8_t completion_percentage, uint32_t completion_time_seconds,
    const union pldm_rde_op_execution_flags* operation_execution_flags,
    uint32_t result_transfer_handle,
    const union pldm_rde_permission_flags* permission_flags,
    uint32_t response_payload_length,
    enum pldm_rde_varstring_format etag_format, const char* etag,
    const uint8_t* response_payload, struct pldm_msg* msg)
{
    if ((msg == NULL) || (operation_execution_flags == NULL) ||
        (permission_flags == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    if ((response_payload_length > 0) && (response_payload == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    struct pldm_header_info header;
    header.msg_type = PLDM_RESPONSE;
    header.instance = instance_id;
    header.pldm_type = PLDM_RDE;
    header.command = PLDM_RDE_OPERATION_INIT;
    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
    if (rc != PLDM_SUCCESS)
    {
        return rc;
    }
    struct pldm_rde_operation_init_resp* response =
        (struct pldm_rde_operation_init_resp*)msg->payload;
    response->completion_code = completion_code;
    if (response->completion_code != PLDM_SUCCESS)
    {
        return PLDM_SUCCESS;
    }
    response->operation_status = operation_status;
    response->completion_percentage = completion_percentage;
    response->completion_time_seconds = htole32(completion_time_seconds);
    response->operation_execution_flags.byte = operation_execution_flags->byte;
    response->result_transfer_handle = htole32(result_transfer_handle);
    response->permission_flags.byte = permission_flags->byte;
    response->response_payload_length = htole32(response_payload_length);
    struct pldm_rde_varstring* resp_etag =
        (struct pldm_rde_varstring*)response->var_data;
    resp_etag->string_format = etag_format;
    // length should include NULL terminator.
    size_t etag_len_wo_null = strlen(etag);
    resp_etag->string_length_bytes = etag_len_wo_null + 1;
    // Copy including NULL terminator.
    memcpy(resp_etag->string_data, etag, resp_etag->string_length_bytes);
    // Copy the payload.
    if (response_payload_length > 0)
    {
        memcpy(response->var_data + sizeof(struct pldm_rde_varstring) +
                   etag_len_wo_null,
               (uint8_t*)response_payload, response_payload_length);
    }
    return PLDM_SUCCESS;
}

int decode_rde_operation_init_resp(
    const struct pldm_msg* msg, size_t payload_length, uint8_t* completion_code,
    uint8_t* completion_percentage, uint8_t* operation_status,
    uint32_t* completion_time_seconds, uint32_t* result_transfer_handle,
    uint32_t* response_payload_length,
    union pldm_rde_permission_flags** permission_flags,
    union pldm_rde_op_execution_flags** operation_execution_flags,
    struct pldm_rde_varstring** resp_etag, uint8_t** response_payload)
{
    if (msg == NULL)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    *completion_code = msg->payload[0];
    if (PLDM_SUCCESS != *completion_code)
    {
        fprintf(stderr,
                "Unsuccessful completion code received in op init: %x\n",
                (uint8_t)(*completion_code));
        return PLDM_ERROR;
    }

    if (payload_length < RDE_READ_OPERATION_INIT_MIN_BYTES)
    {
        fprintf(stderr,
                "Decoded successfully with failed payload length with payload "
                "length: %zu and expected: %d\n",
                payload_length, RDE_READ_OPERATION_INIT_MIN_BYTES);
        return PLDM_ERROR_INVALID_LENGTH;
    }

    struct pldm_rde_operation_init_resp* response =
        (struct pldm_rde_operation_init_resp*)msg->payload;

    *operation_status = response->operation_status;
    *completion_percentage = response->completion_percentage;
    *completion_time_seconds = le32toh(response->completion_time_seconds);
    (*operation_execution_flags)->byte =
        response->operation_execution_flags.byte;
    *result_transfer_handle = le32toh(response->result_transfer_handle);
    (*permission_flags)->byte = response->permission_flags.byte;
    *response_payload_length = le32toh(response->response_payload_length);

    *resp_etag = (struct pldm_rde_varstring*)response->var_data;

    if (*operation_status == PLDM_RDE_OPERATION_COMPLETED)
    {
        *response_payload =
            &(*resp_etag)->string_data[0] + (*resp_etag)->string_length_bytes;
    }
    return 0;
}

int encode_rde_operation_complete_req(uint8_t instance_id, uint32_t resource_id,
                                      uint16_t operation_id,
                                      struct pldm_msg* msg)
{
    if (msg == NULL)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    struct pldm_header_info header;
    header.instance = instance_id;
    header.pldm_type = PLDM_RDE;
    header.msg_type = PLDM_REQUEST;
    header.command = PLDM_RDE_OPERATION_COMPLETE;
    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
    if (rc != PLDM_SUCCESS)
    {
        return rc;
    }
    struct pldm_rde_operation_complete_req* req =
        (struct pldm_rde_operation_complete_req*)msg->payload;
    req->resource_id = htole32(resource_id);
    req->operation_id = htole16(operation_id);
    return PLDM_SUCCESS;
}

int decode_rde_operation_complete_req(const struct pldm_msg* msg,
                                      size_t payload_length,
                                      uint32_t* resource_id,
                                      uint16_t* operation_id)
{
    if ((msg == NULL) || (resource_id == NULL) || (operation_id == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    if (payload_length < sizeof(struct pldm_rde_operation_complete_req))
    {
        return PLDM_ERROR_INVALID_LENGTH;
    }
    struct pldm_rde_operation_complete_req* request =
        (struct pldm_rde_operation_complete_req*)msg->payload;
    *resource_id = le32toh(request->resource_id);
    *operation_id = le16toh(request->operation_id);
    return PLDM_SUCCESS;
}

int encode_rde_operation_complete_resp(uint8_t instance_id,
                                       uint8_t completion_code,
                                       struct pldm_msg* msg)
{
    if (msg == NULL)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    struct pldm_header_info header;
    header.msg_type = PLDM_RESPONSE;
    header.instance = instance_id;
    header.pldm_type = PLDM_RDE;
    header.command = PLDM_RDE_OPERATION_COMPLETE;
    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
    if (rc != PLDM_SUCCESS)
    {
        return rc;
    }
    struct pldm_rde_operation_complete_resp* response =
        (struct pldm_rde_operation_complete_resp*)msg->payload;
    response->completion_code = completion_code;
    return PLDM_SUCCESS;
}

int decode_rde_operation_complete_resp(const struct pldm_msg* msg,
                                       size_t payload_length,
                                       uint8_t* completion_code)
{
    if (msg == NULL)
    {
        fprintf(stderr, "Invalid message object\n");
        return PLDM_ERROR_INVALID_DATA;
    }
    if (payload_length < 1)
    {
        fprintf(stderr, "Invalid payload length\n");
        return PLDM_ERROR_INVALID_LENGTH;
    }

    *completion_code = msg->payload[0];

    if (PLDM_SUCCESS != *completion_code)
    {
        fprintf(stderr,
                "Unsuccessful completion code received in op complete: %x\n",
                (uint8_t)(*completion_code));
        return PLDM_SUCCESS;
    }
    return PLDM_SUCCESS;
}

int encode_rde_operation_status_req(uint8_t instance_id, uint32_t resource_id,
                                    uint16_t operation_id, struct pldm_msg* msg)
{
    if (msg == NULL)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    struct pldm_header_info header;
    header.instance = instance_id;
    header.pldm_type = PLDM_RDE;
    header.msg_type = PLDM_REQUEST;
    header.command = PLDM_RDE_OPERATION_STATUS;
    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
    if (rc != PLDM_SUCCESS)
    {
        return rc;
    }
    struct pldm_rde_operation_status_req* req =
        (struct pldm_rde_operation_status_req*)msg->payload;
    req->resource_id = htole32(resource_id);
    req->operation_id = htole16(operation_id);
    return PLDM_SUCCESS;
}

int decode_rde_operation_status_req(const struct pldm_msg* msg,
                                    size_t payload_length,
                                    uint32_t* resource_id,
                                    uint16_t* operation_id)
{
    if ((msg == NULL) || (resource_id == NULL) || (operation_id == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    if (payload_length < sizeof(struct pldm_rde_operation_status_req))
    {
        return PLDM_ERROR_INVALID_LENGTH;
    }
    struct pldm_rde_operation_status_req* request =
        (struct pldm_rde_operation_status_req*)msg->payload;
    *resource_id = le32toh(request->resource_id);
    *operation_id = le16toh(request->operation_id);
    return PLDM_SUCCESS;
}

int encode_rde_operation_status_resp(
    uint8_t instance_id, uint8_t completion_code, uint8_t operation_status,
    uint8_t completion_percentage, uint32_t completion_time_seconds,
    const union pldm_rde_op_execution_flags* operation_execution_flags,
    uint32_t result_transfer_handle,
    const union pldm_rde_permission_flags* permission_flags,
    uint32_t response_payload_length,
    enum pldm_rde_varstring_format etag_format, const char* etag,
    const uint8_t* response_payload, struct pldm_msg* msg)
{
    if ((msg == NULL) || (operation_execution_flags == NULL) ||
        (permission_flags == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    if ((response_payload_length > 0) && (response_payload == NULL))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    struct pldm_header_info header;
    header.msg_type = PLDM_RESPONSE;
    header.instance = instance_id;
    header.pldm_type = PLDM_RDE;
    header.command = PLDM_RDE_OPERATION_STATUS;
    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
    if (rc != PLDM_SUCCESS)
    {
        return rc;
    }
    struct pldm_rde_operation_status_resp* response =
        (struct pldm_rde_operation_status_resp*)msg->payload;
    response->completion_code = completion_code;
    if (response->completion_code != PLDM_SUCCESS)
    {
        return PLDM_SUCCESS;
    }
    response->operation_status = operation_status;
    response->completion_percentage = completion_percentage;
    response->completion_time_seconds = htole32(completion_time_seconds);
    response->operation_execution_flags.byte = operation_execution_flags->byte;
    response->result_transfer_handle = htole32(result_transfer_handle);
    response->permission_flags.byte = permission_flags->byte;
    response->response_payload_length = htole32(response_payload_length);
    struct pldm_rde_varstring* resp_etag =
        (struct pldm_rde_varstring*)response->var_data;
    resp_etag->string_format = etag_format;
    // length should include NULL terminator.
    size_t etag_len_wo_null = strlen(etag);
    resp_etag->string_length_bytes = etag_len_wo_null + 1;
    // Copy including NULL terminator.
    memcpy(resp_etag->string_data, etag, resp_etag->string_length_bytes);
    // Copy the payload.
    if (response_payload_length > 0)
    {
        memcpy(response->var_data + sizeof(struct pldm_rde_varstring) +
                   etag_len_wo_null,
               (uint8_t*)response_payload, response_payload_length);
    }
    return PLDM_SUCCESS;
}

int decode_rde_operation_status_resp(
    const struct pldm_msg* msg, size_t payload_length, uint8_t* completion_code,
    uint8_t* completion_percentage, uint8_t* operation_status,
    uint32_t* completion_time_seconds, uint32_t* result_transfer_handle,
    uint32_t* response_payload_length,
    union pldm_rde_permission_flags** permission_flags,
    union pldm_rde_op_execution_flags** operation_execution_flags,
    struct pldm_rde_varstring** resp_etag, uint8_t** response_payload)
{
    if (msg == NULL)
    {
        stdplus::print(stderr, "Invalid msg object\n");
        return PLDM_ERROR_INVALID_DATA;
    }

    *completion_code = msg->payload[0];
    if (PLDM_SUCCESS != *completion_code)
    {
        stdplus::print(
            stderr, "Unsuccessful completion code received in op status: {}\n",
            static_cast<uint8_t>(*completion_code));
        return PLDM_SUCCESS;
    }

    if (payload_length < RDE_READ_OPERATION_INIT_MIN_BYTES)
    {
        stdplus::print(stderr,
                       "Decoded sucessfully with failed payload length\n");
        return PLDM_ERROR_INVALID_LENGTH;
    }

    struct pldm_rde_operation_init_resp* response =
        (struct pldm_rde_operation_init_resp*)msg->payload;

    *operation_status = response->operation_status;
    *completion_percentage = response->completion_percentage;
    *completion_time_seconds = le32toh(response->completion_time_seconds);
    (*operation_execution_flags)->byte =
        response->operation_execution_flags.byte;
    *result_transfer_handle = le32toh(response->result_transfer_handle);
    (*permission_flags)->byte = response->permission_flags.byte;
    *response_payload_length = le32toh(response->response_payload_length);

    *resp_etag = (struct pldm_rde_varstring*)response->var_data;
    if (*operation_status == PLDM_RDE_OPERATION_COMPLETED)
    {
        *response_payload =
            &(*resp_etag)->string_data[0] + (*resp_etag)->string_length_bytes;
    }
    return 0;
}

int encode_rde_operation_kill_req(uint8_t instance_id, uint32_t resource_id,
                                  uint16_t operation_id, struct pldm_msg* msg)
{
    if (msg == NULL)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    struct pldm_header_info header;
    header.instance = instance_id;
    header.pldm_type = PLDM_RDE;
    header.msg_type = PLDM_REQUEST;
    header.command = PLDM_RDE_OPERATION_KILL;
    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
    if (rc != PLDM_SUCCESS)
    {
        return rc;
    }
    struct pldm_rde_operation_kill_req* req =
        (struct pldm_rde_operation_kill_req*)msg->payload;
    req->resource_id = htole32(resource_id);
    req->operation_id = htole16(operation_id);
    req->killflags.byte = 4;
    return PLDM_SUCCESS;
}
