#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>>;

uint8_t bcdToDecimal(const uint8_t bcd)
{
    uint8_t tens = bcd >> 4;
    uint8_t ones = bcd & 0x0F;
    if (ones > 9 || tens > 9)
    {
        return 0;
    }
    return (tens * 10) + ones;
}

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 expectedBodyOffset,
                                      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, expectedBodyOffset);
        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 uint32_t sectionOffset)
    {
        const uint64_t kSectionBodySize = expectedSectionBody.size();

        // Make sure the cperArray is large enough to contain the data.
        ASSERT_GE(cperArray.size(), sectionOffset + kSectionBodySize);

        CperType sectionBody(kSectionBodySize, 0);
        memcpy(sectionBody.data(), &cperArray[sectionOffset],
               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));

        structTimestamp.seconds = bcdToDecimal(structTimestamp.seconds);
        structTimestamp.minutes = bcdToDecimal(structTimestamp.minutes);
        structTimestamp.hours = bcdToDecimal(structTimestamp.hours);
        structTimestamp.day = bcdToDecimal(structTimestamp.day);
        structTimestamp.month = bcdToDecimal(structTimestamp.month) - 1;
        structTimestamp.year = bcdToDecimal(structTimestamp.year);
        structTimestamp.century = bcdToDecimal(structTimestamp.century);

        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 expectedBodyOffset =
        kRecordHeaderSizeBytes + (kNumSections * kSectionDescriptorSizeBytes);
    uint64_t sectionIdx = 0;
    for (const std::string& body : sectionBodies)
    {
        const uint32_t kBodyLength = body.size();
        expectValidSectionDescriptor(cperArray, sectionIdx, expectedBodyOffset,
                                     kBodyLength, kMockSectionFlag,
                                     kMockSectionType);

        expectValidSectionBody<char>(cperArray, body, expectedBodyOffset);

        expectedBodyOffset += 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.
    expectedBodyOffset =
        kRecordHeaderSizeBytes + (kNumSections * kSectionDescriptorSizeBytes);
    sectionIdx = 0;
    for (const std::string& body : sectionBodies)
    {
        const uint32_t kBodyLength = body.size();
        expectValidSectionDescriptor(cperStr, sectionIdx, expectedBodyOffset,
                                     kBodyLength, kMockSectionFlag,
                                     kMockSectionType);

        expectValidSectionBody<char>(cperStr, body, expectedBodyOffset);

        expectedBodyOffset += 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 =
        kRecordHeaderSizeBytes + (kNumSections * kSectionDescriptorSizeBytes);
    expectValidSectionDescriptor(cperArray, 0, kExpectedOffset,
                                 kSectionBodySize, kMockSectionFlag,
                                 kMockSectionType);

    expectValidSectionBody<uint8_t>(cperArray, sectionBody, 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 =
        kRecordHeaderSizeBytes + (kNumSections * kSectionDescriptorSizeBytes);
    expectValidSectionDescriptor(cperArray, 0, kExpectedOffset,
                                 kSectionBodySize, kMockSectionFlag,
                                 kMockSectionType);

    expectValidSectionBody<char>(cperArray, sectionBody, 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
