#include "config.h"

#include "buffer.hpp"
#include "pci_handler.hpp"
#include "rde/external_storer_file.hpp"
#include "rde/external_storer_interface.hpp"
#include "rde/rde_handler.hpp"

#include <fmt/format.h>

#include <boost/asio.hpp>
#include <boost/endian/conversion.hpp>
#include <stdplus/fd/create.hpp>
#include <stdplus/fd/impl.hpp>
#include <stdplus/fd/managed.hpp>

#include <chrono>
#include <filesystem>
#include <fstream>
#include <functional>
#include <memory>

namespace
{
constexpr std::chrono::milliseconds readIntervalinMs(READ_INTERVAL_MS);
constexpr std::size_t memoryRegionSize = MEMORY_REGION_SIZE;
constexpr std::size_t memoryRegionOffset = MEMORY_REGION_OFFSET;
constexpr uint32_t bmcInterfaceVersion = BMC_INTERFACE_VERSION;
constexpr uint16_t queueSize = QUEUE_REGION_SIZE;
constexpr uint16_t ueRegionSize = UE_REGION_SIZE;
static constexpr std::array<uint32_t, 4> magicNumber = {
    MAGIC_NUMBER_BYTE1, MAGIC_NUMBER_BYTE2, MAGIC_NUMBER_BYTE3,
    MAGIC_NUMBER_BYTE4};
} // namespace

using namespace bios_bmc_smm_error_logger;

void readLoop(boost::asio::steady_timer* t,
              const std::shared_ptr<BufferInterface>& bufferInterface,
              const std::shared_ptr<rde::RdeCommandHandler>& rdeCommandHandler,
              const boost::system::error_code& error)
{
    if (error)
    {
        fmt::print(stderr, "Async wait failed {}\n", error.message());
        return;
    }
    std::vector<EntryPair> entryPairs = bufferInterface->readErrorLogs();
    for (const auto& [entryHeader, entry] : entryPairs)
    {
        fmt::print(stderr, "Read an entry of '{}' bytes\n", entry.size());

        rde::RdeDecodeStatus rdeDecodeStatus =
            rdeCommandHandler->decodeRdeCommand(
                entry,
                static_cast<rde::RdeCommandType>(entryHeader.rdeCommandType));
        if (rdeDecodeStatus == rde::RdeDecodeStatus::RdeStopFlagReceived)
        {
            auto bufferHeader = bufferInterface->getCachedBufferHeader();
            auto newbmcFlags =
                boost::endian::little_to_native(bufferHeader.bmcFlags) |
                static_cast<uint32_t>(BmcFlags::ready);
            bufferInterface->updateBmcFlags(newbmcFlags);
        }
    }

    t->expires_from_now(readIntervalinMs);
    t->async_wait(
        std::bind_front(readLoop, t, bufferInterface, rdeCommandHandler));
}

int main()
{
    boost::asio::io_context io;
    boost::asio::steady_timer t(io, readIntervalinMs);

    // bufferHandler initialization
    std::unique_ptr<stdplus::ManagedFd> managedFd =
        std::make_unique<stdplus::ManagedFd>(stdplus::fd::open(
            "/dev/mem",
            stdplus::fd::OpenFlags(stdplus::fd::OpenAccess::ReadWrite)
                .set(stdplus::fd::OpenFlag::Sync)));
    std::unique_ptr<DataInterface> pciDataHandler =
        std::make_unique<PciDataHandler>(memoryRegionOffset, memoryRegionSize,
                                         std::move(managedFd));
    std::shared_ptr<BufferInterface> bufferHandler =
        std::make_shared<BufferImpl>(std::move(pciDataHandler));

    // rdeCommandHandler initialization
    std::unique_ptr<rde::FileHandlerInterface> fileIface =
        std::make_unique<rde::ExternalStorerFileWriter>();
    std::unique_ptr<rde::ExternalStorerInterface> exFileIface =
        std::make_unique<rde::ExternalStorerFileInterface>(
            "/run/bmcweb", std::move(fileIface));
    std::shared_ptr<rde::RdeCommandHandler> rdeCommandHandler =
        std::make_unique<rde::RdeCommandHandler>(std::move(exFileIface));

    bufferHandler->initialize(bmcInterfaceVersion, queueSize, ueRegionSize,
                              magicNumber);

    t.async_wait(std::bind_front(readLoop, &t, std::move(bufferHandler),
                                 std::move(rdeCommandHandler)));
    io.run();

    return 0;
}
