#pragma once

#include "cper.hpp"

#include <chrono>
#include <concepts>
#include <cstdint>
#include <cstring>
#include <string>

namespace uefi::cper
{
template <typename T>
concept ByteLike = std::is_trivially_copyable_v<T> && sizeof(T) == 1;

/**
 * @brief Helper function to convert time values into BCD format.
 *
 * @example You may have minutes represented as base10 20 which is 0x14. BCD
 * expects the values to be represented as 0x20.
 *
 * @param[in] val - The value to convert to BCD.
 *
 * @returns a byte with the BCD val.
 */
inline uint8_t convertToBcd(uint8_t val)
{
    return (0x10 * (val / 10)) + (val % 10);
}

/**
 * @brief Helper function to create a UTC UEFI CPER timestamp from a
 * std::chrono time point.
 * https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record.html#record-header
 *
 * @param[in] timeOfCollection - A std::chrono time_point representing the time
 * the fault was detected by the system software.
 * @param[in] isPrecise - Bool which indicates if the time is precise.
 *
 * @param[out] A uefi cper timestamp as uint64_t.
 */
inline uint64_t createCperTimestamp(
    const std::chrono::time_point<std::chrono::system_clock> timeOfCollection,
    const bool isPrecise = true)
{
    // Number of years in a century.
    constexpr int kCentury = 100;

    // The tm_year counts the number of years since 1900.
    // https://en.cppreference.com/w/c/chrono/tm
    constexpr int kTmYearOffset = 1900;

    // UEFI expects the isPrecise byte bits [1:7] to be zero.
    const uint8_t isPreciseBit = 0 | (isPrecise & 0x1);

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

    // The uefi timestamp breaks the calendar year into two bytes
    // representing the number of centuries and number of years.
    const int calendarYear = utcTime.tm_year + kTmYearOffset;
    const uint8_t year = calendarYear % kCentury;
    const uint8_t century = calendarYear / kCentury;

    const Timestamp timestamp{
        .seconds = convertToBcd(utcTime.tm_sec),
        .minutes = convertToBcd(utcTime.tm_min),
        .hours = convertToBcd(utcTime.tm_hour),
        .isPrecise = isPreciseBit,
        .day = convertToBcd(utcTime.tm_mday),
        // tm_mon is months since January, add one to get current month.
        .month = convertToBcd(utcTime.tm_mon + 1),
        .year = convertToBcd(year),
        .century = convertToBcd(century)};

    uint64_t ret;
    memcpy(&ret, &timestamp, sizeof(ret));
    return ret;
}

template <ByteLike ByteType>
class SeqMemcopy
{
  public:
    // Prevent the class from outliving the baseDest pointer.
    SeqMemcopy() = delete;
    SeqMemcopy(const SeqMemcopy&) = delete;
    SeqMemcopy& operator=(const SeqMemcopy&) = delete;

    /**
     * @brief Manages sequentially copying chunks of data to a contiguous memory
     * block.
     *
     * @param[in] baseDest - The memory location to copy to.
     */
    SeqMemcopy(std::span<ByteType> baseDest) : baseDest_(baseDest), offset_(0)
    {}

    /**
     * @brief Copies the src to the next section in the dest address.
     *
     * @param[in] src - The source address to copy from.
     * @param[in] srcSize - The source size.
     *
     * @throws out_of_range If source size goes out of the destinations bounds.
     */
    void copy(const void* src, const uint64_t srcSize)
    {
        if ((offset_ + srcSize) > baseDest_.size_bytes())
        {
            throw std::out_of_range(
                "Attempt to copy out of the destinations bounds");
        }

        memcpy(baseDest_.data() + offset_, src, srcSize);
        offset_ += srcSize;
    }

  private:
    std::span<ByteType> baseDest_;
    uint64_t offset_;
};

template <ByteLike BodyType>
class CperEncoder
{
  public:
    CperEncoder() : totalSectionBodySizeBytes_(0)
    {}

    /**
     * @brief Implementation specific CPER encoders must define how to create
     * RecordHeaders.
     * https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record.html#record-header
     *
     * @param[in] recordLength - The length in bytes of the entire record.
     * @param[in] sectionCount - The number of sections in the record.
     */
    virtual RecordHeader createRecordHeader(const uint32_t recordLength,
                                            const uint16_t sectionCount) = 0;

    /**
     * @brief Implementation specific CPER encoders must define how to create
     * new sectionDescriptors.
     * https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record.html#section-descriptor
     *
     * @param[in] sectionLength - The length in bytes of the section body.
     * @param[in] sectionOffset - The offset in bytes from the section body from
     * the base of the record header.
     * @param[in] sectionFlags - Information that describes the error section.
     * @param[in] sectionType - The ID of the sectionType; useful for
     * implementations with multiple section types.
     *
     * @return A SectionDescriptor struct.
     */
    virtual SectionDescriptor createSectionDescriptor(
        const uint32_t sectionLength, const uint32_t sectionOffset,
        const uint32_t sectionFlags, const guid_t sectionType) = 0;

    /**
     * @brief Adds a new CPER section for the encoder to track.
     *
     * @note Cper logs have a max size of 4GiB including the header and
     * descriptors.
     *
     * @param[in] sectionBody - A span containing the section data as a byte
     * array.
     * @param[in] sectionFlags - The CPER flags for the section.
     * @param[in] sectionType - The guid_t for the section.
     *
     * @warning The CperEncoder class does not own the ptrs of the
     * sectionBodies, it merely tracks the addresses and size. It is expected
     * that the data added to the encoder exists for the entire lifetime of the
     * CperEncoder object.
     *
     * @returns true on success, false if new section goes over the 4GiB
     * threshold.
     */
    bool addSection(const std::span<const BodyType> sectionBody,
                    const uint32_t sectionFlags, const guid_t sectionType)
    {
        if ((calculateRecordLengthBytes() + sectionBody.size_bytes() +
             kSectionDescriptorSizeBytes) >
            std::numeric_limits<uint32_t>::max())
        {
            return false;
        }

        sectionSeeds_.emplace_back(sectionFlags, sectionType, sectionBody);
        totalSectionBodySizeBytes_ += sectionBody.size_bytes();
        return true;
    }

    /**
     * @brief Serializes the CPER Log into a vector of bytes.
     *
     * @return A byte array containing the CPER log contents.
     */
    std::vector<uint8_t> serializeToByteArray()
    {
        const uint64_t totalBytes = calculateRecordLengthBytes();
        std::vector<uint8_t> byteArray(totalBytes);

        encode<uint8_t>(byteArray);
        return byteArray;
    }

    /**
     * @brief Serializes the CPER Log into a string.
     *
     * @return A string containing the CPER log contents.
     */
    std::string serializeToString()
    {
        const uint64_t totalBytes = calculateRecordLengthBytes();
        std::string str(totalBytes, 0);

        encode<char>(str);
        return str;
    }

  private:
    // Save ~3x memory by only caching the section "seeds" and keeping a
    // single full sectionDescriptor on the stack at a time while encoding
    // the log.
    struct SectionSeed
    {
        uint32_t sectionFlags;
        guid_t sectionType;
        std::span<const BodyType> body;
    };

    /**
     * @brief Calculates the total size of the CPER log.
     *
     * @return The total size in bytes.
     */
    uint32_t calculateRecordLengthBytes() const
    {
        return kRecordHeaderSizeBytes +
               (sectionSeeds_.size() * kSectionDescriptorSizeBytes) +
               totalSectionBodySizeBytes_;
    }

    /**
     * @brief Encodes the CPER byte array to the destination pointer.
     *
     * @tparam ByteType - Allows for different cpp byte representations (char,
     * unsigned char, std::byte, etc.)
     *
     * @param[in,out] dest - The destination span to copy the data to.
     *
     * @throws If unable to successfully encode the CPER log.
     */
    template <ByteLike ByteType>
    void encode(std::span<ByteType> dest)
    {
        SeqMemcopy seqMemcpy(dest);
        {
            const RecordHeader header =
                createRecordHeader(dest.size_bytes(), sectionSeeds_.size());

            seqMemcpy.copy(&header, kRecordHeaderSizeBytes);
        }

        // Offset in bytes of the section body from the base of the record
        // header.
        uint64_t sectionOffset =
            kRecordHeaderSizeBytes +
            (sectionSeeds_.size() * kSectionDescriptorSizeBytes);

        for (const SectionSeed& seed : sectionSeeds_)
        {
            // Creates a struct with the following modifiable fields - note this
            // is a temporary struct which is then sequentially copied to a
            // contiguous array.
            const SectionDescriptor descriptor =
                createSectionDescriptor(seed.body.size_bytes(), sectionOffset,
                                        seed.sectionFlags, seed.sectionType);
            sectionOffset += seed.body.size_bytes();

            seqMemcpy.copy(&descriptor, kSectionDescriptorSizeBytes);
        }

        for (const auto& seed : sectionSeeds_)
        {
            seqMemcpy.copy(seed.body.data(), seed.body.size_bytes());
        }
    }

    uint32_t totalSectionBodySizeBytes_;
    std::vector<SectionSeed> sectionSeeds_;
};
} // namespace uefi::cper
