#include "ipmi.hpp"
#include "manager_mock.hpp"

#include <cstring>

#include <gtest/gtest.h>

namespace blobs
{

using ::testing::_;
using ::testing::ElementsAreArray;
using ::testing::Return;

// ipmid.hpp isn't installed where we can grab it and this value is per BMC
// SoC.
#define MAX_IPMI_BUFFER 64

TEST(BlobCommitTest, InvalidCommitDataLengthReturnsFailure)
{
    // The commit command supports an optional commit blob.  This test verifies
    // we sanity check the length of that blob.

    ManagerMock mgr;
    size_t dataLen;
    uint8_t request[MAX_IPMI_BUFFER] = {0};
    uint8_t reply[MAX_IPMI_BUFFER] = {0};
    auto req = reinterpret_cast<struct BmcBlobCommitTx*>(request);

    req->cmd = static_cast<std::uint8_t>(BlobOEMCommands::bmcBlobCommit);
    req->crc = 0;
    req->sessionId = 0x54;
    req->commitDataLen =
        1; // It's one byte, but that's more than the packet size.

    dataLen = sizeof(struct BmcBlobCommitTx);

    EXPECT_EQ(IPMI_CC_REQ_DATA_LEN_INVALID,
              commitBlob(&mgr, request, reply, &dataLen));
}

TEST(BlobCommitTest, ValidCommitNoDataHandlerRejectsReturnsFailure)
{
    // The commit packet is valid and the manager's commit call returns failure.

    ManagerMock mgr;
    size_t dataLen;
    uint8_t request[MAX_IPMI_BUFFER] = {0};
    uint8_t reply[MAX_IPMI_BUFFER] = {0};
    auto req = reinterpret_cast<struct BmcBlobCommitTx*>(request);

    req->cmd = static_cast<std::uint8_t>(BlobOEMCommands::bmcBlobCommit);
    req->crc = 0;
    req->sessionId = 0x54;
    req->commitDataLen = 0;

    dataLen = sizeof(struct BmcBlobCommitTx);

    EXPECT_CALL(mgr, commit(req->sessionId, _)).WillOnce(Return(false));

    EXPECT_EQ(IPMI_CC_UNSPECIFIED_ERROR,
              commitBlob(&mgr, request, reply, &dataLen));
}

TEST(BlobCommitTest, ValidCommitNoDataHandlerAcceptsReturnsSuccess)
{
    // Commit called with no data and everything returns success.

    ManagerMock mgr;
    size_t dataLen;
    uint8_t request[MAX_IPMI_BUFFER] = {0};
    uint8_t reply[MAX_IPMI_BUFFER] = {0};
    auto req = reinterpret_cast<struct BmcBlobCommitTx*>(request);

    req->cmd = static_cast<std::uint8_t>(BlobOEMCommands::bmcBlobCommit);
    req->crc = 0;
    req->sessionId = 0x54;
    req->commitDataLen = 0;

    dataLen = sizeof(struct BmcBlobCommitTx);

    EXPECT_CALL(mgr, commit(req->sessionId, _)).WillOnce(Return(true));

    EXPECT_EQ(IPMI_CC_OK, commitBlob(&mgr, request, reply, &dataLen));
}

TEST(BlobCommitTest, ValidCommitWithDataHandlerAcceptsReturnsSuccess)
{
    // Commit called with extra data and everything returns success.

    ManagerMock mgr;
    size_t dataLen;
    uint8_t request[MAX_IPMI_BUFFER] = {0};
    uint8_t reply[MAX_IPMI_BUFFER] = {0};
    auto req = reinterpret_cast<struct BmcBlobCommitTx*>(request);

    uint8_t expectedBlob[4] = {0x25, 0x33, 0x45, 0x67};

    req->cmd = static_cast<std::uint8_t>(BlobOEMCommands::bmcBlobCommit);
    req->crc = 0;
    req->sessionId = 0x54;
    req->commitDataLen = sizeof(expectedBlob);
    std::memcpy(req + 1, &expectedBlob[0], sizeof(expectedBlob));

    dataLen = sizeof(struct BmcBlobCommitTx) + sizeof(expectedBlob);

    EXPECT_CALL(mgr,
                commit(req->sessionId,
                       ElementsAreArray(expectedBlob, sizeof(expectedBlob))))
        .WillOnce(Return(true));

    EXPECT_EQ(IPMI_CC_OK, commitBlob(&mgr, request, reply, &dataLen));
}
} // namespace blobs
