#include "config.h"

#include "buffer.hpp"

#include "pci_handler.hpp"

#include <boost/endian/arithmetic.hpp>
#include <boost/endian/conversion.hpp>

#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <format>
#include <memory>
#include <numeric>
#include <span>
#include <vector>

namespace bios_bmc_smm_error_logger
{

BufferImpl::BufferImpl(std::unique_ptr<DataInterface> dataInterface) :
    dataInterface(std::move(dataInterface)) {};

void BufferImpl::initialize(uint32_t bmcInterfaceVersion, uint16_t queueSize,
                            uint16_t ueRegionSize,
                            const std::array<uint32_t, 4>& magicNumber)
{
    const size_t memoryRegionSize = dataInterface->getMemoryRegionSize();
    if (queueSize > memoryRegionSize)
    {
        throw std::runtime_error(std::format(
            "[initialize] Proposed queue size '{}' is bigger than the "
            "BMC's allocated MMIO region of '{}'",
            queueSize, memoryRegionSize));
    }

    // Initialize the whole buffer with 0x00
    const std::vector<uint8_t> emptyVector(queueSize, 0);
    size_t byteWritten = dataInterface->write(0, emptyVector);
    if (byteWritten != queueSize)
    {
        throw std::runtime_error(
            std::format("[initialize] Only erased '{}'", byteWritten));
    }

    // Create an initial buffer header and write to it
    struct CircularBufferHeader initializationHeader = {};
    initializationHeader.bmcInterfaceVersion =
        boost::endian::native_to_little(bmcInterfaceVersion);
    initializationHeader.queueSize = boost::endian::native_to_little(queueSize);
    initializationHeader.ueRegionSize =
        boost::endian::native_to_little(ueRegionSize);
    std::transform(magicNumber.begin(), magicNumber.end(),
                   initializationHeader.magicNumber.begin(),
                   [](uint32_t number) -> little_uint32_t {
                       return boost::endian::native_to_little(number);
                   });

    uint8_t* initializationHeaderPtr =
        reinterpret_cast<uint8_t*>(&initializationHeader);
    size_t initializationHeaderSize = sizeof(initializationHeader);
    byteWritten = dataInterface->write(
        0, std::span<const uint8_t>(
               initializationHeaderPtr,
               initializationHeaderPtr + initializationHeaderSize));
    if (byteWritten != initializationHeaderSize)
    {
        throw std::runtime_error(std::format(
            "[initialize] Only wrote '{}' bytes of the header", byteWritten));
    }
    cachedBufferHeader = initializationHeader;
}

void BufferImpl::readBufferHeader()
{
    size_t headerSize = sizeof(struct CircularBufferHeader);
    std::vector<uint8_t> bytesRead =
        dataInterface->read(/*offset=*/0, headerSize);

    if (bytesRead.size() != headerSize)
    {
        throw std::runtime_error(
            std::format("Buffer header read only read '{}', expected '{}'",
                        bytesRead.size(), headerSize));
    }

    cachedBufferHeader =
        *reinterpret_cast<struct CircularBufferHeader*>(bytesRead.data());
};

struct CircularBufferHeader BufferImpl::getCachedBufferHeader() const
{
    return cachedBufferHeader;
}

void BufferImpl::updateReadPtr(const uint32_t newReadPtr)
{
    constexpr uint8_t bmcReadPtrOffset =
        offsetof(struct CircularBufferHeader, bmcReadPtr);

    little_uint24_t truncatedReadPtr =
        boost::endian::native_to_little(newReadPtr & 0xffffff);
    uint8_t* truncatedReadPtrPtr =
        reinterpret_cast<uint8_t*>(&truncatedReadPtr);

    size_t writtenSize = dataInterface->write(
        bmcReadPtrOffset, std::span<const uint8_t>{
                              truncatedReadPtrPtr,
                              truncatedReadPtrPtr + sizeof(truncatedReadPtr)});
    if (writtenSize != sizeof(truncatedReadPtr))
    {
        throw std::runtime_error(std::format(
            "[updateReadPtr] Wrote '{}' bytes, instead of expected '{}'",
            writtenSize, sizeof(truncatedReadPtr)));
    }
    cachedBufferHeader.bmcReadPtr = truncatedReadPtr;
}

void BufferImpl::updateBmcFlags(const uint32_t newBmcFlag)
{
    constexpr uint8_t bmcFlagsPtrOffset =
        offsetof(struct CircularBufferHeader, bmcFlags);

    little_uint32_t littleNewBmcFlag =
        boost::endian::native_to_little(newBmcFlag);
    uint8_t* littleNewBmcFlagPtr =
        reinterpret_cast<uint8_t*>(&littleNewBmcFlag);

    size_t writtenSize = dataInterface->write(
        bmcFlagsPtrOffset, std::span<const uint8_t>{
                               littleNewBmcFlagPtr,
                               littleNewBmcFlagPtr + sizeof(little_uint32_t)});
    if (writtenSize != sizeof(little_uint32_t))
    {
        throw std::runtime_error(std::format(
            "[updateBmcFlags] Wrote '{}' bytes, instead of expected '{}'",
            writtenSize, sizeof(little_uint32_t)));
    }
    cachedBufferHeader.bmcFlags = littleNewBmcFlag;
}

std::vector<uint8_t> BufferImpl::wraparoundRead(const uint32_t relativeOffset,
                                                const uint32_t length)
{
    const size_t maxOffset = getMaxOffset();

    if (relativeOffset > maxOffset)
    {
        throw std::runtime_error(
            std::format("[wraparoundRead] relativeOffset '{}' was bigger "
                        "than maxOffset '{}'",
                        relativeOffset, maxOffset));
    }
    if (length > maxOffset)
    {
        throw std::runtime_error(std::format(
            "[wraparoundRead] length '{}' was bigger than maxOffset '{}'",
            length, maxOffset));
    }

    // Do a calculation to see if the read will wraparound
    const size_t queueOffset = getQueueOffset();
    const size_t writableSpace = maxOffset - relativeOffset;
    size_t numWraparoundBytesToRead = 0;
    if (length > writableSpace)
    {
        // This means we will wrap, count the bytes that are left to read
        numWraparoundBytesToRead = length - writableSpace;
    }
    const size_t numBytesToReadTillQueueEnd = length - numWraparoundBytesToRead;

    std::vector<uint8_t> bytesRead = dataInterface->read(
        queueOffset + relativeOffset, numBytesToReadTillQueueEnd);
    if (bytesRead.size() != numBytesToReadTillQueueEnd)
    {
        throw std::runtime_error(
            std::format("[wraparoundRead] Read '{}' which was not "
                        "the requested length of '{}'",
                        bytesRead.size(), numBytesToReadTillQueueEnd));
    }
    size_t updatedReadPtr = relativeOffset + numBytesToReadTillQueueEnd;
    if (updatedReadPtr == maxOffset)
    {
        // If we read all the way up to the end of the queue, we need to
        // manually wrap the updateReadPtr around to 0
        updatedReadPtr = 0;
    }

    // If there are any more bytes to be read beyond the buffer, wrap around and
    // read from the beginning of the buffer (offset by the queueOffset)
    if (numWraparoundBytesToRead > 0)
    {
        std::vector<uint8_t> wrappedBytesRead =
            dataInterface->read(queueOffset, numWraparoundBytesToRead);
        if (numWraparoundBytesToRead != wrappedBytesRead.size())
        {
            throw std::runtime_error(std::format(
                "[wraparoundRead] Buffer wrapped around but read '{}' which "
                "was not the requested lenght of '{}'",
                wrappedBytesRead.size(), numWraparoundBytesToRead));
        }
        bytesRead.insert(bytesRead.end(), wrappedBytesRead.begin(),
                         wrappedBytesRead.end());
        updatedReadPtr = numWraparoundBytesToRead;
    }
    updateReadPtr(updatedReadPtr);

    return bytesRead;
}

struct QueueEntryHeader BufferImpl::readEntryHeader()
{
    size_t headerSize = sizeof(struct QueueEntryHeader);
    // wraparonudRead will throw if it did not read all the bytes, let it
    // propagate up the stack
    std::vector<uint8_t> bytesRead = wraparoundRead(
        boost::endian::little_to_native(cachedBufferHeader.bmcReadPtr),
        headerSize);

    return *reinterpret_cast<struct QueueEntryHeader*>(bytesRead.data());
}

EntryPair BufferImpl::readEntry()
{
    struct QueueEntryHeader entryHeader = readEntryHeader();
    size_t entrySize = boost::endian::little_to_native(entryHeader.entrySize);

    // wraparonudRead may throw if entrySize was bigger than the buffer or if it
    // was not able to read all the bytes, let it propagate up the stack
    std::vector<uint8_t> entry = wraparoundRead(
        boost::endian::little_to_native(cachedBufferHeader.bmcReadPtr),
        entrySize);

    // Calculate the checksum
    uint8_t* entryHeaderPtr = reinterpret_cast<uint8_t*>(&entryHeader);
    uint8_t checksum =
        std::accumulate(entryHeaderPtr,
                        entryHeaderPtr + sizeof(struct QueueEntryHeader), 0,
                        std::bit_xor<void>()) ^
        std::accumulate(entry.begin(), entry.end(), 0, std::bit_xor<void>());

    if (checksum != 0)
    {
        throw std::runtime_error(std::format(
            "[readEntry] Checksum was '{}', expected '0'", checksum));
    }

    return {entryHeader, entry};
}

std::vector<EntryPair> BufferImpl::readErrorLogs()
{
    // Reading the buffer header will update the cachedBufferHeader
    readBufferHeader();

    const size_t maxOffset = getMaxOffset();
    size_t currentBiosWritePtr =
        boost::endian::little_to_native(cachedBufferHeader.biosWritePtr);
    if (currentBiosWritePtr > maxOffset)
    {
        throw std::runtime_error(std::format(
            "[readErrorLogs] currentBiosWritePtr was '{}' which was bigger "
            "than maxOffset '{}'",
            currentBiosWritePtr, maxOffset));
    }
    size_t currentReadPtr =
        boost::endian::little_to_native(cachedBufferHeader.bmcReadPtr);
    if (currentReadPtr > maxOffset)
    {
        throw std::runtime_error(std::format(
            "[readErrorLogs] currentReadPtr was '{}' which was bigger "
            "than maxOffset '{}'",
            currentReadPtr, maxOffset));
    }

    size_t bytesToRead;
    if (currentBiosWritePtr == currentReadPtr)
    {
        // No new payload was detected, return an empty vector gracefully
        return {};
    }

    if (currentBiosWritePtr > currentReadPtr)
    {
        // Simply subtract in this case
        bytesToRead = currentBiosWritePtr - currentReadPtr;
    }
    else
    {
        // Calculate the bytes to the "end" (maxOffset - ReadPtr) +
        // bytes to read from the "beginning" (0 +  WritePtr)
        bytesToRead = (maxOffset - currentReadPtr) + currentBiosWritePtr;
    }

    size_t byteRead = 0;
    std::vector<EntryPair> entryPairs;
    while (byteRead < bytesToRead)
    {
        EntryPair entryPair = readEntry();
        byteRead += sizeof(struct QueueEntryHeader) + entryPair.second.size();
        entryPairs.push_back(entryPair);

        // Note: readEntry() will update cachedBufferHeader.bmcReadPtr
        currentReadPtr =
            boost::endian::little_to_native(cachedBufferHeader.bmcReadPtr);
    }
    if (currentBiosWritePtr != currentReadPtr)
    {
        throw std::runtime_error(std::format(
            "[readErrorLogs] biosWritePtr '{}' and bmcReaddPtr '{}' "
            "are not identical after reading through all the logs",
            currentBiosWritePtr, currentReadPtr));
    }
    return entryPairs;
}

size_t BufferImpl::getMaxOffset()
{
    size_t queueSize =
        boost::endian::little_to_native(cachedBufferHeader.queueSize);
    size_t ueRegionSize =
        boost::endian::little_to_native(cachedBufferHeader.ueRegionSize);

    if (queueSize != QUEUE_REGION_SIZE)
    {
        throw std::runtime_error(std::format(
            "[{}] runtime queueSize '{}' did not match compile-time queueSize "
            "'{}'. This indicates that the buffer was corrupted",
            __FUNCTION__, queueSize, QUEUE_REGION_SIZE));
    }
    if (ueRegionSize != UE_REGION_SIZE)
    {
        throw std::runtime_error(std::format(
            "[{}] runtime ueRegionSize '{}' did not match compile-time "
            "ueRegionSize '{}'. This indicates that the buffer was corrupted",
            __FUNCTION__, ueRegionSize, UE_REGION_SIZE));
    }

    return queueSize - ueRegionSize - sizeof(struct CircularBufferHeader);
}

size_t BufferImpl::getQueueOffset()
{
    size_t ueRegionSize =
        boost::endian::little_to_native(cachedBufferHeader.ueRegionSize);

    if (ueRegionSize != UE_REGION_SIZE)
    {
        throw std::runtime_error(std::format(
            "[{}] runtime ueRegionSize '{}' did not match compile-time "
            "ueRegionSize '{}'. This indicates that the buffer was corrupted",
            __FUNCTION__, ueRegionSize, UE_REGION_SIZE));
    }
    return sizeof(struct CircularBufferHeader) + ueRegionSize;
}

} // namespace bios_bmc_smm_error_logger
