#pragma once

#include "app.hpp"
#include "power_supply.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "sensors.hpp"
#include "utils/chassis_utils.hpp"
#include "utils/dbus_utils.hpp"

#include <functional>
#include <memory>
#include <optional>
#include <string>

namespace redfish
{

inline void
    doPowerSupplyMetrics(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                         const std::string& chassisId,
                         const std::string& powerSupplyId,
                         const std::optional<std::string>& validChassisPath)
{
    if (!validChassisPath)
    {
        messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
        return;
    }

    asyncResp->res.addHeader(
        boost::beast::http::field::link,
        "</redfish/v1/JsonSchemas/PowerSupplyMetrics/PowerSupplyMetrics.json>; rel=describedby");
    asyncResp->res.jsonValue["@odata.type"] =
        "#PowerSupplyMetrics.v1_0_1.PowerSupplyMetrics";
    asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Chassis", chassisId, "PowerSubsystem",
        "PowerSupplies", powerSupplyId, "Metrics");
    asyncResp->res.jsonValue["Id"] = "Metrics";
    asyncResp->res.jsonValue["Name"] = "PowerSupply Metrics";

    managedStore::ManagedObjectStoreContext context(asyncResp);
    dbus_utils::getProperty<std::string>(
        "xyz.openbmc_project.EntityManager",
        "/xyz/openbmc_project/inventory/system/board/" + powerSupplyId,
        "xyz.openbmc_project.Inventory.Item.PowerSupply", "Sensor", context,
        [asyncResp, context, powerSupplyId](const boost::system::error_code ec,
                                             const std::string& sensorPath) {
        if (ec)
        {
            BMCWEB_LOG_DEBUG << "getVoltageSensor got DBUS response error";
            return;
        }

        dbus_utils::getProperty<double>(
            "xyz.openbmc_project.PSUSensor", sensorPath,
            "xyz.openbmc_project.Sensor.Value", "Value", context,
            [asyncResp](const boost::system::error_code ec,
                        const double sensorValue) {
            if (ec)
            {
                BMCWEB_LOG_DEBUG << "getSensorValue got DBUS response error";
                return;
            }
            asyncResp->res.jsonValue["InputPowerWatts"]["Reading"] =
                sensorValue;
        });

        const auto sensorName =
            sdbusplus::message::object_path(sensorPath).filename();

        asyncResp->res.jsonValue["InputPowerWatts"]["DataSourceUri"] =
            crow::utility::urlFromPieces("redfish", "v1", "Chassis",
                                         powerSupplyId, "Sensors", sensorName);
    });
}

inline void handlePowerSupplyMetricsGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& powerSupplyId)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    redfish::chassis_utils::getValidChassisPath(
        asyncResp, chassisId,
        [asyncResp, chassisId,
         powerSupplyId](const std::optional<std::string>& validChassisPath) {
        if (!validChassisPath)
        {
            messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
            return;
        }

        // Get the correct Path and Service that match the input parameters
        getValidPowerSupplyPath(asyncResp, *validChassisPath, powerSupplyId,
                                std::bind_front(doPowerSupplyMetrics, asyncResp,
                                                chassisId, powerSupplyId));
    });
}

inline void handlePowerSupplyMetricsHead(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& powerSupplyId)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    redfish::chassis_utils::getValidChassisPath(
        asyncResp, chassisId,
        [asyncResp, chassisId,
         powerSupplyId](const std::optional<std::string>& validChassisPath) {
        if (!validChassisPath)
        {
            messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
            return;
        }

        // Get the correct Path and Service that match the input parameters
        getValidPowerSupplyPath(asyncResp, *validChassisPath, powerSupplyId,
                                [asyncResp](const std::string&) {
            asyncResp->res.addHeader(
                boost::beast::http::field::link,
                "</redfish/v1/JsonSchemas/PowerSupplyMetrics/PowerSupplyMetrics.json>; rel=describedby");
        });
    });
}

inline void requestRoutesPowerSupplyMetrics(App& app)
{
    BMCWEB_ROUTE(
        app,
        "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/<str>/Metrics")
        .privileges(redfish::privileges::headPowerSupplyMetrics)
        .methods(boost::beast::http::verb::head)(
            std::bind_front(handlePowerSupplyMetricsHead, std::ref(app)));

    BMCWEB_ROUTE(
        app,
        "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/<str>/Metrics")
        .privileges(redfish::privileges::getPowerSupplyMetrics)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handlePowerSupplyMetricsGet, std::ref(app)));
}

} // namespace redfish
