
#pragma once

#include "app.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "http_request.hpp"
#include "managed_store.hpp"
#include "openbmc_dbus_rest.hpp"
#include "privileges.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "routing.hpp"

#include <boost/algorithm/string/predicate.hpp>
#include <nlohmann/json.hpp>
#include <sdbusplus/asio/property.hpp>

#include <string>
#include <string_view>
#include <unordered_set>

#ifdef UNIT_TEST_BUILD
#include "test/g3/mock_managed_store.hpp" // NOLINT
#endif

namespace redfish
{

using SensorVariantType = dbus::utility::DbusVariantType;

const std::unordered_set<std::string> daemonDoublePropertiesSet{
    "KernelTimeSeconds", "UserTimeSeconds", "UptimeSeconds"};

const std::unordered_set<std::string> daemonU32TPropertiesSet{
    "ResidentSetSizeBytes", "NFileDescriptors", "RestartCount"};

constexpr std::array bootupTimeProperties = {
    "FirmwareTimestampMonotonic",  "LoaderTimestampMonotonic",
    "KernelTimestampMonotonic",    "InitRDTimestampMonotonic",
    "UserspaceTimestampMonotonic", "FinishTimestampMonotonic"};

constexpr std::array bootupTimeMetricName = {
    "FirmwareTimeSeconds", "LoaderTimeSeconds", "KernelTimeSeconds",
    "InitrdTimeSeconds", "UserSpaceTimeSeconds"};

const std::string healthMon = "xyz.openbmc_project.HealthMon";

inline std::optional<std::pair<std::string, std::string>>
    checkAndGetSoleGetSubTreeResponse(
        const dbus::utility::MapperGetSubTreeResponse& subtree)
{
    if (subtree.empty())
    {
        BMCWEB_LOG_DEBUG << "Can't find bmc D-Bus object!";
        return std::nullopt;
    }

    // TODO: Consider Multi-BMC cases
    // Assume only 1 bmc D-Bus object
    // Throw an error if there is more than 1
    if (subtree.size() > 1)
    {
        BMCWEB_LOG_DEBUG << "Found more than 1 bmc D-Bus object!";
        return std::nullopt;
    }

    if (subtree[0].first.empty() || subtree[0].second.size() != 1)
    {
        BMCWEB_LOG_DEBUG << "Error getting bmc D-Bus object!";
        return std::nullopt;
    }

    return std::make_pair(subtree[0].first, subtree[0].second[0].first);
}

// Returns the sole non-Object Mapper service
inline std::optional<std::string> checkAndGetSoleNonMapperGetObjectResponse(
    const dbus::utility::MapperGetObject& objects)
{
    if (objects.empty())
    {
        return std::nullopt;
    }

    for (const std::pair<std::string, std::vector<std::string>>&
             serviceAndIfaces : objects)
    {
        if (serviceAndIfaces.first != "xyz.openbmc_project.ObjectMapper")
        {
            return serviceAndIfaces.first;
        }
    }
    return std::nullopt;
}

inline void populateProcessorStatistics(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    managedStore::ManagedObjectStoreContext context(asyncResp);
    const std::array<std::pair<std::string, std::string>, 2>
        processorStatisticMapping{
            {{"/xyz/openbmc_project/metric/bmc/cpu/kernel", "KernelPercent"},
             {"/xyz/openbmc_project/metric/bmc/cpu/user", "UserPercent"}}};

    for (const auto& mapping : processorStatisticMapping)
    {
        dbus_utils::getProperty<double>(
            healthMon, mapping.first, "xyz.openbmc_project.Metric.Value",
            "Value", context,
            [asyncResp, property(mapping.second)](
                const boost::system::error_code ec2, double value) {
            if (ec2)
            {
                BMCWEB_LOG_ERROR << "DBus response error on getProperty "
                                 << ec2;
                return;
            }
            asyncResp->res.jsonValue["ProcessorStatistics"][property] = value;
        });
    }
}

inline void populateMemoryStatistics(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    managedStore::ManagedObjectStoreContext context(asyncResp);
    dbus_utils::getProperty<double>(
        healthMon, "/xyz/openbmc_project/metric/bmc/memory/available",
        "xyz.openbmc_project.Metric.Value", "Value", context,
        [asyncResp](const boost::system::error_code ec2, double value) {
        if (ec2)
        {
            BMCWEB_LOG_ERROR << "DBus response error on getProperty " << ec2;
            return;
        }
        asyncResp->res.jsonValue["MemoryStatistics"]["AvailableBytes"] =
            static_cast<int64_t>(value);
    });
}

inline void
    populateRWFSStatistics(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    managedStore::ManagedObjectStoreContext context(asyncResp);
    dbus_utils::getProperty<double>(
        healthMon, "/xyz/openbmc_project/metric/bmc/storage/rw",
        "xyz.openbmc_project.Metric.Value", "Value", context,
        [asyncResp](const boost::system::error_code ec, double value) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "DBus response error on getProperty " << ec;
            return;
        }
        asyncResp->res.jsonValue["Oem"]["Google"]["RWStorageSpaceUsageBytes"] =
            static_cast<int64_t>(value);
    });
}

inline void
    populateTMPFSStatistics(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    managedStore::ManagedObjectStoreContext context(asyncResp);
    dbus_utils::getProperty<double>(
        healthMon, "/xyz/openbmc_project/metric/bmc/storage/tmp",
        "xyz.openbmc_project.Metric.Value", "Value", context,
        [asyncResp](const boost::system::error_code ec, double value) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "DBus response error on getProperty " << ec;
            return;
        }
        asyncResp->res.jsonValue["Oem"]["Google"]["TMPStorageSpaceUsageBytes"] =
            static_cast<int64_t>(value);
    });
}

/**
 * @brief Find the endpoints for an Association definition.
 *
 * @param[i,o] asyncResp - Async response object
 *
 * @return void
 */
inline void
    findBmcInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    populateProcessorStatistics(asyncResp);
    populateMemoryStatistics(asyncResp);
    populateRWFSStatistics(asyncResp);
    populateTMPFSStatistics(asyncResp);
}

inline void getBootInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    const std::array<std::string, 2> bootInfoProperties = {
        {"BootCount", "CrashCount"}};

    for (const std::string& propertyName : bootInfoProperties)
    {
        managedStore::ManagedObjectStoreContext context(asyncResp);
        dbus_utils::getProperty<uint32_t>(
            "xyz.openbmc_project.Metric", "/xyz/openbmc_project/metric/bmc0",
            "xyz.openbmc_project.Metric.BMC", propertyName, context,
            [asyncResp, propertyName](const boost::system::error_code ec,
                                      uint32_t property) {
            if (ec)
            {
                BMCWEB_LOG_ERROR << "DBus error getting boot count";
                return;
            }

            asyncResp->res.jsonValue["BootInfo"][propertyName] = property;
        });
    }
}

inline void calculateBootTimeResp(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
        properties)
{
    static_assert(bootupTimeProperties.size() ==
                  bootupTimeMetricName.size() + 1);
    const uint32_t kernelIdx =
        std::find(bootupTimeProperties.begin(), bootupTimeProperties.end(),
                  "KernelTimestampMonotonic") -
        bootupTimeProperties.begin();
    uint64_t lastTime = 0;
    uint32_t metricIdx = 0;

    for (const auto& s : bootupTimeMetricName)
    {
        aResp->res.jsonValue["BootTimeStatistics"][s] = 0.0;
    }
    // each metric should be calculated as next monotime - curr monotime
    // some timestamps maybe 0 if the hardware doesn't support it. In this
    // case we simply set that metrics to 0, and accumulate the diff until
    // an available time is seen
    // e.g. kernelmono initrdmono usermono finishmono is 0, 4, 0, 10
    // The metric values kerneltime initrdtime usertime should be 4, 0, 6
    try
    {
        for (uint32_t i = 0; i < bootupTimeProperties.size(); ++i)
        {
            const uint64_t* currTime = nullptr;
            const bool success = sdbusplus::unpackPropertiesNoThrow(
                dbus_utils::UnpackErrorPrinter(), properties,
                static_cast<std::string>(bootupTimeProperties[i]), currTime);
            if (!success || currTime == nullptr)
            {
                messages::internalError(aResp->res);
                return;
            }

            if (i == 0)
            {
                lastTime = *currTime;
                continue;
            }
            uint64_t timeDiff = 0;
            // KernelTime is 0 and timestamps before kernelTime are negative,
            // timestamps after kernel are positive.
            if (*currTime == 0 && i != kernelIdx)
            {
                continue;
            }

            if (i <= kernelIdx)
            {
                if (lastTime != 0)
                {
                    timeDiff = lastTime - *currTime;
                }
            }
            else
            {
                timeDiff = *currTime - lastTime;
            }

            lastTime = *currTime;

            aResp->res.jsonValue["BootTimeStatistics"]
                                [bootupTimeMetricName[metricIdx]] =
                static_cast<double>(timeDiff) / 1000000.0;
            metricIdx = i;
        }
    }
    catch (...)
    {
        messages::internalError(aResp->res);
    }
}

inline void getBootTimeInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    managedStore::ManagedObjectStoreContext context(asyncResp);
    managedStore::GetManagedObjectStore()->getAllProperties(
        "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
        "org.freedesktop.systemd1.Manager", context,
        [asyncResp](const boost::system::error_code ec2,
                    const dbus::utility::DBusPropertiesMap& properties) {
        if (ec2)
        {
            BMCWEB_LOG_ERROR << "DBUS error getting boot time";
            return;
        }
        calculateBootTimeResp(asyncResp, properties);
    });
}

inline void
    populateDaemonEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                        const std::string& objectPath,
                        const std::string& filterServiceName)
{
    managedStore::ManagedObjectStoreContext context(asyncResp);
    managedStore::GetManagedObjectStore()->getAllProperties(
        "xyz.openbmc_project.Metric", objectPath,
        "xyz.openbmc_project.Metric.Daemon", context,
        [asyncResp, filterServiceName](const boost::system::error_code ec,
                    const dbus::utility::DBusPropertiesMap& propertyMap) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "DBus error getting daemon property";
            return;
        }

        nlohmann::json daemon;

        for (const auto& propertyPair : propertyMap)
        {

            if (propertyPair.first == "CommandLine")
            {
                std::string commandLine =
                    std::get<std::string>(propertyPair.second);
                if (!filterServiceName.empty() &&
                    commandLine.find(filterServiceName) == std::string::npos)
                {
                    BMCWEB_LOG_DEBUG << "Filter param exsits,skipping service:"
                        << commandLine << ". Fitler service name is "
                        << filterServiceName;
                    return;
                }
                daemon[propertyPair.first] = commandLine;
                continue;
            }

            if (daemonDoublePropertiesSet.contains(propertyPair.first))
            {
                daemon[propertyPair.first] =
                    std::get<double>(propertyPair.second);
                continue;
            }

            if (daemonU32TPropertiesSet.contains(propertyPair.first))
            {
                daemon[propertyPair.first] =
                    std::get<uint32_t>(propertyPair.second);
                continue;
            }
        }

        asyncResp->res.jsonValue["TopProcesses"].emplace_back(daemon);
    });
}

inline void getDaemonInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          const query_param::Query& delegatedQuery)
{
    asyncResp->res.jsonValue["TopProcesses"] = nlohmann::json::array();

    std::string filterServiceName;
    if (!delegatedQuery.filter.empty())
    {
        std::vector<std::string> filterParams;
        bmcweb::split(filterParams, delegatedQuery.filter, ' ');

        if (filterParams.size() != 3 ||
            filterParams[0] != "TopProcesses.CommandLine" ||
            filterParams[1] != "eq")
        {
            redfish::messages::queryParameterValueFormatError(
                asyncResp->res, "$filter", delegatedQuery.filter);
            asyncResp->res.result(boost::beast::http::status::not_implemented);
            return;
        }
        filterServiceName = filterParams[2];
    }

    managedStore::ManagedObjectStoreContext context(asyncResp);
    dbus_utils::getProperty<std::vector<std::string>>(
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/metric/bmc0/daemon",
        "xyz.openbmc_project.Association", "endpoints", context,
        [asyncResp, filterServiceName](const boost::system::error_code ec,
                    const std::vector<std::string>& endpoints) {
        if (ec)
        {
            BMCWEB_LOG_ERROR
                << "DBus error getting daemon association endpoints";
            return;
        }

        for (const auto& endpoint : endpoints)
        {
            populateDaemonEntry(asyncResp, endpoint, filterServiceName);
        }
    });
}

inline void getLatencyInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    managedStore::ManagedObjectStoreContext context(asyncResp);
    dbus_utils::getProperty<double>(
        "xyz.openbmc_project.Metric", "/xyz/openbmc_project/metric/bmc0",
        "xyz.openbmc_project.Metric.BMC", "Latency", context,
        [asyncResp](const boost::system::error_code ec, const double property) {
        if (ec)
        {
            BMCWEB_LOG_ERROR
                << "DBus error getting daemon association endpoints";
            return;
        }

        asyncResp->res.jsonValue["Oem"]["Google"]["Latency"] = property;
    });
}

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)
{
    managedStore::ManagedObjectStoreContext context(aResp);
    dbus_utils::getProperty<uint64_t>(
        "org.freedesktop.systemd1",
        "/org/freedesktop/systemd1/unit/bmcweb_2eservice",
        "org.freedesktop.systemd1.Unit", "ActiveEnterTimestampMonotonic",
        context, 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)
{
    query_param::QueryCapabilities capabilities = {
        .canDelegateFilter = true,
    };
    query_param::Query delegatedQuery;
    if (!redfish::setUpRedfishRouteWithDelegation(app, req, asyncResp,
                                    delegatedQuery, capabilities))
    {
        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_STATEFUL_BMCWEB
    asyncResp->res.jsonValue["Oem"]["Google"]["GoogleManagedObjectStoreMetrics"]
                            ["@odata.id"] =
        "/redfish/v1/Managers/bmc/ManagerDiagnosticData/Oem/Google/GoogleManagedObjectStoreMetrics";
#endif

    managerGetServiceRootUptime(asyncResp);

    // Start the first step of the 4-step process to populate
    // the BMC diagnostic data
    findBmcInventory(asyncResp);
    getBootInfo(asyncResp);
    getBootTimeInfo(asyncResp);
    getDaemonInfo(asyncResp, delegatedQuery);
    getLatencyInfo(asyncResp);
}

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)));
}

} // namespace redfish
