#include "NVMeMetricStore.hpp"

#include <xyz/openbmc_project/Common/File/error.hpp>
#include <xyz/openbmc_project/Common/error.hpp>

sdbusplus::message::unix_fd
    MetricStore::writeToFd(std::span<const uint8_t> header,
                           std::span<const uint8_t> data)
{
    std::array<int, 2> pipe{};
    if (::pipe(pipe.data()) < 0)
    {
        std::cerr << "Metric Fetcher failed due to pipe creation "
                  << std::strerror(errno) << "\n";
        throw sdbusplus::xyz::openbmc_project::Common::File::Error::Open{};
    }

    auto asyncPipe =
        std::make_shared<boost::asio::posix::stream_descriptor>(io, pipe[1]);
    std::weak_ptr<boost::asio::posix::stream_descriptor> weakPipe = asyncPipe;

    auto asyncBuffer = std::make_shared<std::vector<uint8_t>>(header.begin(),
                                                              header.end());
    asyncBuffer->insert(asyncBuffer->end(), data.begin(), data.end());

    boost::asio::async_write(
        *asyncPipe, boost::asio::buffer(*asyncBuffer),
        [asyncPipe, asyncBuffer](const boost::system::error_code& error,
                                 std::size_t /* transferredSize */) {
        if (error)
        {
            std::cerr << "Metric Fetcher fails to write fd: " << error.message()
                      << "\n";
        }
    });

    // close the read end of the pipe after waiting for 5 seconds
    // It is expected that the client has duplicated the fd in this time
    auto timer = std::make_shared<boost::asio::steady_timer>(io);
    timer->expires_after(std::chrono::seconds(5));
    timer->async_wait([timer, fd{pipe[0]},
                       weakPipe](const boost::system::error_code& /* ec */) {
        auto pipe = weakPipe.lock();
        if (pipe)
        {
            pipe->cancel();
        }
        close(fd);
    });

    // Return the read end wrapped in a stream descriptor
    return sdbusplus::message::unix_fd{pipe[0]};
}

sdbusplus::message::unix_fd MetricStore::getMetric(std::string name)
{
    auto it = metricStore.find(name);
    if (it == metricStore.end() || !it->second)
    {
        std::cerr << std::format("[{}, {}]cannot find the target Metric",
                                 this->path, name);
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument{};
    }

    if (!it->second->isCacheValid())
    {
        std::cerr << std::format("[{}, {}]the Metric cache is invalid",
                                 this->path, name);
        throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable{};
    }
    auto data = it->second->getCache();
    // Send the data and header to be written to pipe
    MetricHeader header{};
    header.lens = boost::endian::little_uint32_t(sizeof(header));
    header.version = 0;
    header.dataFormat = 0;
    header.startTime = boost::endian::little_uint64_t(
        std::get<0>(data).time_since_epoch().count());
    header.finishTime = boost::endian::little_uint64_t(
        std::get<1>(data).time_since_epoch().count());

    return writeToFd(
        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
        std::span<uint8_t>(reinterpret_cast<std::uint8_t*>(&header),
                           sizeof(header)),
        std::get<2>(data));
}

void MetricStore::signalHelper(
    std::string_view name,
    const std::shared_ptr<MetricBase<std::chrono::steady_clock>>&
        metric) noexcept
{
    if (!metric->isCacheValid())
    {
        // broadcast invalid metric signal
        metricUpdated(std::string{name}, {});
        return;
    }

    auto data = metric->getCache();
    std::vector<uint8_t> headerBuf;
    headerBuf.resize(sizeof(MetricHeader));
    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
    MetricHeader& header = *reinterpret_cast<MetricHeader*>(headerBuf.data());
    header.lens = boost::endian::little_uint32_t(sizeof(header));
    header.version = 0;
    header.dataFormat = 0;
    header.startTime = boost::endian::little_uint64_t(
        std::get<0>(data).time_since_epoch().count());
    header.finishTime = boost::endian::little_uint64_t(
        std::get<1>(data).time_since_epoch().count());
    metricUpdated(std::string{name}, headerBuf);
};
