#include "crc.hpp"
#include "crc_mock.hpp"
#include "ipmi.hpp"
#include "process.hpp"

#include <blobs-ipmid/test/manager_mock.hpp>
#include <cstring>

#include <gtest/gtest.h>

namespace blobs
{

using ::testing::_;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::StrictMock;

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

namespace
{

void EqualFunctions(IpmiBlobHandler lhs, IpmiBlobHandler rhs)
{
    EXPECT_FALSE(lhs == nullptr);
    EXPECT_FALSE(rhs == nullptr);

    ipmi_ret_t (*const* lPtr)(ManagerInterface*, const uint8_t*, uint8_t*,
                              size_t*) =
        lhs.target<ipmi_ret_t (*)(ManagerInterface*, const uint8_t*, uint8_t*,
                                  size_t*)>();

    ipmi_ret_t (*const* rPtr)(ManagerInterface*, const uint8_t*, uint8_t*,
                              size_t*) =
        rhs.target<ipmi_ret_t (*)(ManagerInterface*, const uint8_t*, uint8_t*,
                                  size_t*)>();

    EXPECT_TRUE(lPtr);
    EXPECT_TRUE(rPtr);
    EXPECT_EQ(*lPtr, *rPtr);
    return;
}

} // namespace

TEST(ValidateBlobCommandTest, InvalidCommandReturnsFailure)
{
    // Verify we handle an invalid command.

    StrictMock<CrcMock> crc;
    size_t dataLen;
    uint8_t request[MAX_IPMI_BUFFER] = {0};
    uint8_t reply[MAX_IPMI_BUFFER] = {0};

    request[0] = 0xff;         // There is no command 0xff.
    dataLen = sizeof(uint8_t); // There is no payload for CRC.
    ipmi_ret_t rc;

    EXPECT_EQ(nullptr,
              validateBlobCommand(&crc, request, reply, &dataLen, &rc));
    EXPECT_EQ(IPMI_CC_INVALID_FIELD_REQUEST, rc);
}

TEST(ValidateBlobCommandTest, ValidCommandWithoutPayload)
{
    // Verify we handle a valid command that doesn't have a payload.

    StrictMock<CrcMock> crc;
    size_t dataLen;
    uint8_t request[MAX_IPMI_BUFFER] = {0};
    uint8_t reply[MAX_IPMI_BUFFER] = {0};

    request[0] = BlobOEMCommands::bmcBlobGetCount;
    dataLen = sizeof(uint8_t); // There is no payload for CRC.
    ipmi_ret_t rc;

    IpmiBlobHandler res =
        validateBlobCommand(&crc, request, reply, &dataLen, &rc);
    EXPECT_FALSE(res == nullptr);
    EqualFunctions(getBlobCount, res);
}

TEST(ValidateBlobCommandTest, WithPayloadMinimumLengthIs3VerifyChecks)
{
    // Verify that if there's a payload, it's at least one command byte and
    // two bytes for the crc16 and then one data byte.

    StrictMock<CrcMock> crc;
    size_t dataLen;
    uint8_t request[MAX_IPMI_BUFFER] = {0};
    uint8_t reply[MAX_IPMI_BUFFER] = {0};

    request[0] = BlobOEMCommands::bmcBlobGetCount;
    dataLen = sizeof(uint8_t) + sizeof(uint16_t);
    // There is a payload, but there are insufficient bytes.
    ipmi_ret_t rc;

    EXPECT_EQ(nullptr,
              validateBlobCommand(&crc, request, reply, &dataLen, &rc));
    EXPECT_EQ(IPMI_CC_REQ_DATA_LEN_INVALID, rc);
}

TEST(ValidateBlobCommandTest, WithPayloadAndInvalidCrc)
{
    // Verify that the CRC is checked, and failure is reported.

    StrictMock<CrcMock> crc;
    size_t dataLen;
    uint8_t request[MAX_IPMI_BUFFER] = {0};
    uint8_t reply[MAX_IPMI_BUFFER] = {0};

    auto req = reinterpret_cast<struct BmcBlobWriteTx*>(request);
    req->cmd = BlobOEMCommands::bmcBlobWrite;
    req->crc = 0x34;
    req->sessionId = 0x54;
    req->offset = 0x100;

    uint8_t expectedBytes[2] = {0x66, 0x67};
    std::memcpy(req->data, &expectedBytes[0], sizeof(expectedBytes));

    dataLen = sizeof(struct BmcBlobWriteTx) + sizeof(expectedBytes);

    // skip over cmd and crc.
    size_t expectedLen = dataLen - 3;

    EXPECT_CALL(crc, clear());
    EXPECT_CALL(crc, compute(_, expectedLen))
        .WillOnce(Invoke([&](const uint8_t* bytes, uint32_t length) {
            EXPECT_EQ(0, std::memcmp(&request[3], bytes, length));
        }));
    EXPECT_CALL(crc, get()).WillOnce(Return(0x1234));

    ipmi_ret_t rc;

    EXPECT_EQ(nullptr,
              validateBlobCommand(&crc, request, reply, &dataLen, &rc));
    EXPECT_EQ(IPMI_CC_UNSPECIFIED_ERROR, rc);
}

TEST(ValidateBlobCommandTest, WithPayloadAndValidCrc)
{
    // Verify the CRC is checked and if it matches, return the handler.

    StrictMock<CrcMock> crc;
    size_t dataLen;
    uint8_t request[MAX_IPMI_BUFFER] = {0};
    uint8_t reply[MAX_IPMI_BUFFER] = {0};

    auto req = reinterpret_cast<struct BmcBlobWriteTx*>(request);
    req->cmd = BlobOEMCommands::bmcBlobWrite;
    req->crc = 0x3412;
    req->sessionId = 0x54;
    req->offset = 0x100;

    uint8_t expectedBytes[2] = {0x66, 0x67};
    std::memcpy(req->data, &expectedBytes[0], sizeof(expectedBytes));

    dataLen = sizeof(struct BmcBlobWriteTx) + sizeof(expectedBytes);

    // skip over cmd and crc.
    size_t expectedLen = dataLen - 3;

    EXPECT_CALL(crc, clear());
    EXPECT_CALL(crc, compute(_, expectedLen))
        .WillOnce(Invoke([&](const uint8_t* bytes, uint32_t length) {
            EXPECT_EQ(0, std::memcmp(&request[3], bytes, length));
        }));
    EXPECT_CALL(crc, get()).WillOnce(Return(0x3412));

    ipmi_ret_t rc;

    IpmiBlobHandler res =
        validateBlobCommand(&crc, request, reply, &dataLen, &rc);
    EXPECT_FALSE(res == nullptr);
    EqualFunctions(writeBlob, res);
}

TEST(ValidateBlobCommandTest, InputIntegrationTest)
{
    // Given a request buffer generated by the host-side utility, verify it is
    // properly routed.

    Crc16 crc;
    size_t dataLen;
    uint8_t request[] = {0x02, 0x88, 0x21, 0x03, 0x00, 0x2f, 0x64, 0x65, 0x76,
                         0x2f, 0x68, 0x61, 0x76, 0x65, 0x6e, 0x2f, 0x63, 0x6f,
                         0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x70, 0x61, 0x73,
                         0x73, 0x74, 0x68, 0x72, 0x75, 0x00};

    // The above request to open a file for reading & writing named:
    // "/dev/haven/command_passthru"

    uint8_t reply[MAX_IPMI_BUFFER] = {0};

    dataLen = sizeof(request);
    ipmi_ret_t rc;

    IpmiBlobHandler res =
        validateBlobCommand(&crc, request, reply, &dataLen, &rc);
    EXPECT_FALSE(res == nullptr);
    EqualFunctions(openBlob, res);
}

TEST(ProcessBlobCommandTest, CommandReturnsNotOk)
{
    // Verify that if the IPMI command handler returns not OK that this is
    // noticed and returned.

    StrictMock<CrcMock> crc;
    StrictMock<ManagerMock> manager;
    size_t dataLen;
    uint8_t request[MAX_IPMI_BUFFER] = {0};
    uint8_t reply[MAX_IPMI_BUFFER] = {0};

    IpmiBlobHandler h = [](ManagerInterface* mgr, const uint8_t* reqBuf,
                           uint8_t* replyCmdBuf,
                           size_t* dataLen) { return IPMI_CC_INVALID; };

    dataLen = sizeof(request);

    EXPECT_EQ(IPMI_CC_INVALID,
              processBlobCommand(h, &manager, &crc, request, reply, &dataLen));
}

TEST(ProcessBlobCommandTest, CommandReturnsOkWithNoPayload)
{
    // Verify that if the IPMI command handler returns OK but without a payload
    // it doesn't try to compute a CRC.

    StrictMock<CrcMock> crc;
    StrictMock<ManagerMock> manager;
    size_t dataLen;
    uint8_t request[MAX_IPMI_BUFFER] = {0};
    uint8_t reply[MAX_IPMI_BUFFER] = {0};

    IpmiBlobHandler h = [](ManagerInterface* mgr, const uint8_t* reqBuf,
                           uint8_t* replyCmdBuf, size_t* dataLen) {
        (*dataLen) = 0;
        return IPMI_CC_OK;
    };

    dataLen = sizeof(request);

    EXPECT_EQ(IPMI_CC_OK,
              processBlobCommand(h, &manager, &crc, request, reply, &dataLen));
}

TEST(ProcessBlobCommandTest, CommandReturnsOkWithInvalidPayloadLength)
{
    // There is a minimum payload length of 3 bytes, this command returns a
    // payload of 2 bytes.

    StrictMock<CrcMock> crc;
    StrictMock<ManagerMock> manager;
    size_t dataLen;
    uint8_t request[MAX_IPMI_BUFFER] = {0};
    uint8_t reply[MAX_IPMI_BUFFER] = {0};

    IpmiBlobHandler h = [](ManagerInterface* mgr, const uint8_t* reqBuf,
                           uint8_t* replyCmdBuf, size_t* dataLen) {
        (*dataLen) = sizeof(uint16_t);
        return IPMI_CC_OK;
    };

    dataLen = sizeof(request);

    EXPECT_EQ(IPMI_CC_UNSPECIFIED_ERROR,
              processBlobCommand(h, &manager, &crc, request, reply, &dataLen));
}

TEST(ProcessBlobCommandTest, CommandReturnsOkWithValidPayloadLength)
{
    // There is a minimum payload length of 3 bytes, this command returns a
    // payload of 3 bytes and the crc code is called to process the payload.

    StrictMock<CrcMock> crc;
    StrictMock<ManagerMock> manager;
    size_t dataLen;
    uint8_t request[MAX_IPMI_BUFFER] = {0};
    uint8_t reply[MAX_IPMI_BUFFER] = {0};
    uint32_t payloadLen = sizeof(uint16_t) + sizeof(uint8_t);

    IpmiBlobHandler h = [payloadLen](ManagerInterface* mgr,
                                     const uint8_t* reqBuf,
                                     uint8_t* replyCmdBuf, size_t* dataLen) {
        (*dataLen) = payloadLen;
        replyCmdBuf[2] = 0x56;
        return IPMI_CC_OK;
    };

    dataLen = sizeof(request);

    EXPECT_CALL(crc, clear());
    EXPECT_CALL(crc, compute(_, payloadLen - sizeof(uint16_t)));
    EXPECT_CALL(crc, get()).WillOnce(Return(0x3412));

    EXPECT_EQ(IPMI_CC_OK,
              processBlobCommand(h, &manager, &crc, request, reply, &dataLen));
    EXPECT_EQ(dataLen, payloadLen);

    uint8_t expectedBytes[3] = {0x12, 0x34, 0x56};
    EXPECT_EQ(0, std::memcmp(expectedBytes, reply, sizeof(expectedBytes)));
}
} // namespace blobs
