#include "report_factory.hpp"

#include "metric.hpp"
#include "report.hpp"
#include "sensor.hpp"
#include "utils/transform.hpp"

ReportFactory::ReportFactory(
    std::shared_ptr<sdbusplus::asio::connection> bus,
    const std::shared_ptr<sdbusplus::asio::object_server>& objServer) :
    bus(std::move(bus)),
    objServer(objServer)
{}

std::unique_ptr<interfaces::Report> ReportFactory::make(
    std::optional<std::reference_wrapper<boost::asio::yield_context>> yield,
    const std::string& name, const std::string& reportingType,
    bool emitsReadingsSignal, bool logToMetricReportsCollection,
    std::chrono::milliseconds period, const ReadingParameters& metricParams,
    interfaces::ReportManager& reportManager,
    interfaces::JsonStorage& reportStorage) const
{
    std::optional<std::vector<ReportFactory::SensorTree>> sensorTree;

    std::vector<std::shared_ptr<interfaces::Metric>> metrics;
    metrics.reserve(metricParams.size());

    for (const auto& [sensorPaths, op, id, metadata] : metricParams)
    {
        if (!sensorTree && yield && sensorPaths.size() > 0)
        {
            sensorTree = getSensorTree(*yield);
        }

        std::vector<std::shared_ptr<interfaces::Sensor>> sensors =
            getSensors(sensorTree, sensorPaths);

        metrics.emplace_back(
            std::make_shared<Metric>(std::move(sensors), op, id, metadata));
    }

    return std::make_unique<Report>(
        bus->get_io_context(), objServer, name, reportingType,
        emitsReadingsSignal, logToMetricReportsCollection, period, metricParams,
        reportManager, reportStorage, std::move(metrics));
}

std::vector<std::shared_ptr<interfaces::Sensor>> ReportFactory::getSensors(
    const std::optional<std::vector<ReportFactory::SensorTree>>& tree,
    const std::vector<sdbusplus::message::object_path>& sensorPaths) const
{
    if (tree)
    {
        std::vector<std::shared_ptr<interfaces::Sensor>> sensors;

        for (const auto& [sensor, ifacesMap] : *tree)
        {
            auto it = std::find(sensorPaths.begin(), sensorPaths.end(), sensor);
            if (it != sensorPaths.end())
            {
                for (const auto& [service, ifaces] : ifacesMap)
                {
                    sensors.emplace_back(sensorCache.makeSensor<Sensor>(
                        service, sensor, bus->get_io_context(), bus));
                }
            }
        }

        return sensors;
    }
    else
    {
        return utils::transform(
            sensorPaths,
            [this](const std::string& sensor)
                -> std::shared_ptr<interfaces::Sensor> {
                std::string::size_type pos = sensor.find_first_of(":");
                auto service = sensor.substr(0, pos);
                auto path = sensor.substr(pos + 1);
                return sensorCache.makeSensor<Sensor>(
                    service, path, bus->get_io_context(), bus);
            });
    }
}

std::vector<ReportFactory::SensorTree>
    ReportFactory::getSensorTree(boost::asio::yield_context& yield) const
{
    std::array<const char*, 1> interfaces = {
        "xyz.openbmc_project.Sensor.Value"};
    boost::system::error_code ec;

    auto result = bus->yield_method_call<std::vector<SensorTree>>(
        yield, ec, "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
        "/xyz/openbmc_project/sensors", 2, interfaces);
    if (ec)
    {
        throw std::runtime_error("failed");
    }
    return result;
}
