#include "libpldmresponder/base.hpp"
#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)
    {
        baseHandler.registerMultipartReceiveHandler(PLDM_FILE, &handler);
    }

    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 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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 =
            baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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 =
        baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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 =
        baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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 =
        baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, 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);
}
