#pragma once

#include "app.hpp"
#include "async_resp.hpp"
#include "grpc_statistics.h"
#include "http_request.hpp"
#include "privileges.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "routing.hpp"

#include <nlohmann/json.hpp>
#include <sdbusplus/asio/property.hpp>

#include <string>

namespace redfish
{

inline void
    afterGetManagerStartTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                             const boost::system::error_code& ec,
                             uint64_t bmcwebResetTime)
{
    if (ec)
    {
        // Not all servers will be running in systemd, so ignore the error.
        return;
    }
    using std::chrono::steady_clock;

    std::chrono::duration<steady_clock::rep, std::micro> usReset{
        bmcwebResetTime};
    steady_clock::time_point resetTime{usReset};

    steady_clock::time_point now = steady_clock::now();

    steady_clock::duration runTime = now - resetTime;

    if (runTime < steady_clock::duration::zero())
    {
        BMCWEB_LOG_CRITICAL << "Uptime was negative????";
        messages::internalError(aResp->res);
        return;
    }

    // Floor to the closest millisecond
    using Milli = std::chrono::duration<steady_clock::rep, std::milli>;
    Milli milli = std::chrono::floor<Milli>(runTime);

    using SecondsFloat = std::chrono::duration<double>;
    SecondsFloat sec = std::chrono::duration_cast<SecondsFloat>(milli);

    aResp->res.jsonValue["ServiceRootUptimeSeconds"] = sec.count();
}

inline void
    managerGetServiceRootUptime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
{
    sdbusplus::asio::getProperty<uint64_t>(
        *crow::connections::systemBus, "org.freedesktop.systemd1",
        "/org/freedesktop/systemd1/unit/bmcweb_2eservice",
        "org.freedesktop.systemd1.Unit", "ActiveEnterTimestampMonotonic",
        std::bind_front(afterGetManagerStartTime, aResp));
}
/**
 * handleManagerDiagnosticData supports ManagerDiagnosticData.
 * It retrieves BMC health information from various DBus resources and returns
 * the information through the response.
 */
inline void handleManagerDiagnosticDataGet(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    asyncResp->res.jsonValue["@odata.type"] =
        "#ManagerDiagnosticData.v1_2_0.ManagerDiagnosticData";
    asyncResp->res.jsonValue["@odata.id"] =
        "/redfish/v1/Managers/bmc/ManagerDiagnosticData";
    asyncResp->res.jsonValue["Id"] = "ManagerDiagnosticData";
    asyncResp->res.jsonValue["Name"] = "Manager Diagnostic Data";

#ifdef BMCWEB_ENABLE_REDFISH_OEM_GRPC_STATS
    asyncResp->res.jsonValue["Oem"]["Google"]["@odata.type"] =
        "#GoogleManagerDiagnosticData.v1_0_0.GoogleManagerDiagnosticData";
    asyncResp->res.jsonValue["Oem"]["Google"]["gRPCStatistics"]["@odata.id"] =
        "/redfish/v1/Managers/bmc/ManagerDiagnosticData/Oem/Google/"
        "GooglegRPCStatistics";
#endif
    managerGetServiceRootUptime(asyncResp);
}

#ifdef BMCWEB_ENABLE_REDFISH_OEM_GRPC_STATS

inline void handleManagerDiagnosticDataGooglegRPCStatsHead(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    asyncResp->res.addHeader(
        boost::beast::http::field::link,
        "</redfish/v1/JsonSchemas/GoogleManagerDiagnosticData/"
        "GooglegRPCStatistics.json>; rel=describedby");
}

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

    nlohmann::json& j = asyncResp->res.jsonValue;
    j["@odata.id"] =
        "/redfish/v1/Managers/bmc/ManagerDiagnosticData/Oem/Google/"
        "GooglegRPCStatistics";
    j["@odata.type"] =
        "#GooglegRPCStatistics.v1_0_0.GooglegRPCStatistics";
    j["Id"] = "GooglegRPCStatistics";
    j["Name"] = "Google gRPC Statistics";

    grpc_redfish::gRPCStatisticsShared shared_stats;
    grpc_redfish::gRPCStatistics stats = shared_stats.GetgRPCStatistics();

    j["gRPCInitLatencyMs"] = stats.grpc_init_latency_ms.count();
    j["AuthenticationLatencyMs"] = stats.authn_latency_total_ms.count();
    j["QueueLatencyMs"] = stats.queue_latency_total_ms.count();
    j["RequestLatencyMs"] = stats.request_latency_total_ms.count();
    j["AuthorizationLatencyMs"] = stats.authz_latency_total_ms.count();
    j["ProcessingLatencyMs"] = stats.processing_latency_total_ms.count();
    j["ResponseLatencyMs"] = stats.response_latency_total_ms.count();

    j["AuthorizedCount"] = stats.total_authorized_count;
    j["AuthorizedFailCount"] = stats.total_authorized_fail_count;
    j["AuthenticatedCount"] = stats.total_authenticated_count;
    j["AuthenticatedFailCount"] = stats.total_authenticated_fail_count;

    nlohmann::json::array_t httpMethodCounts;
    for (auto const& [http, count] : stats.request_count)
    {
        nlohmann::json::object_t countObj;
        countObj["Method"] = static_cast<unsigned>(http);
        countObj["Count"] = static_cast<unsigned>(count);
        httpMethodCounts.emplace_back(std::move(countObj));
    }
    nlohmann::json::array_t httpResponseCounts;
    for (auto const& [response, count] : stats.http_response_count)
    {
        nlohmann::json::object_t countObj;
        countObj["StatusCode"] = static_cast<unsigned>(response);
        countObj["Count"] = static_cast<unsigned>(count);
        httpResponseCounts.emplace_back(std::move(countObj));
    }
    nlohmann::json::array_t gRPCStatusCounts;
    for (auto const& [status, count] : stats.grpc_response_count)
    {
        nlohmann::json::object_t countObj;
        countObj["StatusCode"] = static_cast<unsigned>(status);
        countObj["Count"] = static_cast<unsigned>(count);
        gRPCStatusCounts.emplace_back(std::move(countObj));
    }
    j["HTTPMethods"] = std::move(httpMethodCounts);
    j["HTTPResponseCodes"] = std::move(httpResponseCounts);
    j["gRPCResponseCodes"] = std::move(gRPCStatusCounts);
}
#endif

inline void requestRoutesManagerDiagnosticData(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/ManagerDiagnosticData")
        .privileges(redfish::privileges::getManagerDiagnosticData)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleManagerDiagnosticDataGet, std::ref(app)));

#ifdef BMCWEB_ENABLE_REDFISH_OEM_GRPC_STATS
    BMCWEB_ROUTE(
        app,
        "/redfish/v1/Managers/bmc/ManagerDiagnosticData/Oem/Google/"
        "GooglegRPCStatistics")
        .privileges(redfish::privileges::headManagerDiagnosticData)
        .methods(boost::beast::http::verb::head)(std::bind_front(
            handleManagerDiagnosticDataGooglegRPCStatsHead, std::ref(app)));

    BMCWEB_ROUTE(
        app,
        "/redfish/v1/Managers/bmc/ManagerDiagnosticData/Oem/Google/"
        "GooglegRPCStatistics")
        .privileges(redfish::privileges::getManagerDiagnosticData)
        .methods(boost::beast::http::verb::get)(std::bind_front(
            handleManagerDiagnosticDataGooglegRPCStatsGet, std::ref(app)));
#endif
}

} // namespace redfish
