#include "absl/log/log.h"
#include "dbus_utils.hpp"
#include "time_utils.hpp"
#include "health.hpp"

#include <array>
#include <cstdint>
#include <cstddef>
#include <filesystem>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "logging.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/unpack_properties.hpp"

namespace redfish
{

/**
 * Invoked each time Health status for a resource changes.
 */
void HealthStatusCache::processHealthStatusChange(const std::string& dbusPath)
{
    if (healthStatusMap.find(dbusPath) == healthStatusMap.end())
    {
        LOG(ERROR) << "healthStatusMap missing " << dbusPath;
        return;
    }

    healthStatusMap[dbusPath].health = !healthStatusMap[dbusPath].health;
    healthStatusMap[dbusPath].toggleCount += 1;

    std::pair<std::string, std::string> redfishDateTimeOffset =
        redfish::time_utils::getDateTimeOffsetNow();
    if (healthStatusMap[dbusPath].health == false)
    {
        logEntries.push_back(LogEntry(dbusPath, redfishDateTimeOffset.first,
                                      healthStatusMap[dbusPath].severity));
    } else {
        logEntries.push_back(
            LogEntry(dbusPath, redfishDateTimeOffset.first, "OK"));
    }
    healthStatusMap[dbusPath].logId = std::to_string(logEntries.size() - 1);
}

/**
 * Source of Health attributes is Entity manager configuration.
 * objPath points to Dbus object like below:
 * /xyz/openbmc_project/inventory/system/board/<BOARD_NAME>/<CRITERIA_ID>
 */
void HealthStatusCache::getHealthAttributes(const std::string& objPath)
{
    const std::string configService = "xyz.openbmc_project.EntityManager";
    const std::string configInterface =
        "xyz.openbmc_project.Configuration.HealthMonitor";

    managedStore::GetManagedObjectStore()->getAllProperties(
        configService, objPath, configInterface,
        managedStore::ManagedObjectStoreContext(nullptr),
        [this,
         objPath](const boost::system::error_code& ec,
                  const dbus::utility::DBusPropertiesMap& configProperties) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "Failed to get config properties for "
                             << objPath << ": " << ec.message();
            return;
        }
        if (configProperties.empty())
        {
            return;  // No properties found.
        }

        const std::string* criteriaId = nullptr;
        const std::vector<std::string>* messageArgs = nullptr;
        const std::string* failureMessageId = nullptr;
        const std::string* okMessageId = nullptr;
        const std::string* resolution = nullptr;
        const std::string* severity = nullptr;
        const std::string* relatedEntity = nullptr;
        const std::string* relatedEntityType = nullptr;

        if (!sdbusplus::unpackPropertiesNoThrow(
                dbus_utils::UnpackErrorPrinter(), configProperties, "Name",
                criteriaId, "Severity", severity, "FailureMessageId",
                failureMessageId, "OkMessageId", okMessageId, "MessageArgs",
                messageArgs, "Resolution", resolution, "RelatedEntityName",
                relatedEntity, "RelatedEntityType", relatedEntityType))
        {
            return;
        }

        if (criteriaId == nullptr || messageArgs == nullptr ||
            failureMessageId == nullptr || okMessageId == nullptr ||
            resolution == nullptr || severity == nullptr ||
            relatedEntity == nullptr || relatedEntityType == nullptr ||
            messageArgs->size() < 2)
        {
            BMCWEB_LOG_INFO << "Some health attributes not found for "
                            << objPath;
            return;
        }

        HealthAttributes attrs;
        attrs.criteriaId = *criteriaId;
        attrs.messageArgs = *messageArgs;
        attrs.severity = *severity;
        attrs.failureMessageId = *failureMessageId;
        attrs.okMessageId = *okMessageId;
        attrs.resolution = *resolution;
        attrs.fruName = *relatedEntity;
        attrs.fruType = *relatedEntityType;

        std::filesystem::path path(objPath);
        std::string boardPath = path.parent_path().string();
        attrs.boardName = boardPath.substr(
            path.parent_path().parent_path().string().size() + 1);

        const std::string statusService = "xyz.openbmc_project.HealthMonitor";
        std::string statusPath =
            "/xyz/openbmc_project/HealthMonitor/" + attrs.criteriaId;
        const std::string statusInterface =
            "xyz.openbmc_project.HealthMonitor.GetStatus";

        managedStore::GetManagedObjectStore()->getAllProperties(
            statusService, statusPath, statusInterface,
            managedStore::ManagedObjectStoreContext(nullptr),
            [this, objPath, boardPath,
             attrs = std::move(attrs)](const boost::system::error_code& ec2,
                                       const dbus::utility::DBusPropertiesMap&
                                           statusProperties) mutable {
            if (ec2)
            {
                BMCWEB_LOG_ERROR << "Failed to get status for " << objPath
                                 << ": " << ec2.message();
                return;
            }

            const bool* healthy = nullptr;
            const uint64_t* toggleCount = nullptr;
            if (!sdbusplus::unpackPropertiesNoThrow(
                    dbus_utils::UnpackErrorPrinter(), statusProperties,
                    "healthy", healthy, "toggle_count", toggleCount))
            {
                return;
            }

            if (healthy == nullptr || toggleCount == nullptr)
            {
                BMCWEB_LOG_INFO << "Health status not found for " << objPath;
                return;
            }

            attrs.health = *healthy;
            attrs.toggleCount = *toggleCount;

            entityCache[boardPath][attrs.fruType][attrs.fruName].insert(
                objPath);

            if (!attrs.health)
            {
                std::pair<std::string, std::string> redfishDateTimeOffset =
                    redfish::time_utils::getDateTimeOffsetNow();
                logEntries.emplace_back(LogEntry(
                    objPath, redfishDateTimeOffset.first, attrs.severity));
                attrs.logId = std::to_string(logEntries.size() - 1);
            }

            healthStatusMap[objPath] = std::move(attrs);
#ifndef UNIT_TEST_BUILD
            /*
             * This call subscribes to a live D-Bus signal from the HealthMonitor.
             * This directive excludes the live subscription call during the unit test
             * build, allowing the test to verify logic without attempting to create
             * a real signal match which does not exist in the test environment.
             */
            managedStore::GetManagedObjectStore()->subscribeToHealthMonitor(
            "/xyz/openbmc_project/HealthMonitor/" +
            healthStatusMap[objPath].criteriaId);
#endif /* UNIT_TEST_BUILD */
        });
    });
}

HealthStatusCache::HealthStatusCache()
{
    constexpr std::array<std::string_view, 1> interfaces = {
        "xyz.openbmc_project.Configuration.HealthMonitor"};

    managedStore::GetManagedObjectStore()->getSubTreePaths(
        "/xyz/openbmc_project/inventory", 0, interfaces,
        managedStore::ManagedObjectStoreContext(nullptr),
        [this](const boost::system::error_code& ec,
               const dbus::utility::MapperGetSubTreePathsResponse& resp) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "Health monitor GetSubTreePaths failed: "
                             << ec.message();
            return;
        }
        if (resp.empty())
        {
            BMCWEB_LOG_ERROR << "No Health evaluation criterias found.";
            return;
        }

        for (const auto& objPath : resp)
        {
            getHealthAttributes(objPath);
        }
    });
}

/**
 * Populates the Health status information in asyncResp.
 *
 * @return On success, returns std::nullopt.
 * On failure, returns a string with an error message.
 */
std::optional<std::string> HealthStatusCache::healthStatusPopulate(
    std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& oDataId,
    const std::string& boardPath, const std::string& entityType,
    const std::string& entityName, nlohmann::json::json_pointer statusPtr)
{
    auto boardIt = entityCache.find(boardPath);
    if (boardIt == entityCache.end())
    {
        return "Board path '" + boardPath + "' not found in entity cache.";
    }

    auto typeIt = boardIt->second.find(entityType);
    if (typeIt == boardIt->second.end())
    {
        return "Entity type '" + entityType + "' not found for board path '" +
               boardPath + "'.";
    }

    auto nameIt = typeIt->second.find(entityName);
    if (nameIt == typeIt->second.end())
    {
        return "Entity name '" + entityName + "' not found for entity type '" +
               entityType + "'.";
    }

    // Now it's safe to get the set of entity paths
    const std::set<std::string>& entityPaths = nameIt->second;

    size_t i = 0;
    nlohmann::json& jsonStatus = asyncResp->res.jsonValue[statusPtr];
    nlohmann::json& health = jsonStatus["Health"];
    nlohmann::json& rollup = jsonStatus["HealthRollup"];

    // Create Condition redfish resource for unhealthy Object
    for (const auto& entityPath : entityPaths)
    {
        if (healthStatusMap[entityPath].health)
            continue;

        std::string severity = healthStatusMap[entityPath].severity;
        std::vector<std::string> messageArgs =
            healthStatusMap[entityPath].messageArgs;

        jsonStatus["Conditions"][i]["OriginOfCondition"]["@odata.id"] = oDataId;
        jsonStatus["Conditions"][i]["MessageId"] =
            healthStatusMap[entityPath].failureMessageId;
        jsonStatus["Conditions"][i]["Severity"] =
            healthStatusMap[entityPath].severity;
        jsonStatus["Conditions"][i]["Messages"] =
            "The resource property " + messageArgs[0] +
            " has detected errors of type " + messageArgs[1];
        jsonStatus["Conditions"][i]["MessageArgs"] = messageArgs;
        jsonStatus["Conditions"][i]["Resolution"] =
            healthStatusMap[entityPath].resolution;
        jsonStatus["Conditions"][i]["Resolved"] =
            healthStatusMap[entityPath].health;
        jsonStatus["Conditions"][i]["ErrorCount"] =
            (healthStatusMap[entityPath].toggleCount + 1) / 2;
        jsonStatus["Conditions"][i]["DateTime"] =
            healthStatusMap[entityPath].timestamp;

        jsonStatus["Conditions"][i]["LogEntry"]["@odata.id"] =
            "/redfish/v1/Systems/system/LogServices/HealthMonitor/Entries/" +
            healthStatusMap[entityPath].logId;

        if (severity == "Critical")
        {
            health = "Critical";
            rollup = "Critical";
        } else if (severity == "Warning" && health == "OK") {
            health = "Warning";
            rollup = "Warning";
        }
        i++;
    }
    return std::nullopt;  // Success
}

/**
 * Fills a single log entry field
 */
void HealthStatusCache::fillLogEntry(nlohmann::json::object_t& logEntry,
                                     size_t i, const std::string& systemName)
{
    std::string dbusPath = logEntries[i].dbus_path;
    if (healthStatusMap.find(dbusPath) == healthStatusMap.end())
    {
        LOG(ERROR) << "healthStatusMap missing " << dbusPath;
        return;
    }

    std::vector<std::string> messageArgs =
        healthStatusMap[dbusPath].messageArgs;
    std::string severity = logEntries[i].severity;
    logEntry["@odata.id"] = "/redfish/v1/Systems/" + systemName +
                            "/LogServices/HealthMonitor/Entries/" +
                            std::to_string(i);
    logEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";

    if (!healthStatusMap[dbusPath].oDataId.empty())
    {
        logEntry["OriginOfCondition"]["@odata.id"] =
            healthStatusMap[dbusPath].oDataId;
    } else {  // in case oDataId is not initialized
        logEntry["OriginOfCondition"]["@odata.id"] =
            "HealthEvaluationCriteria=" + healthStatusMap[dbusPath].criteriaId;
    }
    logEntry["Created"] = logEntries[i].timestamp;
    logEntry["EntryType"] = "Oem";
    logEntry["Id"] = std::to_string(i);
    logEntry["Message"] = "The resource property " + messageArgs[0] +
                          " has detected errors of type " + messageArgs[1];
    logEntry["MessageArgs"] = messageArgs;
    logEntry["ResolvedEntryId"] = "";
    if (logEntries[i].severity == "OK")
    {
        logEntry["MessageId"] = healthStatusMap[dbusPath].okMessageId;
        logEntry["Resolved"] = true;
        for (int j = static_cast<int>(i) - 1; j >= 0; --j)
        {  // Find previous log entry that corresponds to this resolved entry.
            if (logEntries[static_cast<size_t>(j)].dbus_path == dbusPath &&
                logEntries[static_cast<size_t>(j)].severity != "OK")
            {
                logEntry["ResolvedEntryId"] = std::to_string(j);
                break;
            }
        }
    } else {
        logEntry["MessageId"] = healthStatusMap[dbusPath].failureMessageId;
        logEntry["ErrorCount"] =
            (healthStatusMap[dbusPath].toggleCount + 1) / 2;
        logEntry["Resolved"] = false;
    }
    logEntry["Resolution"] = healthStatusMap[dbusPath].resolution;
    logEntry["Name"] = "Health Monitor Log Entry";
    logEntry["OemRecordFormat"] = "Health Monitor Log Entry";
    logEntry["Severity"] = severity;
}

size_t HealthStatusCache::fillLogEntries(nlohmann::json& logEntryArray,
                                         const std::string& systemName)
{
    logEntryArray = nlohmann::json::array();
    size_t entryCount = logEntries.size();
    for (size_t i = 0; i < entryCount; ++i)
    {
        nlohmann::json::object_t logEntry;
        fillLogEntry(logEntry, i, systemName);
        logEntryArray.push_back(std::move(logEntry));
    }
    return entryCount;
}

}  // namespace redfish
