#include "buffer.hpp"

#include "pci_handler.hpp"

#include <fmt/format.h>

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

#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#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(fmt::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(
            fmt::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(fmt::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(
            fmt::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(fmt::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(fmt::format(
            "[updateBmcFlags] Wrote '{}' bytes, instead of expected '{}'",
            writtenSize, sizeof(little_uint32_t)));
    }
    cachedBufferHeader.bmcFlags = littleNewBmcFlag;
}

size_t BufferImpl::getQueueOffset()
{
    return sizeof(struct CircularBufferHeader) +
           boost::endian::little_to_native(cachedBufferHeader.ueRegionSize);
}

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(
            fmt::format("[wraparoundRead] relativeOffset '{}' was bigger "
                        "than maxOffset '{}'",
                        relativeOffset, maxOffset));
    }
    if (length > maxOffset)
    {
        throw std::runtime_error(fmt::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(
            fmt::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(fmt::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(fmt::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(fmt::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(fmt::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(fmt::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);

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

} // namespace bios_bmc_smm_error_logger
