#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 <sdbusplus/asio/object_server.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::shared_ptr<sdbusplus::asio::connection> conn =
        std::make_shared<sdbusplus::asio::connection>(io);
    conn->request_name("xyz.openbmc_project.bios_bmc_smm_error_logger");
    sdbusplus::bus::bus& bus = static_cast<sdbusplus::bus::bus&>(*conn);

    std::unique_ptr<rde::FileHandlerInterface> fileIface =
        std::make_unique<rde::ExternalStorerFileWriter>();
    std::unique_ptr<rde::ExternalStorerInterface> exFileIface =
        std::make_unique<rde::ExternalStorerFileInterface>(
            bus, "/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;
}
