#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),
        baseHandler(event), handler(&baseHandler, &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::base::Handler baseHandler;
    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);
}
