#include "blob_handler.hpp"

#include <boot_time.pb.h>
#include <fmt/printf.h>

#include <sdbusplus/bus.hpp>

#include <cstdint>
#include <string>
#include <string_view>
#include <variant>
#include <vector>

namespace blobs
{

using CheckpointType = std::vector<std::tuple<std::string, int64_t, int64_t>>;
using DurationType = std::vector<std::tuple<std::string, int64_t>>;

constexpr static std::string_view kHostBlobPath = "/btm/host/0";
constexpr static std::string_view kBMCBlobPath = "/btm/bmc";

namespace BootTimeMonitor
{
constexpr std::string_view kService = "com.google.gbmc.boot_time_monitor";
constexpr std::string_view kHostPath = "/xyz/openbmc_project/time/boot/host0";
constexpr std::string_view kBMCPath = "/xyz/openbmc_project/time/boot/bmc";
} // namespace BootTimeMonitor

namespace Checkpoint
{
constexpr std::string_view kIface = "xyz.openbmc_project.Time.Boot.Checkpoint";
constexpr std::string_view kMethod = "GetCheckpointList";
} // namespace Checkpoint

namespace Duration
{
constexpr std::string_view kIface = "xyz.openbmc_project.Time.Boot.Duration";
constexpr std::string_view kMethod = "GetAdditionalDurations";
} // namespace Duration

namespace Statistic
{
constexpr std::string_view kIface = "org.freedesktop.DBus.Properties";
constexpr std::string_view kMethod = "Get";
constexpr std::string_view kParam1 = "xyz.openbmc_project.Time.Boot.Statistic";
constexpr std::string_view kParam2 = "IsRebooting";
} // namespace Statistic

bool BlobHandler::canHandleBlob(const std::string& path)
{
    return (path == kHostBlobPath) || (path == kBMCBlobPath);
}

// A blob handler may have multiple Blobs.
std::vector<std::string> BlobHandler::getBlobIds()
{
    return {kHostBlobPath.data(), kBMCBlobPath.data()};
}

// BmcBlobDelete (7) is not supported.
bool BlobHandler::deleteBlob([[maybe_unused]] const std::string& path)
{
    return false;
}

// BmcBlobStat (8) (global stat) is not supported.
bool BlobHandler::stat([[maybe_unused]] const std::string& path,
                       [[maybe_unused]] BlobMeta* meta)
{
    return false;
}

// BmcBlobOpen(2) handler.
bool BlobHandler::open(uint16_t session, uint16_t flags,
                       const std::string& path)
{
    if (!isReadOnlyOpenFlags(flags))
    {
        fmt::print(stderr, "[{}] Flag is not read-only. flag={}\n",
                   __FUNCTION__, flags);
        return false;
    }
    if (!canHandleBlob(path))
    {
        fmt::print(stderr, "[{}] Can't handle path={}\n", __FUNCTION__, path);
        return false;
    }

    sdbusplus::bus_t bus = sdbusplus::bus::new_default();
    boottimeproto::BootTime btProto;
    std::string btmPath;
    if (path == kBMCBlobPath)
    {
        btmPath = BootTimeMonitor::kBMCPath;
    }
    else
    {
        btmPath = BootTimeMonitor::kHostPath;
    }

    // Get checkpoints
    try
    {
        auto method = bus.new_method_call(
            BootTimeMonitor::kService.data(), btmPath.c_str(),
            Checkpoint::kIface.data(), Checkpoint::kMethod.data());
        CheckpointType checkpoints;
        bus.call(method).read(checkpoints);
        for (auto checkpoint : checkpoints)
        {
            auto* cpProto = btProto.add_checkpoints();
            cpProto->set_name(std::get<0>(checkpoint));
            cpProto->set_wall_time_ms(std::get<1>(checkpoint));
            cpProto->set_mono_time_ms(std::get<2>(checkpoint));
        }
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        fmt::print(
            stderr,
            "[{}] Failed in method call. service={}, path={}, Iface={}, method={}, error={}\n",
            __FUNCTION__, BootTimeMonitor::kService.data(), btmPath.c_str(),
            Checkpoint::kIface.data(), Checkpoint::kMethod.data(), e.what());
        return false;
    }

    // Get durations
    try
    {
        auto method = bus.new_method_call(
            BootTimeMonitor::kService.data(), btmPath.c_str(),
            Duration::kIface.data(), Duration::kMethod.data());
        DurationType durations;
        bus.call(method).read(durations);
        for (auto duration : durations)
        {
            auto* durProto = btProto.add_durations();
            durProto->set_name(std::get<0>(duration));
            durProto->set_duration_ms(std::get<1>(duration));
        }
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        fmt::print(
            stderr,
            "[{}] Failed in method call. service={}, path={}, Iface={}, method={}, error={}\n",
            __FUNCTION__, BootTimeMonitor::kService.data(), btmPath.c_str(),
            Duration::kIface.data(), Duration::kMethod.data(), e.what());
        return false;
    }

    // Get `IsRebooting`
    try
    {
        auto method = bus.new_method_call(
            BootTimeMonitor::kService.data(), btmPath.c_str(),
            Statistic::kIface.data(), Statistic::kMethod.data());
        method.append(Statistic::kParam1.data(), Statistic::kParam2.data());

        std::variant<bool> isRebooting;
        bus.call(method).read(isRebooting);
        btProto.set_is_rebooting(std::get<bool>(isRebooting));
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        fmt::print(
            stderr,
            "[{}] Failed in method call. service={}, path={}, Iface={}, method={}, param1={}, param2={}, error={}\n",
            __FUNCTION__, BootTimeMonitor::kService.data(), btmPath.c_str(),
            Statistic::kIface.data(), Statistic::kMethod.data(),
            Statistic::kParam1.data(), Statistic::kParam2.data(), e.what());
        return false;
    }

    std::vector<char> vec(btProto.ByteSizeLong());
    if (!btProto.SerializeToArray(vec.data(), static_cast<int>(vec.size())))
    {
        fmt::print(stderr, "[{}]: Could not serialize protobuf to array\n",
                   __FUNCTION__);
        return false;
    }

    sessions[session] = std::move(vec);
    return true;
}

// BmcBlobRead(3) handler.
std::vector<uint8_t> BlobHandler::read(uint16_t session, uint32_t offset,
                                       uint32_t requestedSize)
{
    auto it = sessions.find(session);
    if (it == sessions.end())
    {
        return {};
    }

    if (offset + requestedSize > it->second.size())
    {
        return std::vector<uint8_t>(it->second.data() + offset,
                                    it->second.data() + it->second.size());
    }
    return std::vector<uint8_t>(it->second.data() + offset,
                                it->second.data() + offset + requestedSize);
}

// BmcBlobWrite(4) is not supported.
bool BlobHandler::write([[maybe_unused]] uint16_t session,
                        [[maybe_unused]] uint32_t offset,
                        [[maybe_unused]] const std::vector<uint8_t>& data)
{
    return false;
}

// BmcBlobWriteMeta(10) is not supported.
bool BlobHandler::writeMeta([[maybe_unused]] uint16_t session,
                            [[maybe_unused]] uint32_t offset,
                            [[maybe_unused]] const std::vector<uint8_t>& data)
{
    return false;
}

// BmcBlobCommit(5) is not supported.
bool BlobHandler::commit([[maybe_unused]] uint16_t session,
                         [[maybe_unused]] const std::vector<uint8_t>& data)
{
    return false;
}

// BmcBlobClose(6) handler.
bool BlobHandler::close(uint16_t session)
{
    auto itr = sessions.find(session);
    if (itr == sessions.end())
    {
        return false;
    }
    sessions.erase(itr);
    return true;
}

bool BlobHandler::stat(uint16_t session, BlobMeta* meta)
{
    auto it = sessions.find(session);
    if (it == sessions.end())
    {
        return false;
    }

    meta->size = it->second.size();
    meta->blobState = blobs::StateFlags::open_read;
    return true;
}

bool BlobHandler::expire(uint16_t session)
{
    return close(session);
}

// Checks for a read-only flag.
bool BlobHandler::isReadOnlyOpenFlags(const uint16_t flags)
{
    return ((flags & blobs::OpenFlags::read) == blobs::OpenFlags::read) &&
           ((flags & blobs::OpenFlags::write) == 0);
}

} // namespace blobs
