#include "helper.hpp"
#include "ipmi.hpp"
#include "manager_mock.hpp"
#include "process.hpp"

#include <ipmiblob/test/crc_mock.hpp>

#include <cstring>
#include <span>

#include <gtest/gtest.h>

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

using ::testing::_;
using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::Return;
using ::testing::StrictMock;

namespace ipmiblob
{
CrcInterface* crcIntf = nullptr;

std::uint16_t generateCrc(const std::vector<std::uint8_t>& data)
{
    return (crcIntf) ? crcIntf->generateCrc(data) : 0x00;
}
} // namespace ipmiblob

namespace blobs
{
namespace
{

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

    Resp (*const* lPtr)(ManagerInterface*, std::span<const uint8_t>) =
        lhs.target<Resp (*)(ManagerInterface*, std::span<const uint8_t>)>();

    Resp (*const* rPtr)(ManagerInterface*, std::span<const uint8_t>) =
        rhs.target<Resp (*)(ManagerInterface*, std::span<const uint8_t>)>();

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

} // namespace

class ValidateBlobCommandTest : public ::testing::Test
{
  protected:
    void SetUp() override
    {
        ipmiblob::crcIntf = &crcMock;
    }

    ipmiblob::CrcMock crcMock;
};

TEST_F(ValidateBlobCommandTest, InvalidCommandReturnsFailure)
{
    // Verify we handle an invalid command.
    std::vector<uint8_t> request(MAX_IPMI_BUFFER - 1);
    // There is no command 0xff.
    IpmiBlobHandler handler = validateBlobCommand(0xff, request);
    EXPECT_EQ(ipmi::responseInvalidFieldRequest(), handler(nullptr, {}));
}

TEST_F(ValidateBlobCommandTest, ValidCommandWithoutPayload)
{
    // Verify we handle a valid command that doesn't have a payload.
    std::vector<uint8_t> request(MAX_IPMI_BUFFER - 1);
    IpmiBlobHandler handler = validateBlobCommand(
        static_cast<std::uint8_t>(BlobOEMCommands::bmcBlobGetCount), request);
    EXPECT_FALSE(handler == nullptr);
    EqualFunctions(getBlobCount, handler);
}

TEST_F(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.

    std::vector<uint8_t> request(sizeof(uint16_t));
    // There is a payload, but there are insufficient bytes.

    IpmiBlobHandler handler = validateBlobCommand(
        static_cast<std::uint8_t>(BlobOEMCommands::bmcBlobGetCount), request);
    EXPECT_EQ(ipmi::responseReqDataLenInvalid(), handler(nullptr, {}));
}

TEST_F(ValidateBlobCommandTest, WithPayloadAndInvalidCrc)
{
    // Verify that the CRC is checked, and failure is reported.
    std::vector<uint8_t> request;
    BmcBlobWriteTx req;
    req.crc = 0x34;
    req.sessionId = 0x54;
    req.offset = 0x100;

    std::array<uint8_t, 2> expectedBytes = {0x66, 0x67};
    request.resize(sizeof(struct BmcBlobWriteTx));
    std::memcpy(request.data(), &req, sizeof(struct BmcBlobWriteTx));
    request.insert(request.end(), expectedBytes.begin(), expectedBytes.end());

    // skip over cmd and crc.
    std::vector<uint8_t> bytes(request.begin() + sizeof(req.crc),
                               request.end());
    EXPECT_CALL(crcMock, generateCrc(Eq(bytes))).WillOnce(Return(0x1234));

    IpmiBlobHandler handler = validateBlobCommand(
        static_cast<std::uint8_t>(BlobOEMCommands::bmcBlobWrite), request);
    EXPECT_EQ(ipmi::responseUnspecifiedError(), handler(nullptr, {}));
}

TEST_F(ValidateBlobCommandTest, WithPayloadAndValidCrc)
{
    // Verify the CRC is checked and if it matches, return the handler.
    std::vector<uint8_t> request;
    BmcBlobWriteTx req;
    req.crc = 0x3412;
    req.sessionId = 0x54;
    req.offset = 0x100;

    std::array<uint8_t, 2> expectedBytes = {0x66, 0x67};
    request.resize(sizeof(struct BmcBlobWriteTx));
    std::memcpy(request.data(), &req, sizeof(struct BmcBlobWriteTx));
    request.insert(request.end(), expectedBytes.begin(), expectedBytes.end());

    // skip over cmd and crc.
    std::vector<uint8_t> bytes(request.begin() + sizeof(req.crc),
                               request.end());
    EXPECT_CALL(crcMock, generateCrc(Eq(bytes))).WillOnce(Return(0x3412));

    IpmiBlobHandler handler = validateBlobCommand(
        static_cast<std::uint8_t>(BlobOEMCommands::bmcBlobWrite), request);
    EXPECT_FALSE(handler == nullptr);
    EqualFunctions(writeBlob, handler);
}

class ProcessBlobCommandTest : public ::testing::Test
{
  protected:
    void SetUp() override
    {
        ipmiblob::crcIntf = &crcMock;
    }

    ipmiblob::CrcMock crcMock;
};

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

    StrictMock<ManagerMock> manager;
    std::vector<uint8_t> request(MAX_IPMI_BUFFER - 1);

    IpmiBlobHandler h = [](ManagerInterface*, std::span<const uint8_t>) {
        return ipmi::responseInvalidCommand();
    };

    EXPECT_EQ(ipmi::responseInvalidCommand(),
              processBlobCommand(h, &manager, request, MAX_IPMI_BUFFER));
}

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

    StrictMock<ManagerMock> manager;
    std::vector<uint8_t> request(MAX_IPMI_BUFFER - 1);

    IpmiBlobHandler h = [](ManagerInterface*, std::span<const uint8_t>) {
        return ipmi::responseSuccess(std::vector<uint8_t>());
    };

    EXPECT_EQ(ipmi::responseSuccess(std::vector<uint8_t>()),
              processBlobCommand(h, &manager, request, MAX_IPMI_BUFFER));
}

TEST_F(ProcessBlobCommandTest, CommandReturnsOkWithInvalidPayloadLength)
{
    // There is a minimum payload length of 2 bytes (the CRC only, no data, for
    // read), this returns 1.

    StrictMock<ManagerMock> manager;
    std::vector<uint8_t> request(MAX_IPMI_BUFFER - 1);

    IpmiBlobHandler h = [](ManagerInterface*, std::span<const uint8_t>) {
        return ipmi::responseSuccess(std::vector<uint8_t>(1));
    };

    EXPECT_EQ(ipmi::responseUnspecifiedError(),
              processBlobCommand(h, &manager, request, MAX_IPMI_BUFFER));
}

TEST_F(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<ManagerMock> manager;
    std::vector<uint8_t> request(MAX_IPMI_BUFFER - 1);
    uint32_t payloadLen = sizeof(uint16_t) + sizeof(uint8_t);

    IpmiBlobHandler h =
        [payloadLen](ManagerInterface*, std::span<const uint8_t>) {
            std::vector<uint8_t> output(payloadLen, 0);
            output[2] = 0x56;
            return ipmi::responseSuccess(output);
        };

    EXPECT_CALL(crcMock, generateCrc(_)).WillOnce(Return(0x3412));

    auto result = validateReply(
        processBlobCommand(h, &manager, request, MAX_IPMI_BUFFER));

    EXPECT_EQ(result.size(), payloadLen);
    EXPECT_THAT(result, ElementsAre(0x12, 0x34, 0x56));
}

TEST_F(ProcessBlobCommandTest,
       CommandReturnsErrorWithReplyExceededMaxTransferSize)
{
    // 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<ManagerMock> manager;
    std::vector<uint8_t> request(MAX_IPMI_BUFFER - 1);
    uint32_t payloadLen = sizeof(uint16_t) + sizeof(uint8_t);

    IpmiBlobHandler h =
        [payloadLen](ManagerInterface*, std::span<const uint8_t>) {
            std::vector<uint8_t> output(payloadLen, 0);
            output[2] = 0x56;
            return ipmi::responseSuccess(output);
        };

    EXPECT_EQ(ipmi::responseResponseError(),
              processBlobCommand(h, &manager, request, 0));
}
} // namespace blobs
