#include "libpldm/base.h"
#include "libpldm/file_io.h"

#include "libpldmresponder/file_io.hpp"
#include "libpldmresponder/file_io_by_type.hpp"
#include "libpldmresponder/file_io_type_cert.hpp"
#include "libpldmresponder/file_io_type_dump.hpp"
#include "libpldmresponder/file_io_type_lid.hpp"
#include "libpldmresponder/file_io_type_pel.hpp"
#include "libpldmresponder/file_table.hpp"
#include "xyz/openbmc_project/Common/error.hpp"

#include <nlohmann/json.hpp>
#include <phosphor-logging/elog-errors.hpp>

#include <filesystem>
#include <fstream>

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

namespace fs = std::filesystem;
using Json = nlohmann::json;
using namespace pldm::filetable;
using namespace pldm::responder;

class TestFileTable : public testing::Test
{
  public:
    void SetUp() override
    {
        // Create a temporary directory to hold the config file and files to
        // populate the file table.
        char tmppldm[] = "/tmp/pldm_fileio_table.XXXXXX";
        dir = fs::path(mkdtemp(tmppldm));

        // Copy the sample image files to the directory
        fs::copy("./files", dir);

        imageFile = dir / "NVRAM-IMAGE";
        auto jsonObjects = Json::array();
        auto obj = Json::object();
        obj["path"] = imageFile.c_str();
        obj["file_traits"] = 1;

        jsonObjects.push_back(obj);
        obj.clear();
        cksumFile = dir / "NVRAM-IMAGE-CKSUM";
        obj["path"] = cksumFile.c_str();
        obj["file_traits"] = 4;
        jsonObjects.push_back(obj);

        fileTableConfig = dir / "configFile.json";
        std::ofstream file(fileTableConfig.c_str());
        file << std::setw(4) << jsonObjects << std::endl;
    }

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

    fs::path dir;
    fs::path imageFile;
    fs::path cksumFile;
    fs::path fileTableConfig;

    // <4 bytes - File handle - 0 (0x00 0x00 0x00 0x00)>,
    // <2 bytes - Filename length - 11 (0x0b 0x00>
    // <11 bytes - Filename - ASCII for NVRAM-IMAGE>
    // <4 bytes - File size - 1024 (0x00 0x04 0x00 0x00)>
    // <4 bytes - File traits - 1 (0x01 0x00 0x00 0x00)>
    // <4 bytes - File handle - 1 (0x01 0x00 0x00 0x00)>,
    // <2 bytes - Filename length - 17 (0x11 0x00>
    // <17 bytes - Filename - ASCII for NVRAM-IMAGE-CKSUM>
    // <4 bytes - File size - 16 (0x0f 0x00 0x00 0x00)>
    // <4 bytes - File traits - 4 (0x04 0x00 0x00 0x00)>
    // No pad bytes added since the length for both the file entries in the
    // table is 56, which is a multiple of 4.
    // <4 bytes - Checksum - 2088303182(0x4e 0xfa 0x78 0x7c)>
    Table attrTable = {
        0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x4e, 0x56, 0x52, 0x41, 0x4d, 0x2d,
        0x49, 0x4d, 0x41, 0x47, 0x45, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00,
        0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x4e, 0x56, 0x52, 0x41, 0x4d,
        0x2d, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x2d, 0x43, 0x4b, 0x53, 0x55, 0x4d,
        0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x4e, 0xfa, 0x78, 0x7c};
};

namespace pldm
{

namespace responder
{

namespace dma
{

class MockDMA
{
  public:
    MOCK_METHOD5(transferDataHost, int(int fd, uint32_t offset, uint32_t length,
                                       uint64_t address, bool upstream));
};

} // namespace dma
} // namespace responder
} // namespace pldm
using namespace pldm::responder;
using ::testing::_;
using ::testing::Return;

TEST(TransferDataHost, GoodPath)
{
    using namespace pldm::responder::dma;

    MockDMA dmaObj;
    char tmpfile[] = "/tmp/pldm_fileio_table.XXXXXX";
    int fd = mkstemp(tmpfile);
    close(fd);
    fs::path path(tmpfile);

    // Minimum length of 16 and expect transferDataHost to be called once
    // returns the default value of 0 (the return type of transferDataHost is
    // int, the default value for int is 0)
    uint32_t length = minSize;
    EXPECT_CALL(dmaObj, transferDataHost(_, 0, length, 0, true)).Times(1);
    auto response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY,
                                         path, 0, length, 0, true, 0);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
    ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]),
                        &length, sizeof(length)));

    // maxsize of DMA
    length = maxSize;
    EXPECT_CALL(dmaObj, transferDataHost(_, 0, length, 0, true)).Times(1);
    response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path,
                                    0, length, 0, true, 0);
    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
    ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]),
                        &length, sizeof(length)));

    // length greater than maxsize of DMA
    length = maxSize + minSize;
    EXPECT_CALL(dmaObj, transferDataHost(_, 0, maxSize, 0, true)).Times(1);
    EXPECT_CALL(dmaObj, transferDataHost(_, maxSize, minSize, maxSize, true))
        .Times(1);
    response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path,
                                    0, length, 0, true, 0);
    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
    ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]),
                        &length, sizeof(length)));

    // length greater than 2*maxsize of DMA
    length = 3 * maxSize;
    EXPECT_CALL(dmaObj, transferDataHost(_, _, _, _, true)).Times(3);
    response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path,
                                    0, length, 0, true, 0);
    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
    ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]),
                        &length, sizeof(length)));

    // check for downstream(copy data from host to BMC) parameter
    length = minSize;
    EXPECT_CALL(dmaObj, transferDataHost(_, 0, length, 0, false)).Times(1);
    response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path,
                                    0, length, 0, false, 0);
    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
    ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]),
                        &length, sizeof(length)));
}

TEST(TransferDataHost, BadPath)
{
    using namespace pldm::responder::dma;

    MockDMA dmaObj;
    char tmpfile[] = "/tmp/pldm_fileio_table.XXXXXX";
    int fd = mkstemp(tmpfile);
    close(fd);
    fs::path path(tmpfile);

    // Minimum length of 16 and transferDataHost returning a negative errno
    uint32_t length = minSize;
    EXPECT_CALL(dmaObj, transferDataHost(_, _, _, _, _)).WillOnce(Return(-1));
    auto response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY,
                                         path, 0, length, 0, true, 0);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR);

    // length greater than maxsize of DMA and transferDataHost returning a
    // negative errno
    length = maxSize + minSize;
    EXPECT_CALL(dmaObj, transferDataHost(_, _, _, _, _)).WillOnce(Return(-1));
    response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path,
                                    0, length, 0, true, 0);
    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR);
}

TEST(ReadFileIntoMemory, BadPath)
{
    uint32_t fileHandle = 0;
    uint32_t offset = 0;
    uint32_t length = 10;
    uint64_t address = 0;

    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES>
        requestMsg{};
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    memcpy(request->payload, &fileHandle, sizeof(fileHandle));
    memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset));
    memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length,
           sizeof(length));
    memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
               sizeof(length),
           &address, sizeof(address));

    // Pass invalid payload length
    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto response = handler.readFileIntoMemory(request, 0);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
}

TEST_F(TestFileTable, ReadFileInvalidFileHandle)
{
    // Invalid file handle in the file table
    uint32_t fileHandle = 2;
    uint32_t offset = 0;
    uint32_t length = 0;
    uint64_t address = 0;

    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES>
        requestMsg{};
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
    memcpy(request->payload, &fileHandle, sizeof(fileHandle));
    memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset));
    memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length,
           sizeof(length));
    memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
               sizeof(length),
           &address, sizeof(address));

    using namespace pldm::filetable;
    // Initialise the file table with 2 valid file handles 0 & 1.
    auto& table = buildFileTable(fileTableConfig.c_str());

    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto response = handler.readFileIntoMemory(request, requestPayloadLength);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
    // Clear the file table contents.
    table.clear();
}

TEST_F(TestFileTable, ReadFileInvalidOffset)
{
    uint32_t fileHandle = 0;
    // The file size is 1024, so the offset is invalid
    uint32_t offset = 1024;
    uint32_t length = 0;
    uint64_t address = 0;

    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES>
        requestMsg{};
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
    memcpy(request->payload, &fileHandle, sizeof(fileHandle));
    memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset));
    memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length,
           sizeof(length));
    memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
               sizeof(length),
           &address, sizeof(address));

    using namespace pldm::filetable;
    auto& table = buildFileTable(fileTableConfig.c_str());

    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto response = handler.readFileIntoMemory(request, requestPayloadLength);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
    // Clear the file table contents.
    table.clear();
}

TEST_F(TestFileTable, ReadFileInvalidLength)
{
    uint32_t fileHandle = 0;
    uint32_t offset = 100;
    // Length should be a multiple of dma min size(16)
    uint32_t length = 10;
    uint64_t address = 0;

    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES>
        requestMsg{};
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
    memcpy(request->payload, &fileHandle, sizeof(fileHandle));
    memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset));
    memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length,
           sizeof(length));
    memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
               sizeof(length),
           &address, sizeof(address));

    using namespace pldm::filetable;
    auto& table = buildFileTable(fileTableConfig.c_str());

    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto response = handler.readFileIntoMemory(request, requestPayloadLength);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
    // Clear the file table contents.
    table.clear();
}

TEST_F(TestFileTable, ReadFileInvalidEffectiveLength)
{
    uint32_t fileHandle = 0;
    // valid offset
    uint32_t offset = 100;
    // length + offset exceeds the size, so effective length is
    // filesize(1024) - offset(100). The effective length is not a multiple of
    // DMA min size(16)
    uint32_t length = 1024;
    uint64_t address = 0;

    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES>
        requestMsg{};
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
    memcpy(request->payload, &fileHandle, sizeof(fileHandle));
    memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset));
    memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length,
           sizeof(length));
    memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
               sizeof(length),
           &address, sizeof(address));

    using namespace pldm::filetable;
    auto& table = buildFileTable(fileTableConfig.c_str());

    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto response = handler.readFileIntoMemory(request, requestPayloadLength);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
    // Clear the file table contents.
    table.clear();
}

TEST(WriteFileFromMemory, BadPath)
{
    uint32_t fileHandle = 0;
    uint32_t offset = 0;
    uint32_t length = 10;
    uint64_t address = 0;

    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES>
        requestMsg{};
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
    memcpy(request->payload, &fileHandle, sizeof(fileHandle));
    memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset));
    memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length,
           sizeof(length));
    memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
               sizeof(length),
           &address, sizeof(address));

    // Pass invalid payload length
    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto response = handler.writeFileFromMemory(request, 0);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);

    // The length field is not a multiple of DMA minsize
    response = handler.writeFileFromMemory(request, requestPayloadLength);
    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
}

TEST_F(TestFileTable, WriteFileInvalidFileHandle)
{
    // Invalid file handle in the file table
    uint32_t fileHandle = 2;
    uint32_t offset = 0;
    uint32_t length = 16;
    uint64_t address = 0;

    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES>
        requestMsg{};
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
    memcpy(request->payload, &fileHandle, sizeof(fileHandle));
    memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset));
    memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length,
           sizeof(length));
    memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
               sizeof(length),
           &address, sizeof(address));

    using namespace pldm::filetable;
    // Initialise the file table with 2 valid file handles 0 & 1.
    auto& table = buildFileTable(fileTableConfig.c_str());

    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto response = handler.writeFileFromMemory(request, requestPayloadLength);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
    // Clear the file table contents.
    table.clear();
}

TEST_F(TestFileTable, WriteFileInvalidOffset)
{
    uint32_t fileHandle = 0;
    // The file size is 1024, so the offset is invalid
    uint32_t offset = 1024;
    uint32_t length = 16;
    uint64_t address = 0;

    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES>
        requestMsg{};
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
    memcpy(request->payload, &fileHandle, sizeof(fileHandle));
    memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset));
    memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length,
           sizeof(length));
    memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
               sizeof(length),
           &address, sizeof(address));

    using namespace pldm::filetable;
    // Initialise the file table with 2 valid file handles 0 & 1.
    auto& table = buildFileTable(TestFileTable::fileTableConfig.c_str());

    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto response = handler.writeFileFromMemory(request, requestPayloadLength);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
    // Clear the file table contents.
    table.clear();
}

TEST(FileTable, ConfigNotExist)
{
    FileTable tableObj("");
    EXPECT_EQ(tableObj.isEmpty(), true);
}

TEST_F(TestFileTable, ValidateFileEntry)
{
    FileTable tableObj(fileTableConfig.c_str());

    // Test file handle 0, the file size is 1K bytes.
    auto value = tableObj.at(0);
    ASSERT_EQ(value.handle, 0);
    ASSERT_EQ(strcmp(value.fsPath.c_str(), imageFile.c_str()), 0);
    ASSERT_EQ(static_cast<uint32_t>(fs::file_size(value.fsPath)), 1024);
    ASSERT_EQ(value.traits.value, 1);
    ASSERT_EQ(true, fs::exists(value.fsPath));

    // Test file handle 1, the file size is 16 bytes
    auto value1 = tableObj.at(1);
    ASSERT_EQ(value1.handle, 1);
    ASSERT_EQ(strcmp(value1.fsPath.c_str(), cksumFile.c_str()), 0);
    ASSERT_EQ(static_cast<uint32_t>(fs::file_size(value1.fsPath)), 16);
    ASSERT_EQ(value1.traits.value, 4);
    ASSERT_EQ(true, fs::exists(value1.fsPath));

    // Test invalid file handle
    ASSERT_THROW(tableObj.at(2), std::out_of_range);
}

TEST_F(TestFileTable, ValidateFileTable)
{
    FileTable tableObj(fileTableConfig.c_str());

    // Validate file attribute table
    auto table = tableObj();
    ASSERT_EQ(true,
              std::equal(attrTable.begin(), attrTable.end(), table.begin()));
}

TEST_F(TestFileTable, GetFileTableCommand)
{
    // Initialise the file table with a valid handle of 0 & 1
    auto& table = buildFileTable(fileTableConfig.c_str());

    uint32_t transferHandle = 0;
    uint8_t opFlag = 0;
    uint8_t type = PLDM_FILE_ATTRIBUTE_TABLE;
    uint32_t nextTransferHandle = 0;
    uint8_t transferFlag = PLDM_START_AND_END;

    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_FILE_TABLE_REQ_BYTES>
        requestMsg{};
    auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
    size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
    auto request = reinterpret_cast<pldm_get_file_table_req*>(
        requestMsg.data() + sizeof(pldm_msg_hdr));
    request->transfer_handle = transferHandle;
    request->operation_flag = opFlag;
    request->table_type = type;

    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto response = handler.getFileTable(requestMsgPtr, requestPayloadLength);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
    size_t offsetSize = sizeof(responsePtr->payload[0]);
    ASSERT_EQ(0, memcmp(responsePtr->payload + offsetSize, &nextTransferHandle,
                        sizeof(nextTransferHandle)));
    offsetSize += sizeof(nextTransferHandle);
    ASSERT_EQ(0, memcmp(responsePtr->payload + offsetSize, &transferFlag,
                        sizeof(transferFlag)));
    offsetSize += sizeof(transferFlag);
    ASSERT_EQ(0, memcmp(responsePtr->payload + offsetSize, attrTable.data(),
                        attrTable.size()));
    table.clear();
}

TEST_F(TestFileTable, GetFileTableCommandReqLengthMismatch)
{
    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_FILE_TABLE_REQ_BYTES>
        requestMsg{};
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());

    // Pass invalid command payload length
    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto response = handler.getFileTable(request, 0);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
}

TEST_F(TestFileTable, GetFileTableCommandOEMAttrTable)
{
    uint32_t transferHandle = 0;
    uint8_t opFlag = 0;
    uint8_t type = PLDM_OEM_FILE_ATTRIBUTE_TABLE;

    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_FILE_TABLE_REQ_BYTES>
        requestMsg{};
    auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
    size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
    auto request = reinterpret_cast<pldm_get_file_table_req*>(
        requestMsg.data() + sizeof(pldm_msg_hdr));
    request->transfer_handle = transferHandle;
    request->operation_flag = opFlag;
    request->table_type = type;

    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto response = handler.getFileTable(requestMsgPtr, requestPayloadLength);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_TABLE_TYPE);
}

TEST_F(TestFileTable, ReadFileBadPath)
{
    uint32_t fileHandle = 1;
    uint32_t offset = 0;
    uint32_t length = 0x4;

    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_READ_FILE_REQ_BYTES>
        requestMsg{};
    auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
    auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr);
    auto request = reinterpret_cast<pldm_read_file_req*>(requestMsg.data() +
                                                         sizeof(pldm_msg_hdr));

    request->file_handle = fileHandle;
    request->offset = offset;
    request->length = length;

    using namespace pldm::filetable;
    // Initialise the file table with 2 valid file handles 0 & 1.
    auto& table = buildFileTable(fileTableConfig.c_str());

    // Invalid payload length
    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto response = handler.readFile(requestMsgPtr, 0);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);

    // Data out of range. File size is 1024, offset = 1024 is invalid.
    request->offset = 1024;

    response = handler.readFile(requestMsgPtr, payload_length);
    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);

    // Invalid file handle
    request->file_handle = 2;

    response = handler.readFile(requestMsgPtr, payload_length);
    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);

    table.clear();
}

TEST_F(TestFileTable, ReadFileGoodPath)
{
    uint32_t fileHandle = 0;
    uint32_t offset = 0;
    uint32_t length = 0x4;

    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_READ_FILE_REQ_BYTES>
        requestMsg{};
    auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
    auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr);
    auto request = reinterpret_cast<pldm_read_file_req*>(requestMsg.data() +
                                                         sizeof(pldm_msg_hdr));

    request->file_handle = fileHandle;
    request->offset = offset;
    request->length = length;

    using namespace pldm::filetable;
    // Initialise the file table with 2 valid file handles 0 & 1.
    auto& table = buildFileTable(fileTableConfig.c_str());
    FileEntry value{};
    value = table.at(fileHandle);

    std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
    stream.seekg(offset);
    std::vector<char> buffer(length);
    stream.read(buffer.data(), length);

    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto responseMsg = handler.readFile(requestMsgPtr, payload_length);
    auto response = reinterpret_cast<pldm_read_file_resp*>(
        responseMsg.data() + sizeof(pldm_msg_hdr));
    ASSERT_EQ(response->completion_code, PLDM_SUCCESS);
    ASSERT_EQ(response->length, length);
    ASSERT_EQ(0, memcmp(response->file_data, buffer.data(), length));

    // Test condition offset + length > fileSize;
    size_t fileSize = 1024;
    request->offset = 1023;
    request->length = 10;

    stream.seekg(request->offset);
    buffer.resize(fileSize - request->offset);
    stream.read(buffer.data(), (fileSize - request->offset));

    responseMsg = handler.readFile(requestMsgPtr, payload_length);
    response = reinterpret_cast<pldm_read_file_resp*>(responseMsg.data() +
                                                      sizeof(pldm_msg_hdr));
    ASSERT_EQ(response->completion_code, PLDM_SUCCESS);
    ASSERT_EQ(response->length, (fileSize - request->offset));
    ASSERT_EQ(0, memcmp(response->file_data, buffer.data(),
                        (fileSize - request->offset)));

    table.clear();
}

TEST_F(TestFileTable, WriteFileBadPath)
{
    uint32_t fileHandle = 0;
    uint32_t offset = 0;
    uint32_t length = 0x10;

    std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
                                    PLDM_WRITE_FILE_REQ_BYTES + length);
    auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
    auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr);
    auto request = reinterpret_cast<pldm_write_file_req*>(requestMsg.data() +
                                                          sizeof(pldm_msg_hdr));

    using namespace pldm::filetable;
    // Initialise the file table with 2 valid file handles 0 & 1.
    auto& table = buildFileTable(fileTableConfig.c_str());

    request->file_handle = fileHandle;
    request->offset = offset;
    request->length = length;

    // Invalid payload length
    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto response = handler.writeFile(requestMsgPtr, 0);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);

    // Data out of range. File size is 1024, offset = 1024 is invalid.
    request->offset = 1024;

    response = handler.writeFile(requestMsgPtr, payload_length);
    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);

    // Invalid file handle
    request->file_handle = 2;

    response = handler.writeFile(requestMsgPtr, payload_length);
    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);

    table.clear();
}

TEST_F(TestFileTable, WriteFileGoodPath)
{
    uint32_t fileHandle = 1;
    uint32_t offset = 0;
    std::array<uint8_t, 4> fileData = {0x41, 0x42, 0x43, 0x44};
    uint32_t length = fileData.size();

    std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
                                    PLDM_WRITE_FILE_REQ_BYTES + length);
    auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
    auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr);
    auto request = reinterpret_cast<pldm_write_file_req*>(requestMsg.data() +
                                                          sizeof(pldm_msg_hdr));

    using namespace pldm::filetable;
    // Initialise the file table with 2 valid file handles 0 & 1.
    auto& table = buildFileTable(fileTableConfig.c_str());
    FileEntry value{};
    value = table.at(fileHandle);

    request->file_handle = fileHandle;
    request->offset = offset;
    request->length = length;
    memcpy(request->file_data, fileData.data(), fileData.size());

    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto responseMsg = handler.writeFile(requestMsgPtr, payload_length);
    auto response = reinterpret_cast<pldm_read_file_resp*>(
        responseMsg.data() + sizeof(pldm_msg_hdr));

    std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
    stream.seekg(offset);
    std::vector<char> buffer(length);
    stream.read(buffer.data(), length);

    ASSERT_EQ(response->completion_code, PLDM_SUCCESS);
    ASSERT_EQ(response->length, length);
    ASSERT_EQ(0, memcmp(fileData.data(), buffer.data(), length));

    table.clear();
}

TEST(writeFileByTypeFromMemory, testBadPath)
{
    const auto hdr_size = sizeof(pldm_msg_hdr);
    std::array<uint8_t, hdr_size + PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES>
        requestMsg{};
    auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
    size_t requestPayloadLength = requestMsg.size() - hdr_size;
    struct pldm_read_write_file_by_type_memory_req* request =
        reinterpret_cast<struct pldm_read_write_file_by_type_memory_req*>(
            req->payload);
    request->file_type = PLDM_FILE_TYPE_PEL;
    request->file_handle = 0xFFFFFFFF;
    request->offset = 0;
    request->length = 17;
    request->address = 0;

    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto response = handler.writeFileByTypeFromMemory(req, 0);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());

    struct pldm_read_write_file_by_type_memory_resp* resp =
        reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>(
            responsePtr->payload);
    ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code);

    response = handler.writeFileByTypeFromMemory(req, requestPayloadLength);
    responsePtr = reinterpret_cast<pldm_msg*>(response.data());

    resp = reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>(
        responsePtr->payload);
    ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code);
}

TEST(getHandlerByType, allPaths)
{
    uint32_t fileHandle{};
    auto handler = getHandlerByType(PLDM_FILE_TYPE_PEL, fileHandle);
    auto pelType = dynamic_cast<PelHandler*>(handler.get());
    ASSERT_TRUE(pelType != nullptr);

    handler = getHandlerByType(PLDM_FILE_TYPE_LID_PERM, fileHandle);
    auto lidType = dynamic_cast<LidHandler*>(handler.get());
    ASSERT_TRUE(lidType != nullptr);
    pelType = dynamic_cast<PelHandler*>(handler.get());
    ASSERT_TRUE(pelType == nullptr);
    handler = getHandlerByType(PLDM_FILE_TYPE_LID_TEMP, fileHandle);
    lidType = dynamic_cast<LidHandler*>(handler.get());
    ASSERT_TRUE(lidType != nullptr);

    handler = getHandlerByType(PLDM_FILE_TYPE_DUMP, fileHandle);
    auto dumpType = dynamic_cast<DumpHandler*>(handler.get());
    ASSERT_TRUE(dumpType != nullptr);

    handler = getHandlerByType(PLDM_FILE_TYPE_CERT_SIGNING_REQUEST, fileHandle);
    auto certType = dynamic_cast<CertHandler*>(handler.get());
    ASSERT_TRUE(certType != nullptr);

    handler = getHandlerByType(PLDM_FILE_TYPE_SIGNED_CERT, fileHandle);
    certType = dynamic_cast<CertHandler*>(handler.get());
    ASSERT_TRUE(certType != nullptr);

    handler = getHandlerByType(PLDM_FILE_TYPE_ROOT_CERT, fileHandle);
    certType = dynamic_cast<CertHandler*>(handler.get());
    ASSERT_TRUE(certType != nullptr);

    using namespace sdbusplus::xyz::openbmc_project::Common::Error;
    ASSERT_THROW(getHandlerByType(0xFFFF, fileHandle), InternalFailure);
}

TEST(readFileByTypeIntoMemory, testBadPath)
{
    const auto hdr_size = sizeof(pldm_msg_hdr);
    std::array<uint8_t, hdr_size + PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES>
        requestMsg{};
    auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
    struct pldm_read_write_file_by_type_memory_req* request =
        reinterpret_cast<struct pldm_read_write_file_by_type_memory_req*>(
            req->payload);
    request->file_type = 0xFFFF;
    request->file_handle = 0;
    request->offset = 0;
    request->length = 17;
    request->address = 0;

    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto response = handler.readFileByTypeIntoMemory(req, 0);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    struct pldm_read_write_file_by_type_memory_resp* resp =
        reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>(
            responsePtr->payload);
    ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code);

    response = handler.readFileByTypeIntoMemory(
        req, PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES);
    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    resp = reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>(
        responsePtr->payload);
    ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code);

    request->length = 16;
    response = handler.readFileByTypeIntoMemory(
        req, PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES);
    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    resp = reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>(
        responsePtr->payload);
    ASSERT_EQ(PLDM_INVALID_FILE_TYPE, resp->completion_code);
}

TEST(readFileByType, testBadPath)
{
    const auto hdr_size = sizeof(pldm_msg_hdr);
    std::array<uint8_t, hdr_size + PLDM_RW_FILE_BY_TYPE_REQ_BYTES> requestMsg{};
    auto payloadLength = requestMsg.size() - hdr_size;
    auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
    struct pldm_read_write_file_by_type_req* request =
        reinterpret_cast<struct pldm_read_write_file_by_type_req*>(
            req->payload);
    request->file_type = 0xFFFF;
    request->file_handle = 0;
    request->offset = 0;
    request->length = 13;

    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
    oem_ibm::Handler handler(oemPlatformHandler.get());
    auto response = handler.readFileByType(req, 0);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    struct pldm_read_write_file_by_type_resp* resp =
        reinterpret_cast<struct pldm_read_write_file_by_type_resp*>(
            responsePtr->payload);
    ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code);

    response = handler.readFileByType(req, payloadLength);
    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
    resp = reinterpret_cast<struct pldm_read_write_file_by_type_resp*>(
        responsePtr->payload);
    ASSERT_EQ(PLDM_INVALID_FILE_TYPE, resp->completion_code);
}

TEST(readFileByType, testReadFile)
{
    LidHandler handler(0, true);
    Response response;
    uint32_t length{};

    auto rc = handler.readFile({}, 0, length, response);
    ASSERT_EQ(PLDM_INVALID_FILE_HANDLE, rc);

    char tmplt[] = "/tmp/lid.XXXXXX";
    auto fd = mkstemp(tmplt);
    std::vector<uint8_t> in = {100, 10, 56, 78, 34, 56, 79, 235, 111};
    write(fd, in.data(), in.size());
    close(fd);
    length = in.size() + 1000;
    rc = handler.readFile(tmplt, 0, length, response);
    ASSERT_EQ(rc, PLDM_SUCCESS);
    ASSERT_EQ(length, in.size());
    ASSERT_EQ(response.size(), in.size());
    ASSERT_EQ(std::equal(in.begin(), in.end(), response.begin()), true);
}
