#pragma once

#include "managed_store_types.hpp"

#include <dbus_utility.hpp>
#include <human_sort.hpp>
#include <sdbusplus/asio/property.hpp>
#include <utility.hpp>
#include <utils/dbus_utils.hpp>
#include <utils/json_utils.hpp>
#include <utils/location_utils.hpp>

#include "managed_store.hpp"

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

namespace redfish
{
inline void addAssemblyAssetProperties(
    const std::string& serviceName, const std::string& path,
    const std::shared_ptr<bmcweb::AsyncResp>& aResp, std::size_t index)
{
    managedStore::ManagedObjectStoreContext context(aResp);
    managedStore::GetManagedObjectStore()->getAllProperties(
        serviceName, path, "xyz.openbmc_project.Inventory.Decorator.Asset",
        context,
        [aResp, index](const boost::system::error_code ec,
                       const dbus::utility::DBusPropertiesMap& propertiesList) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "Failed to get asset properties: " << ec;
            messages::internalError(aResp->res);
            return;
        }

        nlohmann::json& assembliesJson = aResp->res.jsonValue["Assemblies"];
        if (!assembliesJson.is_array() || assembliesJson.size() <= index)
        {
            BMCWEB_LOG_ERROR << "Assemblies list too small";
            messages::internalError(aResp->res);
            return;
        }

        for (const auto& [propertyName, value] : propertiesList)
        {
            // This should really be a string_view, but nlohmann::json
            // doesn't support string_view keys.
            std::string jsonKey;
            if ((propertyName == "PartNumber") ||
                (propertyName == "SerialNumber") || (propertyName == "Model") ||
                (propertyName == "SparePartNumber"))
            {
                jsonKey = propertyName;
            }
            else if (propertyName == "Manufacturer")
            {
                jsonKey = "Producer";
            }
            else if (propertyName == "BuildDate")
            {
                jsonKey = "ProductionDate";
            }
            else
            {
                // Not supported.
                BMCWEB_LOG_WARNING << "Unsupported assembly asset "
                                   << propertyName;
                continue;
            }

            const auto* valueStr = std::get_if<std::string>(&value);
            if (valueStr == nullptr)
            {
                BMCWEB_LOG_ERROR << "Null value returned for " << propertyName;
                messages::internalError(aResp->res);
                return;
            }
            // SparePartNumber default is empty
            if (propertyName == "SparePartNumber" && valueStr->empty())
            {
                continue;
            }

            assembliesJson[index][jsonKey] = *valueStr;
        }
        });
}

inline void getAssemblyPrettyName(
    const std::string& serviceName, const std::string& path,
    const std::shared_ptr<bmcweb::AsyncResp>& aResp, std::size_t index)
{
    managedStore::ManagedObjectStoreContext context(aResp);
    redfish::dbus_utils::getProperty<std::string>(
        serviceName, path, "xyz.openbmc_project.Inventory.Item", "PrettyName",
        context,
        [aResp, index](const boost::system::error_code& ec,
                       const std::string& prettyName) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "Failed to get Item properties: " << ec;
            messages::internalError(aResp->res);
            return;
        }

        aResp->res.jsonValue["Assemblies"][index]["Name"] = prettyName;
        });
}

inline void populateAssemblyProperties(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::string& assembly, const boost::urls::url& assemblyId,
    const boost::system::error_code ec,
    const std::vector<std::pair<std::string, std::vector<std::string>>>& object)
{
    if (ec)
    {
        BMCWEB_LOG_DEBUG << "DBUS response error";
        messages::internalError(aResp->res);
        return;
    }

    // All Assemblys implement interface
    // "xyz.openbmc_project.Inventory.Item.Component"
    // If interface is not found, then it is not an Assembly connection and we
    // should abort.
    constexpr std::array<std::string_view, 1> assemblyInterface = {
        "xyz.openbmc_project.Inventory.Item.Component",
    };

    if (!redfish::dbus_utils::findInterfacesInServiceMap(object,
                                                         assemblyInterface))
    {
        return;
    }

    nlohmann::json& assembliesJson = aResp->res.jsonValue["Assemblies"];
    std::size_t assemblyIndex = assembliesJson.size();
    boost::urls::url dataID = assemblyId;
    std::string assemblyName = sdbusplus::message::object_path(assembly).filename();
    dataID.set_fragment(crow::utility::urlFromPieces(
                            "Assemblies", std::to_string(assembliesJson.size()))
                            .buffer());

    assembliesJson.push_back(
        {{"@odata.type", "#Assembly.v1_3_0.AssemblyData"},
         {"@odata.id", dataID.buffer()},
         {"MemberId", std::to_string(assemblyIndex)},
         {"Name", assemblyName}});
    aResp->res.jsonValue["Assemblies@odata.count"] = assembliesJson.size();

    for (const auto& [serviceName, interfaceList] : object)
    {
        for (const auto& interface : interfaceList)
        {
            if (interface == "xyz.openbmc_project.Inventory.Decorator.Asset")
            {
                addAssemblyAssetProperties(serviceName, assembly, aResp,
                                           assemblyIndex);
            }
            else if (interface == "xyz.openbmc_project.Inventory."
                                  "Decorator.LocationCode")
            {
                nlohmann::json::json_pointer locationPtr =
                    "/Assemblies"_json_pointer / assemblyIndex / "Location";
                location_util::getLocationCode(aResp, serviceName, assembly,
                                               locationPtr);
                location_util::getPartLocationContext(
                    aResp, locationPtr, assembly + "/contained_by");
            }
            else if (interface == "xyz.openbmc_project.Inventory.Item")
            {
                getAssemblyPrettyName(serviceName, assembly, aResp,
                                      assemblyIndex);
            }
            else
            {
                std::optional<std::string> type =
                    location_util::getLocationType(interface);
                if (type)
                {
                    assembliesJson[assemblyIndex]["Location"]["PartLocation"]
                                  ["LocationType"] = *type;
                }
            }
        }
    }
}

/**
 * @brief Get properties for an assembly
 * @param[in] aResp - Shared pointer for asynchronous calls.
 * @param[in] assemblyId - Assembly resource ID.
 * @param[in] assemblies - list of all the dbus paths associated as an assembly
 * with the parent.
 * @return None.
 */
inline void
    getAssemblyProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                          const boost::urls::url& assemblyId,
                          const boost::system::error_code& ec,
                          const std::vector<std::string>& assemblies)
{
    if (ec)
    {
        BMCWEB_LOG_DEBUG << " error_code = " << ec
                         << " error msg =  " << ec.message();
        // Don't throw error DBus object may not exist.
        return;
    }

    aResp->res.jsonValue["Assemblies"] = nlohmann::json::array();

    managedStore::ManagedObjectStoreContext requestContext(aResp);

    for (const std::string& assembly : assemblies)
    {
        std::string name = sdbusplus::message::object_path(assembly).filename();
        if (name.empty())
        {
            BMCWEB_LOG_DEBUG << "Empty name in assembly";
            messages::internalError(aResp->res);
            return;
        }

        constexpr std::array<std::string_view, 4> interfaces = {
            "xyz.openbmc_project.Inventory.Decorator.Asset",
            "xyz.openbmc_project.Inventory.Decorator.LocationCode",
            "xyz.openbmc_project.Inventory.Connector.Embedded",
            "xyz.openbmc_project.Inventory.Connector.Slot"};

        managedStore::GetManagedObjectStore()->getDbusObject(
            assembly, interfaces, requestContext,
            std::bind_front(populateAssemblyProperties, aResp, assembly,
                            assemblyId));
    }
}

/**
 * @brief Gets assemblies from assembly associations to an object.
 * @param[in] aResp - Shared pointer for asynchronous calls.
 * @param[in] assemblyId - Assembly resource ID.
 * @param[in] parentPath - DBus path of parent of assembly.
 *
 * @return None.
 */
inline void getAssembly(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                        const boost::urls::url& assemblyId,
                        const std::string& parentPath)
{
    aResp->res.jsonValue["@odata.type"] = "#Assembly.v1_3_0.Assembly";
    aResp->res.jsonValue["@odata.id"] = assemblyId.buffer();
    aResp->res.jsonValue["Name"] = "Assembly Collection";
    aResp->res.jsonValue["Id"] = "Assembly";

    aResp->res.jsonValue["Assemblies"] = nlohmann::json::array();
    aResp->res.jsonValue["Assemblies@odata.count"] = 0;

    managedStore::ManagedObjectStoreContext requestContext(aResp);

    constexpr std::array<std::string_view, 1> assemblyInterface = {
        "xyz.openbmc_project.Inventory.Item.Component",
    };

    const std::string inventoryPath = "/xyz/openbmc_project/inventory";

    managedStore::ManagedObjectStoreContext context(aResp);
    dbus_utils::getAssociatedSubTreePaths(
        parentPath + "/containing", inventoryPath, 0,
        assemblyInterface, context,
        std::bind_front(getAssemblyProperties, aResp,
        assemblyId));
}

} // namespace redfish
