#include "cper_encoder.hpp"
#include "mock_cper_encoder.hpp"

#include <chrono>
#include <concepts>

#include "gtest/gtest.h"
#include <gmock/gmock.h>

using testing::_;
using testing::Contains;

namespace uefi::cper
{
template <typename T>
concept StringOrVector =
    std::is_same_v<T, std::string> || std::is_same_v<T, std::vector<uint8_t>>;

class CperEncoderTest : public testing::Test
{
  public:
    void SetUp() override
    {}

    bool isArrayEq(const void* arr1, const void* arr2, const uint64_t arr1Size,
                   const uint64_t arr2Size)
    {
        if (arr1Size != arr2Size)
        {
            return false;
        }
        return memcmp(arr1, arr2, arr1Size) == 0;
    }

    template <StringOrVector CperType>
    void expectValidHeader(const CperType& cperArray,
                           const uint16_t numSections, const uint64_t cperSize,
                           const uint64_t timestamp)
    {
        RecordHeader header;
        memcpy(&header, cperArray.data(), sizeof(header));

        EXPECT_EQ(header.signature, kRecordSignature);
        EXPECT_EQ(header.revision, kRecordRevision);
        EXPECT_EQ(header.signatureEnd, kRecordSignatureEnd);
        EXPECT_EQ(header.sectionCount, numSections);
        EXPECT_EQ(header.errorSeverity, kMockRecordSeverity);
        EXPECT_EQ(header.validationBits, kMockValidationBits);
        EXPECT_EQ(header.recordLength, cperSize);
        EXPECT_EQ(header.timestamp, timestamp);
        EXPECT_EQ(header.platformId, kMockPlatformId);
        EXPECT_EQ(header.partitionId, kMockPartitionId);
        EXPECT_EQ(header.creatorId, kMockCreatorId);
        EXPECT_EQ(header.notificationType, kMockNotificationType);
        EXPECT_EQ(header.recordId, kMockRecordId);
        EXPECT_EQ(header.flags, kMockHeaderFlags);
        EXPECT_EQ(header.persistenceInformation, kMockPersistenceInformation);
        EXPECT_THAT(header.reserved, Contains(0).Times(header.reserved.size()));
    }

    template <StringOrVector CperType>
    void expectValidSectionDescriptor(const CperType& cperArray,
                                      const uint64_t sectionNum,
                                      const uint32_t expectedOffset,
                                      const uint32_t expectedLength,
                                      const uint32_t expectedFlag,
                                      const guid_t expectedSectionType)
    {
        const uint64_t sectionOffset =
            kRecordHeaderSizeBytes + (kSectionDescriptorSizeBytes * sectionNum);

        SectionDescriptor descriptor;
        memcpy(&descriptor, &cperArray[sectionOffset], sizeof(descriptor));

        EXPECT_EQ(descriptor.sectionOffset, expectedOffset);
        EXPECT_EQ(descriptor.sectionLength, expectedLength);
        EXPECT_EQ(descriptor.revision, kMockSectionRevision);
        EXPECT_EQ(descriptor.validationBits, kMockSectionValidationBits);
        EXPECT_EQ(descriptor.reserved, 0);
        EXPECT_EQ(descriptor.flags, expectedFlag);
        EXPECT_EQ(descriptor.sectionType, expectedSectionType);
        EXPECT_EQ(descriptor.fruId, kMockFruId);
        EXPECT_EQ(descriptor.sectionSeverity, kMockSectionSeverity);
        EXPECT_EQ(descriptor.fruText, kMockFruText);
    }

    template <ByteLike BodyType, StringOrVector CperType>
    void expectValidSectionBody(
        const CperType& cperArray,
        const std::span<const BodyType> expectedSectionBody,
        const uint64_t totalSections, const uint32_t sectionOffset)
    {
        // The offset set in the section descriptors is the offset in bytes
        // after the header and descriptors.
        const uint32_t kTrueBodyOffset =
            sectionOffset + kRecordHeaderSizeBytes +
            (kSectionDescriptorSizeBytes * totalSections);

        const uint64_t kSectionBodySize = expectedSectionBody.size();

        ASSERT_GE(cperArray.size(), (kTrueBodyOffset + kSectionBodySize));

        CperType sectionBody(kSectionBodySize, 0);
        memcpy(sectionBody.data(), &cperArray[kTrueBodyOffset],
               sectionBody.size());

        EXPECT_TRUE(isArrayEq(sectionBody.data(), expectedSectionBody.data(),
                              sectionBody.size(), expectedSectionBody.size()));
    }

    void expectEqTimestamp(
        const uint64_t cperTimestamp,
        const std::chrono::time_point<std::chrono::system_clock> ref,
        const bool isPrecise = true)
    {
        Timestamp structTimestamp;
        memcpy(&structTimestamp, &cperTimestamp, sizeof(structTimestamp));

        time_t tt = std::chrono::system_clock::to_time_t(ref);
        tm utcTime = *gmtime(&tt);

        EXPECT_EQ(structTimestamp.seconds, utcTime.tm_sec);
        EXPECT_EQ(structTimestamp.minutes, utcTime.tm_min);
        EXPECT_EQ(structTimestamp.hours, utcTime.tm_hour);
        EXPECT_EQ(structTimestamp.isPrecise, (isPrecise & 0x1));
        EXPECT_EQ(structTimestamp.day, utcTime.tm_mday);
        EXPECT_EQ(structTimestamp.month, utcTime.tm_mon);
        EXPECT_EQ(structTimestamp.year, (utcTime.tm_year + 1900) % 100);
        EXPECT_EQ(structTimestamp.century, (utcTime.tm_year + 1900) / 100);
    }
};

TEST_F(CperEncoderTest, TooMuchData)
{
    MockCperEncoder<uint8_t> mockEncoder;
    uint64_t totalSize = kRecordHeaderSizeBytes;

    // Exceed the 4GiB CPER Log max size by adding 2^16 * 2^16 Bytes worth of
    // section bodies along with their descriptors.
    for (uint64_t i = 0; i < std::numeric_limits<uint16_t>::max(); i++)
    {
        std::array<uint8_t, std::numeric_limits<uint16_t>::max()> sectionBody;
        totalSize += sectionBody.size() + kSectionDescriptorSizeBytes;

        // Note the encoder does not own the sectionBody, it just tracks the
        // body ptrs and size. This would never work in a real application since
        // the sectionBody only exists within each loops iteration.
        if (totalSize < std::numeric_limits<uint32_t>::max())
        {

            EXPECT_TRUE(mockEncoder.addSection(sectionBody, kMockSectionFlag,
                                               kMockSectionType));
        }
        else
        {
            EXPECT_FALSE(mockEncoder.addSection(sectionBody, kMockSectionFlag,
                                                kMockSectionType));
            return;
        }
    }

    FAIL() << "Should never be able to complete the loop";
}

TEST_F(CperEncoderTest, EncodeMultipleCharSectionsToArrayAndString)
{
    MockCperEncoder<char> mockEncoder;

    // Fill our CPER Log with some quotes to get through the work week.
    std::vector<std::string> sectionBodies;
    sectionBodies.push_back("The first principle is that you must not fool "
                            "yourself and you are the easiest person to fool.");
    sectionBodies.push_back("Spread love everywhere you go.");
    sectionBodies.push_back("The only thing we have to fear is fear itself.");
    sectionBodies.push_back("If you can't explain it to a six year old, you "
                            "don't understand it yourself.");
    sectionBodies.push_back("I have no wings, so I guess I'll look up at this "
                            "sky, and crawl along the Earth.");
    sectionBodies.push_back("If I have seen further, it is by standing on the "
                            "shoulders of giants.");

    const uint16_t kNumSections = sectionBodies.size();

    // Add the sections to our encoder.
    uint64_t totalSectionBodySize = 0;
    for (const std::string& body : sectionBodies)
    {
        mockEncoder.addSection(body, kMockSectionFlag, kMockSectionType);
        totalSectionBodySize += body.size();
    }

    const uint64_t kExpectedCperSize =
        (kRecordHeaderSizeBytes + (kSectionDescriptorSizeBytes * kNumSections) +
         totalSectionBodySize);

    // Serialize to an array.
    EXPECT_CALL(mockEncoder, mockCreateRecordHeader).Times(1);
    EXPECT_CALL(mockEncoder, mockCreateSectionDescriptor).Times(kNumSections);
    const std::vector<uint8_t> cperArray = mockEncoder.serializeToByteArray();
    ASSERT_EQ(cperArray.size(), kExpectedCperSize);

    // Check that the serialized arrays header contains the same contents we
    // configured the encoder to use.
    expectValidHeader(cperArray, kNumSections, kExpectedCperSize,
                      mockEncoder.timestamp);

    // Check that the section descriptors and bodies all contain the correct
    // information about their respective section.
    uint32_t expectedOffset = 0;
    uint64_t sectionIdx = 0;
    for (const std::string& body : sectionBodies)
    {
        const uint32_t kBodyLength = body.size();
        expectValidSectionDescriptor(cperArray, sectionIdx, expectedOffset,
                                     kBodyLength, kMockSectionFlag,
                                     kMockSectionType);

        expectValidSectionBody<char>(cperArray, body, kNumSections,
                                     expectedOffset);

        expectedOffset += kBodyLength;
        sectionIdx++;
    }

    // Serialize to a string.
    EXPECT_CALL(mockEncoder, mockCreateRecordHeader).Times(1);
    EXPECT_CALL(mockEncoder, mockCreateSectionDescriptor).Times(kNumSections);
    const std::string cperStr = mockEncoder.serializeToString();
    ASSERT_EQ(cperStr.size(), kExpectedCperSize);

    // Check that the serialized arrays header contains the same contents we
    // configured the encoder to use.
    expectValidHeader(cperStr, kNumSections, kExpectedCperSize,
                      mockEncoder.timestamp);

    // Check that the section descriptors and bodies all contain the correct
    // information about their respective section.
    expectedOffset = 0;
    sectionIdx = 0;
    for (const std::string& body : sectionBodies)
    {
        const uint32_t kBodyLength = body.size();
        expectValidSectionDescriptor(cperStr, sectionIdx, expectedOffset,
                                     kBodyLength, kMockSectionFlag,
                                     kMockSectionType);

        expectValidSectionBody<char>(cperStr, body, kNumSections,
                                     expectedOffset);

        expectedOffset += kBodyLength;
        sectionIdx++;
    }
}

TEST_F(CperEncoderTest, EncodeOneU8SectionToString)
{
    MockCperEncoder<uint8_t> mockEncoder;

    const std::array<uint8_t, 10> sectionBody = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    const uint64_t kSectionBodySize = sectionBody.size();
    constexpr uint16_t kNumSections = 1;

    // Add 1 section
    mockEncoder.addSection(sectionBody, kMockSectionFlag, kMockSectionType);

    // Serialize the data into a CPER byte array.
    EXPECT_CALL(mockEncoder, mockCreateRecordHeader).Times(1);
    EXPECT_CALL(mockEncoder, mockCreateSectionDescriptor).Times(kNumSections);
    const std::string cperArray = mockEncoder.serializeToString();

    // If this bricks, abort ship - there is likely memory corruption.
    const uint64_t kExpectedCperSize =
        (kSectionBodySize + kSectionDescriptorSizeBytes +
         kRecordHeaderSizeBytes);

    ASSERT_EQ(cperArray.size(), kExpectedCperSize);

    // Check that the serialized arrays header contains the same contents we
    // configured the encoder to use.
    expectValidHeader(cperArray, kNumSections, kExpectedCperSize,
                      mockEncoder.timestamp);

    // Check that the section descriptor contains the correct information about
    // the section.
    const uint32_t kExpectedOffset = 0;
    expectValidSectionDescriptor(cperArray, 0, kExpectedOffset,
                                 kSectionBodySize, kMockSectionFlag,
                                 kMockSectionType);

    expectValidSectionBody<uint8_t>(cperArray, sectionBody, kNumSections,
                                    kExpectedOffset);
}

TEST_F(CperEncoderTest, EncodeOneCharSectionToArray)
{
    MockCperEncoder<char> mockEncoder;

    const std::string sectionBody =
        "Hello world, this is a simplistic example of a CPER Section Body.";
    const uint64_t kSectionBodySize = sectionBody.size();
    constexpr uint16_t kNumSections = 1;

    // Add 1 section
    mockEncoder.addSection(sectionBody, kMockSectionFlag, kMockSectionType);

    // Serialize the data into a CPER byte array.
    EXPECT_CALL(mockEncoder, mockCreateRecordHeader).Times(1);
    EXPECT_CALL(mockEncoder, mockCreateSectionDescriptor).Times(kNumSections);
    const std::vector<uint8_t> cperArray = mockEncoder.serializeToByteArray();

    // If this bricks, abort ship - there is likely memory corruption.
    const uint64_t kExpectedCperSize =
        (kSectionBodySize + kSectionDescriptorSizeBytes +
         kRecordHeaderSizeBytes);

    ASSERT_EQ(cperArray.size(), kExpectedCperSize);

    // Check that the serialized arrays header contains the same contents we
    // configured the encoder to use.
    expectValidHeader(cperArray, kNumSections, kExpectedCperSize,
                      mockEncoder.timestamp);

    // Check that the section descriptor contains the correct information about
    // the section.
    const uint32_t kExpectedOffset = 0;
    expectValidSectionDescriptor(cperArray, 0, kExpectedOffset,
                                 kSectionBodySize, kMockSectionFlag,
                                 kMockSectionType);

    expectValidSectionBody<char>(cperArray, sectionBody, kNumSections,
                                 kExpectedOffset);
}

TEST_F(CperEncoderTest, SeqMemcopy)
{
    std::string section1 = "Hello";
    std::string section2 = " ";
    std::string section3 = "World";

    std::string dest(section1.size() + section2.size() + section3.size(), 0);

    SeqMemcopy<char> seqMemcpy(dest);

    EXPECT_NO_THROW(seqMemcpy.copy(section1.data(), section1.size()));
    EXPECT_NO_THROW(seqMemcpy.copy(section2.data(), section2.size()));
    EXPECT_NO_THROW(seqMemcpy.copy(section3.data(), section3.size()));

    EXPECT_EQ(dest, section1 + section2 + section3);

    std::string section4 = "This is an attempted buffer overflow!";

    EXPECT_THROW(seqMemcpy.copy(section4.data(), section4.size()),
                 std::out_of_range);
}

TEST_F(CperEncoderTest, CreateCperTimestamp)
{
    const auto now = std::chrono::system_clock::now();

    const uint64_t preciseTimestamp = createCperTimestamp(now);
    expectEqTimestamp(preciseTimestamp, now);

    const uint64_t impreciseTimestamp = createCperTimestamp(now, false);
    expectEqTimestamp(impreciseTimestamp, now, false);
}

TEST_F(CperEncoderTest, SmokeTest)
{
    RecordHeader recordHeader;

    const std::array<uint8_t, 4> kExpectedSignature = {'C', 'P', 'E', 'R'};
    const std::array<uint8_t, 12> kExpectedReserved = {0};

    EXPECT_EQ(recordHeader.signature, kExpectedSignature);
    EXPECT_EQ(recordHeader.revision, 0x0000);
    EXPECT_EQ(recordHeader.signatureEnd, 0xffffffff);
    EXPECT_EQ(recordHeader.reserved, kExpectedReserved);

    // Check for proper packing by putting a needle in the haystack.
    recordHeader.flags = 0xBEEF;
    const size_t flagsOffset = 104;

    std::array<uint8_t, sizeof(recordHeader)> headerBin;
    memcpy(&headerBin, &recordHeader, sizeof(headerBin));

    uint32_t flagsValue;
    memcpy(&flagsValue, &headerBin[flagsOffset], sizeof(flagsValue));
    EXPECT_EQ(recordHeader.flags, flagsValue);
}
} // namespace uefi::cper
