#include "libpldmresponder/file_transfer.hpp"
#include "libpldmresponder/platform.hpp"

#include <libpldm/base.h>
#include <libpldm/file.h>

#include <algorithm>
#include <filesystem>
#include <fstream>
#include <numeric>
#include <random>
#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

namespace fs = std::filesystem;
using namespace pldm::responder;
using namespace pldm::responder::file_transfer;

using ::testing::_;
using ::testing::NiceMock;
using ::testing::Return;

// Test fixture for the standalone fileRead function
class FileReadTest : public ::testing::Test
{
  protected:
    void SetUp() override
    {
        // Create a temporary file with known content
        char tmppath[] = "/tmp/pldm_fileread_test.XXXXXX";
        dir = fs::path(mkdtemp(tmppath));
        testFilePath = dir / "testfile.bin";
        std::ofstream testFile(testFilePath, std::ios::binary);
        fileContent.resize(256);
        std::iota(fileContent.begin(), fileContent.end(), 0);
        testFile.write(reinterpret_cast<const char*>(fileContent.data()),
                       fileContent.size());
        testFile.close();
        fileSize = fileContent.size();
    }

    void TearDown() override
    {
        fs::remove_all(dir);
    }

    fs::path dir;
    fs::path testFilePath;
    std::vector<uint8_t> fileContent;
    uint32_t fileSize;
};

TEST_F(FileReadTest, SuccessCases)
{
    FILE* fp = fopen(testFilePath.c_str(), "rb");
    ASSERT_NE(fp, nullptr);

    // Read from start
    uint32_t readSize = 64;

    std::vector<uint8_t> buffer(readSize);
    EXPECT_EQ(fileRead(fp, fileSize, 0, readSize, buffer.data()), 0);
    EXPECT_EQ(0, memcmp(buffer.data(), fileContent.data(), readSize));

    // Read from middle
    uint32_t offset = 100;
    readSize = 50;
    buffer.resize(readSize);
    EXPECT_EQ(fileRead(fp, fileSize, offset, readSize, buffer.data()), 0);
    EXPECT_EQ(0, memcmp(buffer.data(), fileContent.data() + offset, readSize));

    // Test case where offset + readSize == fileSize
    offset = 128;
    readSize = fileSize - offset;
    buffer.resize(readSize);
    EXPECT_EQ(fileRead(fp, fileSize, offset, readSize, buffer.data()), 0);
    EXPECT_EQ(0, memcmp(buffer.data(), fileContent.data() + offset, readSize));

    // Read the full file
    buffer.resize(fileSize);
    EXPECT_EQ(fileRead(fp, fileSize, 0, fileSize, buffer.data()), 0);
    EXPECT_EQ(buffer, fileContent);

    fclose(fp);
}

TEST_F(FileReadTest, FailureCases)
{
    std::vector<uint8_t> buffer(10);

    // Null file pointer
    EXPECT_EQ(fileRead(nullptr, fileSize, 0, 10, buffer.data()), -1);

    FILE* fp = fopen(testFilePath.c_str(), "rb");
    ASSERT_NE(fp, nullptr);

    // Null data buffer
    EXPECT_EQ(fileRead(fp, fileSize, 0, 10, nullptr), -1);

    // Offset >= fileSize
    EXPECT_EQ(fileRead(fp, fileSize, fileSize, 1, buffer.data()), -1);
    EXPECT_EQ(fileRead(fp, fileSize, fileSize + 1, 1, buffer.data()), -1);

    // Read size > fileSize
    std::vector<uint8_t> largeBuffer(fileSize + 1);
    EXPECT_EQ(fileRead(fp, fileSize, 0, fileSize + 1, largeBuffer.data()), -1);

    // Read would go beyond file
    EXPECT_EQ(fileRead(fp, fileSize, fileSize - 5, 10, buffer.data()), -1);

    fclose(fp);
}

class FileTransferTests : public ::testing::Test
{
  protected:
    FileTransferTests() :
        event(sdeventplus::Event::get_default()),
        // platform::Handler needs a valid directory for PDRs
        pdrDir(fs::temp_directory_path() / "pldm_pdr"),
        pdrRepo(pldm_pdr_init(), pldm_pdr_destroy),
        platformHandler(nullptr, 0, nullptr, pdrDir, pdrRepo.get(), nullptr,
                        nullptr, nullptr, nullptr, nullptr, event, true),
        handler(&platformHandler)
    {}

    void SetUp() override
    {
        // Create a directory to hold the PDR JSON files
        fs::create_directories(pdrDir);

        // Create a target file that the PDR will point to
        char tmppath[] = "/tmp/pldm_target_file.XXXXXX";
        targetFileDir = fs::path(mkdtemp(tmppath));
        targetFilePath = targetFileDir / "testfile.bin";
        fileContent.resize(400);
        // Assign random values to the file
        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_int_distribution<> distrib(0, 255);
        std::generate(fileContent.begin(), fileContent.end(),
                      [&]() { return distrib(gen); });
        std::ofstream testFile(targetFilePath, std::ios::binary);
        testFile.write(reinterpret_cast<const char*>(fileContent.data()),
                       fileContent.size());
    }

    void TearDown() override
    {
        // Clean up the created directories and files
        fs::remove_all(targetFileDir);
        fs::remove_all(pdrDir);
    }

    /**
     * @brief Creates a PDR JSON file to set up the platform handler's state
     *
     * @param fileIdentifier The identifier for the file PDR
     * @param filePath The path to the file on disk
     */
    void setupPDR(uint16_t fileIdentifier, const fs::path& filePath)
    {
        uint32_t fileSize = fs::file_size(filePath);

        // Construct the JSON content
        nlohmann::json pdrJson = {
            {"fileDescriptorPDRs",
             {{{"entries",
                {{{"EntityType", 9},
                  {"Path", targetFileDir.string()},
                  {"Files",
                   {{{"FileIdentifier", fileIdentifier},
                     {"FileName", filePath.filename().string()},
                     {"FileSize", fileSize}}}}}}}}}}};

        // Write the JSON to a file in the PDR directory
        std::ofstream jsonFile(pdrDir / "test_pdr.json");
        jsonFile << pdrJson;
        jsonFile.close();

        // Use the public API to parse the PDRs and populate internal state
        const pldm::utils::DBusHandler dBusIntf;
        platformHandler.generate(dBusIntf, {pdrDir}, platformHandler.getRepo());
    }

    sdeventplus::Event event;
    fs::path pdrDir;
    std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> pdrRepo;
    pldm::responder::platform::Handler platformHandler;
    pldm::responder::file_transfer::Handler handler;
    fs::path targetFileDir;
    fs::path targetFilePath;
    std::vector<uint8_t> fileContent;
};

// Verify successfully opening a file
TEST_F(FileTransferTests, DfOpenSuccess)
{
    uint16_t fileIdentifier = 1;
    setupPDR(fileIdentifier, targetFilePath);

    std::vector<uint8_t> request_msg(
        sizeof(pldm_msg_hdr) + PLDM_DF_OPEN_REQ_BYTES);
    struct pldm_msg* openRequest =
        reinterpret_cast<struct pldm_msg*>(request_msg.data());

    struct pldm_file_df_open_req req{};
    req.file_identifier = fileIdentifier;
    size_t requestPayloadLength = PLDM_DF_OPEN_REQ_BYTES;

    int encode_rc = encode_pldm_file_df_open_req(0, &req, openRequest,
                                                 &requestPayloadLength);
    ASSERT_EQ(encode_rc, 0);

    auto response = handler.handle(0, PLDM_FILE_CMD_DF_OPEN, openRequest,
                                   PLDM_DF_OPEN_REQ_BYTES);
    ASSERT_NE(response.data(), nullptr);

    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_GE(response.size(), sizeof(pldm_msg_hdr) + PLDM_DF_OPEN_RESP_BYTES);

    struct pldm_file_df_open_resp decoded_resp{};
    decode_pldm_file_df_open_resp(
        responsePtr, response.size() - sizeof(pldm_msg_hdr), &decoded_resp);
    ASSERT_EQ(decoded_resp.completion_code, PLDM_SUCCESS);
}

// Invalid DfOpen request length
TEST_F(FileTransferTests, InvalidDfOpenRequestLength)
{
    pldm_msg request{};
    // Use an incorrect payload length
    size_t invalidPayloadLength = PLDM_DF_OPEN_REQ_BYTES - 1;

    // FIX: Use the correct 'handle' method name
    auto response = handler.handle(0, PLDM_FILE_CMD_DF_OPEN, &request,
                                   invalidPayloadLength);

    ASSERT_NE(response.data(), nullptr);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    EXPECT_EQ(responsePtr->payload[0], PLDM_ERROR);
}

// Successfully open a file and read a section
TEST_F(FileTransferTests, DfOpenAndRead)
{
    // Setup PDR for the test file
    uint16_t fileIdentifier = 1;
    setupPDR(fileIdentifier, targetFilePath);

    // Open the file via dfOpen
    std::vector<uint8_t> openRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_DF_OPEN_REQ_BYTES);
    auto openRequest = reinterpret_cast<pldm_msg*>(openRequestMsg.data());
    struct pldm_file_df_open_req req{};
    req.file_identifier = fileIdentifier;
    size_t openRequestPayloadLength = PLDM_DF_OPEN_REQ_BYTES;

    int rc = encode_pldm_file_df_open_req(0, &req, openRequest,
                                          &openRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    auto openResponse = handler.handle(0, PLDM_FILE_CMD_DF_OPEN, openRequest,
                                       PLDM_DF_OPEN_REQ_BYTES);
    ASSERT_NE(openResponse.data(), nullptr);

    auto openResponsePtr = reinterpret_cast<pldm_msg*>(openResponse.data());
    struct pldm_file_df_open_resp decodedOpenResp{};
    decode_pldm_file_df_open_resp(openResponsePtr,
                                  openResponse.size() - sizeof(pldm_msg_hdr),
                                  &decodedOpenResp);
    ASSERT_EQ(decodedOpenResp.completion_code, PLDM_SUCCESS);

    uint16_t fileDescriptor = decodedOpenResp.file_descriptor;

    // Read a portion of the file via dfRead
    uint32_t offset = 10;
    uint32_t lengthToRead = 64;
    std::vector<uint8_t> readRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    auto readRequest = reinterpret_cast<pldm_msg*>(readRequestMsg.data());
    size_t readRequestPayloadLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES;
    struct pldm_base_multipart_receive_req read_req{};
    read_req.pldm_type = PLDM_FILE;
    read_req.transfer_opflag = PLDM_XFER_FIRST_PART;
    read_req.transfer_ctx = fileDescriptor;
    read_req.transfer_handle = 0;
    read_req.section_offset = offset;
    read_req.section_length = lengthToRead;
    rc = encode_pldm_base_multipart_receive_req(0, &read_req, readRequest,
                                                &readRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handlers
    auto readResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest,
                                       PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    ASSERT_NE(readResponse.data(), nullptr);

    // Verify the response
    auto readResponsePtr = reinterpret_cast<pldm_msg*>(readResponse.data());

    uint32_t data_integrity_checksum;
    pldm_base_multipart_receive_resp resp;
    ASSERT_EQ(decode_pldm_base_multipart_receive_resp(
                  readResponsePtr, readResponse.size() - sizeof(pldm_msg_hdr),
                  &resp, &data_integrity_checksum),
              0);

    EXPECT_EQ(resp.completion_code, PLDM_SUCCESS);
    EXPECT_EQ(resp.transfer_flag, PLDM_START_AND_END);
    EXPECT_EQ(resp.data.length, lengthToRead);

    const uint8_t* responseData = resp.data.ptr;
    EXPECT_EQ(0,
              memcmp(responseData, fileContent.data() + offset, lengthToRead));

    EXPECT_EQ(data_integrity_checksum,
              pldm_edac_crc32(responseData, lengthToRead));
}

// Opening a file with an invalid file identifier
TEST_F(FileTransferTests, InvalidFileIdentifier)
{
    // Setup: We set up a PDR for a specific ID.
    uint16_t validFileIdentifier = 1;
    setupPDR(validFileIdentifier, targetFilePath);

    // Create request for a DIFFERENT, invalid ID.
    uint16_t invalidFileIdentifier = 99;
    pldm_msg request{};
    struct pldm_file_df_open_req req{};
    req.file_identifier = invalidFileIdentifier;
    size_t requestPayloadLength = PLDM_DF_OPEN_REQ_BYTES;

    int encode_rc =
        encode_pldm_file_df_open_req(0, &req, &request, &requestPayloadLength);
    ASSERT_EQ(encode_rc, 0);

    // Process request and check for the expected error.
    auto response = handler.handle(0, PLDM_FILE_CMD_DF_OPEN, &request,
                                   PLDM_DF_OPEN_REQ_BYTES);
    ASSERT_NE(response.data(), nullptr);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());

    struct pldm_file_df_open_resp decodedOpenResp{};
    ASSERT_EQ(decode_pldm_file_df_open_resp(
                  responsePtr, response.size() - sizeof(pldm_msg_hdr),
                  &decodedOpenResp),
              0);
    ASSERT_EQ(decodedOpenResp.completion_code,
              PLDM_FILE_CC_INVALID_FILE_IDENTIFIER);
}

// Successfully open a file and close it
TEST_F(FileTransferTests, OpenAndClose)
{
    uint16_t fileIdentifier = 1;
    setupPDR(fileIdentifier, targetFilePath);

    std::vector<uint8_t> openeRquestMsg(
        sizeof(pldm_msg_hdr) + PLDM_DF_OPEN_REQ_BYTES);
    struct pldm_msg* openRequest =
        reinterpret_cast<struct pldm_msg*>(openeRquestMsg.data());

    struct pldm_file_df_open_req req{};
    req.file_identifier = fileIdentifier;
    size_t requestPayloadLength = PLDM_DF_OPEN_REQ_BYTES;

    int encode_rc = encode_pldm_file_df_open_req(0, &req, openRequest,
                                                 &requestPayloadLength);
    ASSERT_EQ(encode_rc, 0);

    // Send the request to the handler
    auto response = handler.handle(0, PLDM_FILE_CMD_DF_OPEN, openRequest,
                                   PLDM_DF_OPEN_REQ_BYTES);
    ASSERT_NE(response.data(), nullptr);

    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    struct pldm_file_df_open_resp decoded_resp{};
    decode_pldm_file_df_open_resp(
        responsePtr, response.size() - sizeof(pldm_msg_hdr), &decoded_resp);
    uint16_t new_fd = decoded_resp.file_descriptor;

    std::vector<uint8_t> closeRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_DF_CLOSE_REQ_BYTES);
    struct pldm_msg* closeRequest =
        reinterpret_cast<struct pldm_msg*>(closeRequestMsg.data());

    struct pldm_file_df_close_req close_req{};
    close_req.file_descriptor = new_fd;
    size_t closePayloadLength = PLDM_DF_CLOSE_REQ_BYTES;
    encode_rc = encode_pldm_file_df_close_req(0, &close_req, closeRequest,
                                              &closePayloadLength);
    ASSERT_EQ(encode_rc, 0);

    // Send the request to the handler
    auto close_response = handler.handle(0, PLDM_FILE_CMD_DF_CLOSE,
                                         closeRequest, PLDM_DF_CLOSE_REQ_BYTES);

    ASSERT_NE(close_response.data(), nullptr);
    auto closeResponsePtr = reinterpret_cast<pldm_msg*>(close_response.data());
    EXPECT_EQ(closeResponsePtr->payload[0], PLDM_SUCCESS);
}

// Close with a invalid file descriptor
TEST_F(FileTransferTests, DfCloseInvalidFileDescriptor)
{
    // Attempt to close a file descriptor that was never opened.
    uint16_t invalidFileDescriptor = 999;
    std::vector<uint8_t> requestMsg(
        sizeof(pldm_msg_hdr) + PLDM_DF_CLOSE_REQ_BYTES);
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());

    struct pldm_file_df_close_req req{};
    req.file_descriptor = invalidFileDescriptor;
    size_t payloadLength = PLDM_DF_CLOSE_REQ_BYTES;
    int rc = encode_pldm_file_df_close_req(0, &req, request, &payloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto response = handler.handle(0, PLDM_FILE_CMD_DF_CLOSE, request,
                                   PLDM_DF_CLOSE_REQ_BYTES);

    ASSERT_NE(response.data(), nullptr);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    EXPECT_EQ(responsePtr->payload[0], PLDM_FILE_CC_INVALID_FILE_DESCRIPTOR);
}

// Invalid DfClose request length
TEST_F(FileTransferTests, DfCloseInvalidRequestLength)
{
    // Attempt to close with an incorrect payload length.
    uint16_t fileDescriptor = 123; // Can be any value
    std::vector<uint8_t> requestMsg(
        sizeof(pldm_msg_hdr) + PLDM_DF_CLOSE_REQ_BYTES);
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());

    struct pldm_file_df_close_req req{};
    req.file_descriptor = fileDescriptor;
    size_t payloadLength = PLDM_DF_CLOSE_REQ_BYTES;
    int rc = encode_pldm_file_df_close_req(0, &req, request, &payloadLength);
    ASSERT_EQ(rc, 0);

    // Use an invalid length
    size_t invalidPayloadLength = PLDM_DF_CLOSE_REQ_BYTES - 1;
    auto response = handler.handle(0, PLDM_FILE_CMD_DF_CLOSE, request,
                                   invalidPayloadLength);

    ASSERT_NE(response.data(), nullptr);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    EXPECT_EQ(responsePtr->payload[0], PLDM_ERROR);
}

// Open and read a file completely with multiple multipart request messages
TEST_F(FileTransferTests, DfReadCompleteFile)
{
    uint16_t fileIdentifier = 2;
    setupPDR(fileIdentifier, targetFilePath);

    std::vector<uint8_t> openRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_DF_OPEN_REQ_BYTES);
    auto openRequest = reinterpret_cast<pldm_msg*>(openRequestMsg.data());
    struct pldm_file_df_open_req req{};
    req.file_identifier = fileIdentifier;
    size_t openRequestPayloadLength = PLDM_DF_OPEN_REQ_BYTES;

    int rc = encode_pldm_file_df_open_req(0, &req, openRequest,
                                          &openRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto openResponse = handler.handle(0, PLDM_FILE_CMD_DF_OPEN, openRequest,
                                       PLDM_DF_OPEN_REQ_BYTES);
    ASSERT_NE(openResponse.data(), nullptr);

    auto openResponsePtr = reinterpret_cast<pldm_msg*>(openResponse.data());
    struct pldm_file_df_open_resp decodedOpenResp{};
    decode_pldm_file_df_open_resp(openResponsePtr,
                                  openResponse.size() - sizeof(pldm_msg_hdr),
                                  &decodedOpenResp);
    ASSERT_EQ(decodedOpenResp.completion_code, PLDM_SUCCESS);

    uint16_t fileDescriptor = decodedOpenResp.file_descriptor;

    // Initialize variables for multi-part read
    uint32_t offset = 0;
    uint32_t transferHandle = 0;
    uint8_t transferFlag = PLDM_XFER_FIRST_PART;
    std::vector<uint8_t> receivedData;
    uint32_t lengthToRead = fileContent.size();
    uint32_t final_checksum = 0;

    std::vector<uint8_t> readRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    auto readRequest = reinterpret_cast<pldm_msg*>(readRequestMsg.data());

    // Read the file in multiple parts
    while (transferFlag != PLDM_END && transferFlag != PLDM_START_AND_END)
    {
        struct pldm_base_multipart_receive_req read_req{};
        read_req.pldm_type = PLDM_FILE;
        read_req.transfer_opflag = transferFlag;
        read_req.transfer_ctx = fileDescriptor;
        read_req.transfer_handle = transferHandle;
        read_req.section_offset = offset;
        read_req.section_length = lengthToRead;
        size_t readRequestPayloadLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES;
        rc = encode_pldm_base_multipart_receive_req(0, &read_req, readRequest,
                                                    &readRequestPayloadLength);
        ASSERT_EQ(rc, 0);

        // Send the request to the handler
        auto readResponse =
            handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest,
                           PLDM_MULTIPART_RECEIVE_REQ_BYTES);
        ASSERT_NE(readResponse.data(), nullptr);

        auto readResponsePtr = reinterpret_cast<pldm_msg*>(readResponse.data());

        uint32_t data_integrity_checksum;
        pldm_base_multipart_receive_resp resp;
        ASSERT_EQ(decode_pldm_base_multipart_receive_resp(
                      readResponsePtr,
                      readResponse.size() - sizeof(pldm_msg_hdr), &resp,
                      &data_integrity_checksum),
                  0);

        EXPECT_EQ(resp.completion_code, PLDM_SUCCESS);

        transferFlag = resp.transfer_flag;
        final_checksum = data_integrity_checksum;
        uint32_t dataLengthBytes = resp.data.length;

        const uint8_t* responseData = resp.data.ptr;
        receivedData.insert(receivedData.end(), responseData,
                            responseData + dataLengthBytes);

        offset += dataLengthBytes;
        transferHandle = offset; // Update transferHandle for next request
        lengthToRead = 0;
        offset = 0;
    }

    // Verify that all data has been read correctly
    ASSERT_EQ(receivedData.size(), fileContent.size());
    EXPECT_EQ(0, memcmp(receivedData.data(), fileContent.data(),
                        fileContent.size()));
    EXPECT_EQ(final_checksum,
              pldm_edac_crc32(fileContent.data(), fileContent.size()));

    struct pldm_base_multipart_receive_req read_req{};
    read_req.pldm_type = PLDM_FILE;
    read_req.transfer_opflag = PLDM_XFER_COMPLETE;
    read_req.transfer_ctx = fileDescriptor;
    size_t readRequestPayloadLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES;
    rc = encode_pldm_base_multipart_receive_req(0, &read_req, readRequest,
                                                &readRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto readResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest,
                                       PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    ASSERT_NE(readResponse.data(), nullptr);
    auto readResponsePtr = reinterpret_cast<pldm_msg*>(readResponse.data());

    uint32_t data_integrity_checksum;
    pldm_base_multipart_receive_resp resp;
    ASSERT_EQ(decode_pldm_base_multipart_receive_resp(
                  readResponsePtr, readResponse.size() - sizeof(pldm_msg_hdr),
                  &resp, &data_integrity_checksum),
              0);

    EXPECT_EQ(resp.completion_code, PLDM_SUCCESS);
    EXPECT_EQ(resp.transfer_flag, PLDM_ACKNOWLEDGE_COMPLETION);
}

// Open and read a file at a given offset
TEST_F(FileTransferTests, DfReadWithOffset)
{
    uint16_t fileIdentifier = 3;
    setupPDR(fileIdentifier, targetFilePath);

    std::vector<uint8_t> openRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_DF_OPEN_REQ_BYTES);
    auto openRequest = reinterpret_cast<pldm_msg*>(openRequestMsg.data());
    struct pldm_file_df_open_req req{};
    req.file_identifier = fileIdentifier;
    size_t openRequestPayloadLength = PLDM_DF_OPEN_REQ_BYTES;

    int rc = encode_pldm_file_df_open_req(0, &req, openRequest,
                                          &openRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto openResponse = handler.handle(0, PLDM_FILE_CMD_DF_OPEN, openRequest,
                                       PLDM_DF_OPEN_REQ_BYTES);
    ASSERT_NE(openResponse.data(), nullptr);

    auto openResponsePtr = reinterpret_cast<pldm_msg*>(openResponse.data());
    struct pldm_file_df_open_resp decodedOpenResp{};
    decode_pldm_file_df_open_resp(openResponsePtr,
                                  openResponse.size() - sizeof(pldm_msg_hdr),
                                  &decodedOpenResp);
    ASSERT_EQ(decodedOpenResp.completion_code, PLDM_SUCCESS);

    uint16_t fileDescriptor = decodedOpenResp.file_descriptor;

    uint32_t offset = 35;
    uint32_t lengthToRead = 100;
    std::vector<uint8_t> readRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    auto readRequest = reinterpret_cast<pldm_msg*>(readRequestMsg.data());
    size_t readRequestPayloadLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES;
    struct pldm_base_multipart_receive_req read_req{};
    read_req.pldm_type = PLDM_FILE;
    read_req.transfer_opflag = PLDM_XFER_FIRST_PART;
    read_req.transfer_ctx = fileDescriptor;
    read_req.transfer_handle = 0;
    read_req.section_offset = offset;
    read_req.section_length = lengthToRead;
    rc = encode_pldm_base_multipart_receive_req(0, &read_req, readRequest,
                                                &readRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto readResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest,
                                       PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    ASSERT_NE(readResponse.data(), nullptr);
    auto readResponsePtr = reinterpret_cast<pldm_msg*>(readResponse.data());

    uint32_t data_integrity_checksum;
    pldm_base_multipart_receive_resp resp;
    ASSERT_EQ(decode_pldm_base_multipart_receive_resp(
                  readResponsePtr, readResponse.size() - sizeof(pldm_msg_hdr),
                  &resp, &data_integrity_checksum),
              0);

    EXPECT_EQ(resp.completion_code, PLDM_SUCCESS);
    EXPECT_EQ(resp.transfer_flag, PLDM_START_AND_END);
    EXPECT_EQ(resp.data.length, lengthToRead);

    const uint8_t* responseData = resp.data.ptr;
    EXPECT_EQ(0,
              memcmp(responseData, fileContent.data() + offset, lengthToRead));
}

// Open and read a file then restart read without closing the file
TEST_F(FileTransferTests, DfReadRestart)
{
    uint16_t fileIdentifier = 4;
    setupPDR(fileIdentifier, targetFilePath);

    std::vector<uint8_t> openRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_DF_OPEN_REQ_BYTES);
    auto openRequest = reinterpret_cast<pldm_msg*>(openRequestMsg.data());
    struct pldm_file_df_open_req req{};
    req.file_identifier = fileIdentifier;
    size_t openRequestPayloadLength = PLDM_DF_OPEN_REQ_BYTES;

    int rc = encode_pldm_file_df_open_req(0, &req, openRequest,
                                          &openRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto openResponse = handler.handle(0, PLDM_FILE_CMD_DF_OPEN, openRequest,
                                       PLDM_DF_OPEN_REQ_BYTES);
    ASSERT_NE(openResponse.data(), nullptr);

    auto openResponsePtr = reinterpret_cast<pldm_msg*>(openResponse.data());
    struct pldm_file_df_open_resp decodedOpenResp{};
    decode_pldm_file_df_open_resp(openResponsePtr,
                                  openResponse.size() - sizeof(pldm_msg_hdr),
                                  &decodedOpenResp);
    ASSERT_EQ(decodedOpenResp.completion_code, PLDM_SUCCESS);

    uint16_t fileDescriptor = decodedOpenResp.file_descriptor;

    uint32_t offset1 = 0;
    uint32_t lengthToRead1 = 100;
    std::vector<uint8_t> readRequestMsg1(
        sizeof(pldm_msg_hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    auto readRequest1 = reinterpret_cast<pldm_msg*>(readRequestMsg1.data());
    size_t readRequestPayloadLength1 = PLDM_MULTIPART_RECEIVE_REQ_BYTES;
    struct pldm_base_multipart_receive_req read_req1{};
    read_req1.pldm_type = PLDM_FILE;
    read_req1.transfer_opflag = PLDM_XFER_FIRST_PART;
    read_req1.transfer_ctx = fileDescriptor;
    read_req1.transfer_handle = 0;
    read_req1.section_offset = offset1;
    read_req1.section_length = lengthToRead1;
    rc = encode_pldm_base_multipart_receive_req(0, &read_req1, readRequest1,
                                                &readRequestPayloadLength1);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto readResponse1 = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest1,
                                        PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    ASSERT_NE(readResponse1.data(), nullptr);
    auto readResponsePtr1 = reinterpret_cast<pldm_msg*>(readResponse1.data());

    uint32_t data_integrity_checksum;
    pldm_base_multipart_receive_resp resp;
    ASSERT_EQ(decode_pldm_base_multipart_receive_resp(
                  readResponsePtr1, readResponse1.size() - sizeof(pldm_msg_hdr),
                  &resp, &data_integrity_checksum),
              0);

    EXPECT_EQ(resp.completion_code, PLDM_SUCCESS);
    EXPECT_EQ(resp.transfer_flag, PLDM_START_AND_END);
    EXPECT_EQ(resp.data.length, lengthToRead1);

    const uint8_t* responseData1 = resp.data.ptr;
    EXPECT_EQ(0, memcmp(responseData1, fileContent.data(), lengthToRead1));
    EXPECT_EQ(data_integrity_checksum,
              pldm_edac_crc32(fileContent.data(), lengthToRead1));

    uint32_t offset2 = 35;
    uint32_t lengthToRead2 = 200;
    std::vector<uint8_t> readRequestMsg2(
        sizeof(pldm_msg_hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    auto readRequest2 = reinterpret_cast<pldm_msg*>(readRequestMsg2.data());
    size_t readRequestPayloadLength2 = PLDM_MULTIPART_RECEIVE_REQ_BYTES;
    struct pldm_base_multipart_receive_req read_req2{};
    read_req2.pldm_type = PLDM_FILE;
    read_req2.transfer_opflag = PLDM_XFER_FIRST_PART;
    read_req2.transfer_ctx = fileDescriptor;
    read_req2.transfer_handle = 0;
    read_req2.section_offset = offset2;
    read_req2.section_length = lengthToRead2;
    rc = encode_pldm_base_multipart_receive_req(0, &read_req2, readRequest2,
                                                &readRequestPayloadLength2);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto readResponse2 = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest2,
                                        PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    ASSERT_NE(readResponse2.data(), nullptr);

    auto readResponsePtr2 = reinterpret_cast<pldm_msg*>(readResponse2.data());

    ASSERT_EQ(decode_pldm_base_multipart_receive_resp(
                  readResponsePtr2, readResponse2.size() - sizeof(pldm_msg_hdr),
                  &resp, &data_integrity_checksum),
              0);

    EXPECT_EQ(resp.completion_code, PLDM_SUCCESS);
    EXPECT_EQ(resp.transfer_flag, PLDM_START_AND_END);
    EXPECT_EQ(resp.data.length, lengthToRead2);

    const uint8_t* responseData2 = resp.data.ptr;
    EXPECT_EQ(0, memcmp(responseData2, fileContent.data() + offset2,
                        lengthToRead2));
    EXPECT_EQ(data_integrity_checksum,
              pldm_edac_crc32(fileContent.data() + offset2, lengthToRead2));
}

// Open and read a file then re request the current part
TEST_F(FileTransferTests, DfReadCurrentPart)
{
    uint16_t fileIdentifier = 5;
    setupPDR(fileIdentifier, targetFilePath);

    std::vector<uint8_t> openRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_DF_OPEN_REQ_BYTES);
    auto openRequest = reinterpret_cast<pldm_msg*>(openRequestMsg.data());
    struct pldm_file_df_open_req req{};
    req.file_identifier = fileIdentifier;
    size_t openRequestPayloadLength = PLDM_DF_OPEN_REQ_BYTES;

    int rc = encode_pldm_file_df_open_req(0, &req, openRequest,
                                          &openRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto openResponse = handler.handle(0, PLDM_FILE_CMD_DF_OPEN, openRequest,
                                       PLDM_DF_OPEN_REQ_BYTES);
    ASSERT_NE(openResponse.data(), nullptr);

    auto openResponsePtr = reinterpret_cast<pldm_msg*>(openResponse.data());
    struct pldm_file_df_open_resp decodedOpenResp{};
    decode_pldm_file_df_open_resp(openResponsePtr,
                                  openResponse.size() - sizeof(pldm_msg_hdr),
                                  &decodedOpenResp);
    ASSERT_EQ(decodedOpenResp.completion_code, PLDM_SUCCESS);

    uint16_t fileDescriptor = decodedOpenResp.file_descriptor;

    uint32_t offset = 10;
    uint32_t lengthToRead = 380;
    std::vector<uint8_t> readRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    auto readRequest = reinterpret_cast<pldm_msg*>(readRequestMsg.data());
    size_t readRequestPayloadLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES;

    // Send the read request for the first part
    struct pldm_base_multipart_receive_req read_req1{};
    read_req1.pldm_type = PLDM_FILE;
    read_req1.transfer_opflag = PLDM_XFER_FIRST_PART;
    read_req1.transfer_ctx = fileDescriptor;
    read_req1.transfer_handle = 0;
    read_req1.section_offset = offset;
    read_req1.section_length = lengthToRead;
    rc = encode_pldm_base_multipart_receive_req(0, &read_req1, readRequest,
                                                &readRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto readResponse1 = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest,
                                        PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    ASSERT_NE(readResponse1.data(), nullptr);
    auto readResponsePtr1 = reinterpret_cast<pldm_msg*>(readResponse1.data());

    uint32_t data_integrity_checksum;
    pldm_base_multipart_receive_resp resp;
    ASSERT_EQ(decode_pldm_base_multipart_receive_resp(
                  readResponsePtr1, readResponse1.size() - sizeof(pldm_msg_hdr),
                  &resp, &data_integrity_checksum),
              0);

    EXPECT_EQ(resp.completion_code, PLDM_SUCCESS);

    uint32_t request2TransferHandle = resp.next_transfer_handle;
    uint32_t dataLengthBytes = resp.data.length;
    ASSERT_EQ(dataLengthBytes, 239);
    EXPECT_EQ(0, memcmp(readResponsePtr1->payload +
                            PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES,
                        fileContent.data() + offset, dataLengthBytes));
    EXPECT_EQ(data_integrity_checksum,
              pldm_edac_crc32(fileContent.data() + offset, dataLengthBytes));

    // Send the read request for the next part
    struct pldm_base_multipart_receive_req read_req2{};
    read_req2.pldm_type = PLDM_FILE;
    read_req2.transfer_opflag = PLDM_XFER_NEXT_PART;
    read_req2.transfer_ctx = fileDescriptor;
    read_req2.transfer_handle = request2TransferHandle;
    readRequestPayloadLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES;
    rc = encode_pldm_base_multipart_receive_req(0, &read_req2, readRequest,
                                                &readRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto readResponse2 = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest,
                                        PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    ASSERT_NE(readResponse2.data(), nullptr);
    auto readResponsePtr2 = reinterpret_cast<pldm_msg*>(readResponse2.data());

    ASSERT_EQ(decode_pldm_base_multipart_receive_resp(
                  readResponsePtr2, readResponse2.size() - sizeof(pldm_msg_hdr),
                  &resp, &data_integrity_checksum),
              0);

    EXPECT_EQ(resp.completion_code, PLDM_SUCCESS);
    EXPECT_EQ(resp.data.length, 141);
    EXPECT_EQ(0, memcmp(readResponsePtr2->payload +
                            PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES,
                        fileContent.data() + offset + 239, resp.data.length));
    // Verify the checksum over data in both responses.
    EXPECT_EQ(data_integrity_checksum,
              pldm_edac_crc32(fileContent.data() + offset, lengthToRead));

    // Try requesting the current part
    struct pldm_base_multipart_receive_req read_req3{};
    read_req3.pldm_type = PLDM_FILE;
    read_req3.transfer_opflag = PLDM_XFER_CURRENT_PART;
    read_req3.transfer_ctx = fileDescriptor;
    read_req3.transfer_handle = request2TransferHandle;
    readRequestPayloadLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES;
    rc = encode_pldm_base_multipart_receive_req(0, &read_req3, readRequest,
                                                &readRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto readResponse3 = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest,
                                        PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    ASSERT_NE(readResponse3.data(), nullptr);
    auto readResponsePtr3 = reinterpret_cast<pldm_msg*>(readResponse3.data());

    ASSERT_EQ(decode_pldm_base_multipart_receive_resp(
                  readResponsePtr3, readResponse3.size() - sizeof(pldm_msg_hdr),
                  &resp, &data_integrity_checksum),
              0);

    EXPECT_EQ(resp.completion_code, PLDM_SUCCESS);
    EXPECT_EQ(readResponse2.size(), readResponse3.size());
    EXPECT_EQ(0, memcmp(readResponsePtr3->payload +
                            PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES,
                        fileContent.data() + offset + 239, 141));
    EXPECT_EQ(0, memcmp(readResponse2.data(), readResponse3.data(),
                        readResponse2.size()));
}

// Open and read the first part and then abort the read
TEST_F(FileTransferTests, DfReadAbort)
{
    // Setup PDR and open the file
    uint16_t fileIdentifier = 9;
    setupPDR(fileIdentifier, targetFilePath);

    std::vector<uint8_t> openRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_DF_OPEN_REQ_BYTES);
    auto openRequest = reinterpret_cast<pldm_msg*>(openRequestMsg.data());
    struct pldm_file_df_open_req req{};
    req.file_identifier = fileIdentifier;
    size_t openRequestPayloadLength = PLDM_DF_OPEN_REQ_BYTES;
    int rc = encode_pldm_file_df_open_req(0, &req, openRequest,
                                          &openRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto openResponse = handler.handle(0, PLDM_FILE_CMD_DF_OPEN, openRequest,
                                       PLDM_DF_OPEN_REQ_BYTES);
    ASSERT_NE(openResponse.data(), nullptr);
    auto openResponsePtr = reinterpret_cast<pldm_msg*>(openResponse.data());
    struct pldm_file_df_open_resp decodedOpenResp{};
    decode_pldm_file_df_open_resp(openResponsePtr,
                                  openResponse.size() - sizeof(pldm_msg_hdr),
                                  &decodedOpenResp);
    ASSERT_EQ(decodedOpenResp.completion_code, PLDM_SUCCESS);
    uint16_t fileDescriptor = decodedOpenResp.file_descriptor;

    // Send a first read request to start a transfer
    uint32_t offset = 0;
    uint32_t lengthToRead = 100;
    std::vector<uint8_t> readRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    auto readRequest = reinterpret_cast<pldm_msg*>(readRequestMsg.data());
    size_t readRequestPayloadLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES;
    struct pldm_base_multipart_receive_req read_req1{};
    read_req1.pldm_type = PLDM_FILE;
    read_req1.transfer_opflag = PLDM_XFER_FIRST_PART;
    read_req1.transfer_ctx = fileDescriptor;
    read_req1.transfer_handle = 0;
    read_req1.section_offset = offset;
    read_req1.section_length = lengthToRead;
    rc = encode_pldm_base_multipart_receive_req(0, &read_req1, readRequest,
                                                &readRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto firstReadResponse =
        handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest,
                       PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    ASSERT_NE(firstReadResponse.data(), nullptr);
    auto firstReadResponsePtr =
        reinterpret_cast<pldm_msg*>(firstReadResponse.data());
    ASSERT_EQ(firstReadResponsePtr->payload[0], PLDM_SUCCESS);

    // Send an abort request
    struct pldm_base_multipart_receive_req read_req2{};
    read_req2.pldm_type = PLDM_FILE;
    read_req2.transfer_opflag = PLDM_XFER_ABORT;
    read_req2.transfer_ctx = fileDescriptor;
    readRequestPayloadLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES;
    rc = encode_pldm_base_multipart_receive_req(0, &read_req2, readRequest,
                                                &readRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto abortResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest,
                                        PLDM_MULTIPART_RECEIVE_REQ_BYTES);

    // Verify the abort response
    ASSERT_NE(abortResponse.data(), nullptr);
    auto abortResponsePtr = reinterpret_cast<pldm_msg*>(abortResponse.data());

    uint32_t data_integrity_checksum;
    pldm_base_multipart_receive_resp resp;
    ASSERT_EQ(decode_pldm_base_multipart_receive_resp(
                  abortResponsePtr, abortResponse.size() - sizeof(pldm_msg_hdr),
                  &resp, &data_integrity_checksum),
              0);

    EXPECT_EQ(resp.completion_code, PLDM_SUCCESS);
    EXPECT_EQ(resp.transfer_flag, PLDM_ACKNOWLEDGE_COMPLETION);
    EXPECT_EQ(resp.data.length, 0);
}

// Open the file and send a read request with an invalid transfer handle
TEST_F(FileTransferTests, DfReadFirstPartInvalidTransferHandle)
{
    // Setup PDR and open the file
    uint16_t fileIdentifier = 6;
    setupPDR(fileIdentifier, targetFilePath);

    std::vector<uint8_t> openRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_DF_OPEN_REQ_BYTES);
    auto openRequest = reinterpret_cast<pldm_msg*>(openRequestMsg.data());
    struct pldm_file_df_open_req req{};
    req.file_identifier = fileIdentifier;
    size_t openRequestPayloadLength = PLDM_DF_OPEN_REQ_BYTES;
    int rc = encode_pldm_file_df_open_req(0, &req, openRequest,
                                          &openRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto openResponse = handler.handle(0, PLDM_FILE_CMD_DF_OPEN, openRequest,
                                       PLDM_DF_OPEN_REQ_BYTES);
    ASSERT_NE(openResponse.data(), nullptr);
    auto openResponsePtr = reinterpret_cast<pldm_msg*>(openResponse.data());
    struct pldm_file_df_open_resp decodedOpenResp{};
    decode_pldm_file_df_open_resp(openResponsePtr,
                                  openResponse.size() - sizeof(pldm_msg_hdr),
                                  &decodedOpenResp);
    ASSERT_EQ(decodedOpenResp.completion_code, PLDM_SUCCESS);
    uint16_t fileDescriptor = decodedOpenResp.file_descriptor;

    // Send dfRead with non-zero transfer handle for FIRST_PART
    uint32_t offset = 0;
    uint32_t lengthToRead = 64;
    uint32_t invalidTransferHandle = 1; // Should be 0 for FIRST_PART
    std::vector<uint8_t> readRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    auto readRequest = reinterpret_cast<pldm_msg*>(readRequestMsg.data());
    size_t readRequestPayloadLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES;
    struct pldm_base_multipart_receive_req read_req{};
    read_req.pldm_type = PLDM_FILE;
    read_req.transfer_opflag = PLDM_XFER_FIRST_PART;
    read_req.transfer_ctx = fileDescriptor;
    read_req.transfer_handle = invalidTransferHandle;
    read_req.section_offset = offset;
    read_req.section_length = lengthToRead;
    rc = encode_pldm_base_multipart_receive_req(0, &read_req, readRequest,
                                                &readRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto readResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest,
                                       PLDM_MULTIPART_RECEIVE_REQ_BYTES);

    // Verify the error response
    ASSERT_NE(readResponse.data(), nullptr);
    auto readResponsePtr = reinterpret_cast<pldm_msg*>(readResponse.data());

    uint32_t data_integrity_checksum;
    pldm_base_multipart_receive_resp resp;
    ASSERT_EQ(decode_pldm_base_multipart_receive_resp(
                  readResponsePtr, readResponse.size() - sizeof(pldm_msg_hdr),
                  &resp, &data_integrity_checksum),
              0);
    EXPECT_EQ(resp.completion_code, PLDM_ERROR_INVALID_DATA);
}

// Open the file and send a read request with an invalid offset
TEST_F(FileTransferTests, DfReadFirstPartInvalidOffset)
{
    // Setup PDR and open the file
    uint16_t fileIdentifier = 7;
    setupPDR(fileIdentifier, targetFilePath);

    std::vector<uint8_t> openRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_DF_OPEN_REQ_BYTES);
    auto openRequest = reinterpret_cast<pldm_msg*>(openRequestMsg.data());
    struct pldm_file_df_open_req req{};
    req.file_identifier = fileIdentifier;
    size_t openRequestPayloadLength = PLDM_DF_OPEN_REQ_BYTES;
    int rc = encode_pldm_file_df_open_req(0, &req, openRequest,
                                          &openRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto openResponse = handler.handle(0, PLDM_FILE_CMD_DF_OPEN, openRequest,
                                       PLDM_DF_OPEN_REQ_BYTES);
    ASSERT_NE(openResponse.data(), nullptr);
    auto openResponsePtr = reinterpret_cast<pldm_msg*>(openResponse.data());
    struct pldm_file_df_open_resp decodedOpenResp{};
    decode_pldm_file_df_open_resp(openResponsePtr,
                                  openResponse.size() - sizeof(pldm_msg_hdr),
                                  &decodedOpenResp);
    ASSERT_EQ(decodedOpenResp.completion_code, PLDM_SUCCESS);
    uint16_t fileDescriptor = decodedOpenResp.file_descriptor;

    // Send dfRead with offset >= fileSize
    uint32_t invalidOffset = fileContent.size(); // 400
    uint32_t lengthToRead = 1;
    std::vector<uint8_t> readRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    auto readRequest = reinterpret_cast<pldm_msg*>(readRequestMsg.data());
    size_t readRequestPayloadLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES;
    struct pldm_base_multipart_receive_req read_req{};
    read_req.pldm_type = PLDM_FILE;
    read_req.transfer_opflag = PLDM_XFER_FIRST_PART;
    read_req.transfer_ctx = fileDescriptor;
    read_req.transfer_handle = 0;
    read_req.section_offset = invalidOffset;
    read_req.section_length = lengthToRead;
    rc = encode_pldm_base_multipart_receive_req(0, &read_req, readRequest,
                                                &readRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto readResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest,
                                       PLDM_MULTIPART_RECEIVE_REQ_BYTES);

    // Verify the error response
    ASSERT_NE(readResponse.data(), nullptr);
    auto readResponsePtr = reinterpret_cast<pldm_msg*>(readResponse.data());

    uint32_t data_integrity_checksum;
    pldm_base_multipart_receive_resp resp;
    ASSERT_EQ(decode_pldm_base_multipart_receive_resp(
                  readResponsePtr, readResponse.size() - sizeof(pldm_msg_hdr),
                  &resp, &data_integrity_checksum),
              0);
    EXPECT_EQ(resp.completion_code, PLDM_ERROR_INVALID_DATA);
}

// Open the file and send a read request with an invalid read length
TEST_F(FileTransferTests, DfReadFirstPartInvalidLength)
{
    // Setup PDR and open the file
    uint16_t fileIdentifier = 8;
    setupPDR(fileIdentifier, targetFilePath);

    std::vector<uint8_t> openRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_DF_OPEN_REQ_BYTES);
    auto openRequest = reinterpret_cast<pldm_msg*>(openRequestMsg.data());
    struct pldm_file_df_open_req req{};
    req.file_identifier = fileIdentifier;
    size_t openRequestPayloadLength = PLDM_DF_OPEN_REQ_BYTES;
    int rc = encode_pldm_file_df_open_req(0, &req, openRequest,
                                          &openRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto openResponse = handler.handle(0, PLDM_FILE_CMD_DF_OPEN, openRequest,
                                       PLDM_DF_OPEN_REQ_BYTES);
    ASSERT_NE(openResponse.data(), nullptr);
    auto openResponsePtr = reinterpret_cast<pldm_msg*>(openResponse.data());
    struct pldm_file_df_open_resp decodedOpenResp{};
    decode_pldm_file_df_open_resp(openResponsePtr,
                                  openResponse.size() - sizeof(pldm_msg_hdr),
                                  &decodedOpenResp);
    ASSERT_EQ(decodedOpenResp.completion_code, PLDM_SUCCESS);
    uint16_t fileDescriptor = decodedOpenResp.file_descriptor;

    // Send dfRead with offset + length > fileSize
    uint32_t offset = 100;
    uint32_t invalidLength = fileContent.size() - offset + 1; // 301
    std::vector<uint8_t> readRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    auto readRequest = reinterpret_cast<pldm_msg*>(readRequestMsg.data());
    size_t readRequestPayloadLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES;
    struct pldm_base_multipart_receive_req read_req{};
    read_req.pldm_type = PLDM_FILE;
    read_req.transfer_opflag = PLDM_XFER_FIRST_PART;
    read_req.transfer_ctx = fileDescriptor;
    read_req.transfer_handle = 0;
    read_req.section_offset = offset;
    read_req.section_length = invalidLength;
    rc = encode_pldm_base_multipart_receive_req(0, &read_req, readRequest,
                                                &readRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto readResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest,
                                       PLDM_MULTIPART_RECEIVE_REQ_BYTES);

    // Verify the error response
    ASSERT_NE(readResponse.data(), nullptr);
    auto readResponsePtr = reinterpret_cast<pldm_msg*>(readResponse.data());

    uint32_t data_integrity_checksum;
    pldm_base_multipart_receive_resp resp;
    ASSERT_EQ(decode_pldm_base_multipart_receive_resp(
                  readResponsePtr, readResponse.size() - sizeof(pldm_msg_hdr),
                  &resp, &data_integrity_checksum),
              0);
    EXPECT_EQ(resp.completion_code, PLDM_ERROR_INVALID_DATA);
}

// Open the file and read the first part. Then send a transfer handle less than
// the start offset
TEST_F(FileTransferTests, DfReadNextPartInvalidTransferHandleTooSmall)
{
    // Setup PDR and open the file
    uint16_t fileIdentifier = 10;
    setupPDR(fileIdentifier, targetFilePath);

    // Encode the request
    std::vector<uint8_t> openRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_DF_OPEN_REQ_BYTES);
    auto openRequest = reinterpret_cast<pldm_msg*>(openRequestMsg.data());
    struct pldm_file_df_open_req req{};
    req.file_identifier = fileIdentifier;
    size_t openRequestPayloadLength = PLDM_DF_OPEN_REQ_BYTES;
    int rc = encode_pldm_file_df_open_req(0, &req, openRequest,
                                          &openRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto openResponse = handler.handle(0, PLDM_FILE_CMD_DF_OPEN, openRequest,
                                       PLDM_DF_OPEN_REQ_BYTES);
    ASSERT_NE(openResponse.data(), nullptr);
    auto openResponsePtr = reinterpret_cast<pldm_msg*>(openResponse.data());
    struct pldm_file_df_open_resp decodedOpenResp{};
    decode_pldm_file_df_open_resp(openResponsePtr,
                                  openResponse.size() - sizeof(pldm_msg_hdr),
                                  &decodedOpenResp);
    ASSERT_EQ(decodedOpenResp.completion_code, PLDM_SUCCESS);
    uint16_t fileDescriptor = decodedOpenResp.file_descriptor;

    // Send a first read request to establish starting_offset
    uint32_t offset = 100;
    uint32_t lengthToRead = 50;
    std::vector<uint8_t> readRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    auto readRequest = reinterpret_cast<pldm_msg*>(readRequestMsg.data());
    size_t readRequestPayloadLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES;
    struct pldm_base_multipart_receive_req read_req1{};
    read_req1.pldm_type = PLDM_FILE;
    read_req1.transfer_opflag = PLDM_XFER_FIRST_PART;
    read_req1.transfer_ctx = fileDescriptor;
    read_req1.transfer_handle = 0;
    read_req1.section_offset = offset;
    read_req1.section_length = lengthToRead;
    rc = encode_pldm_base_multipart_receive_req(0, &read_req1, readRequest,
                                                &readRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto firstReadResponse =
        handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest,
                       PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    ASSERT_NE(firstReadResponse.data(), nullptr);
    auto firstReadResponsePtr =
        reinterpret_cast<pldm_msg*>(firstReadResponse.data());

    uint32_t data_integrity_checksum;
    pldm_base_multipart_receive_resp resp;
    ASSERT_EQ(decode_pldm_base_multipart_receive_resp(
                  firstReadResponsePtr,
                  firstReadResponse.size() - sizeof(pldm_msg_hdr), &resp,
                  &data_integrity_checksum),
              0);
    EXPECT_EQ(resp.completion_code, PLDM_SUCCESS);

    // Send a next part request with transfer_handle < starting_offset
    uint32_t invalidTransferHandle = offset - 1;
    struct pldm_base_multipart_receive_req read_req2{};
    read_req2.pldm_type = PLDM_FILE;
    read_req2.transfer_opflag = PLDM_XFER_NEXT_PART;
    read_req2.transfer_ctx = fileDescriptor;
    read_req2.transfer_handle = invalidTransferHandle;
    readRequestPayloadLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES;
    rc = encode_pldm_base_multipart_receive_req(0, &read_req2, readRequest,
                                                &readRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto errorResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest,
                                        readRequestPayloadLength);

    // Verify the error response
    ASSERT_NE(errorResponse.data(), nullptr);
    auto errorResponsePtr = reinterpret_cast<pldm_msg*>(errorResponse.data());

    ASSERT_EQ(decode_pldm_base_multipart_receive_resp(
                  errorResponsePtr, errorResponse.size() - sizeof(pldm_msg_hdr),
                  &resp, &data_integrity_checksum),
              0);
    EXPECT_EQ(resp.completion_code, PLDM_ERROR_INVALID_DATA);
}

// Open the file and read the first part. Then send a transfer handle greater
// than the end offset
TEST_F(FileTransferTests, DfReadNextPartInvalidTransferHandleTooLarge)
{
    // Setup PDR and open the file
    uint16_t fileIdentifier = 11;
    setupPDR(fileIdentifier, targetFilePath);

    // Encode the request
    std::vector<uint8_t> openRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_DF_OPEN_REQ_BYTES);
    auto openRequest = reinterpret_cast<pldm_msg*>(openRequestMsg.data());
    struct pldm_file_df_open_req req{};
    req.file_identifier = fileIdentifier;
    size_t openRequestPayloadLength = PLDM_DF_OPEN_REQ_BYTES;
    int rc = encode_pldm_file_df_open_req(0, &req, openRequest,
                                          &openRequestPayloadLength);
    ASSERT_EQ(rc, 0);

    // Send the request to the handler
    auto openResponse = handler.handle(0, PLDM_FILE_CMD_DF_OPEN, openRequest,
                                       PLDM_DF_OPEN_REQ_BYTES);

    // Verify the response
    ASSERT_NE(openResponse.data(), nullptr);
    auto openResponsePtr = reinterpret_cast<pldm_msg*>(openResponse.data());
    struct pldm_file_df_open_resp decodedOpenResp{};
    decode_pldm_file_df_open_resp(openResponsePtr,
                                  openResponse.size() - sizeof(pldm_msg_hdr),
                                  &decodedOpenResp);
    ASSERT_EQ(decodedOpenResp.completion_code, PLDM_SUCCESS);

    // Send a first read request to establish starting_offset and section_length
    uint16_t fileDescriptor = decodedOpenResp.file_descriptor;
    uint32_t offset = 100;
    uint32_t lengthToRead = 50;
    std::vector<uint8_t> readRequestMsg(
        sizeof(pldm_msg_hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    auto readRequest = reinterpret_cast<pldm_msg*>(readRequestMsg.data());
    size_t readRequestPayloadLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES;
    struct pldm_base_multipart_receive_req read_req1{};
    read_req1.pldm_type = PLDM_FILE;
    read_req1.transfer_opflag = PLDM_XFER_FIRST_PART;
    read_req1.transfer_ctx = fileDescriptor;
    read_req1.transfer_handle = 0;
    read_req1.section_offset = offset;
    read_req1.section_length = lengthToRead;
    rc = encode_pldm_base_multipart_receive_req(0, &read_req1, readRequest,
                                                &readRequestPayloadLength);
    ASSERT_EQ(rc, 0);
    auto firstReadResponse =
        handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest,
                       PLDM_MULTIPART_RECEIVE_REQ_BYTES);
    ASSERT_NE(firstReadResponse.data(), nullptr);
    auto firstReadResponsePtr =
        reinterpret_cast<pldm_msg*>(firstReadResponse.data());

    uint32_t data_integrity_checksum;
    pldm_base_multipart_receive_resp resp;
    ASSERT_EQ(decode_pldm_base_multipart_receive_resp(
                  firstReadResponsePtr,
                  firstReadResponse.size() - sizeof(pldm_msg_hdr), &resp,
                  &data_integrity_checksum),
              0);
    EXPECT_EQ(resp.completion_code, PLDM_SUCCESS);

    // Send a next part request with transfer_handle >= starting_offset +
    // section_length
    uint32_t invalidTransferHandle = offset + lengthToRead;
    struct pldm_base_multipart_receive_req read_req2{};
    read_req2.pldm_type = PLDM_FILE;
    read_req2.transfer_opflag = PLDM_XFER_NEXT_PART;
    read_req2.transfer_ctx = fileDescriptor;
    read_req2.transfer_handle = invalidTransferHandle;
    readRequestPayloadLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES;
    rc = encode_pldm_base_multipart_receive_req(0, &read_req2, readRequest,
                                                &readRequestPayloadLength);
    ASSERT_EQ(rc, 0);
    auto errorResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest,
                                        PLDM_MULTIPART_RECEIVE_REQ_BYTES);

    // Verify the error response
    ASSERT_NE(errorResponse.data(), nullptr);
    auto errorResponsePtr = reinterpret_cast<pldm_msg*>(errorResponse.data());

    ASSERT_EQ(decode_pldm_base_multipart_receive_resp(
                  errorResponsePtr, errorResponse.size() - sizeof(pldm_msg_hdr),
                  &resp, &data_integrity_checksum),
              0);
    EXPECT_EQ(resp.completion_code, PLDM_ERROR_INVALID_DATA);
}
