#pragma once

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

namespace redfish
{
inline void addAssemblyAssetProperties(
    const std::string& serviceName, const std::string& path,
    const std::shared_ptr<bmcweb::AsyncResp>& aResp, std::size_t index)
{
    sdbusplus::asio::getAllProperties(
        *crow::connections::systemBus, serviceName, path,
        "xyz.openbmc_project.Inventory.Decorator.Asset",
        [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;
            }
        });
}

/**
 * @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 std::vector<std::string>& assemblies)
{
    aResp->res.jsonValue["Assemblies@odata.count"] = assemblies.size();
    aResp->res.jsonValue["Assemblies"] = nlohmann::json::array();

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

        crow::connections::systemBus->async_method_call(
            [aResp, assembly, assemblyId, name](
                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;
                }

                nlohmann::json& assembliesJson =
                    aResp->res.jsonValue["Assemblies"];
                std::size_t assemblyIndex = assembliesJson.size();
                boost::urls::url dataID = assemblyId;
                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", name}});

                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 + "/chassis");
                        }
                        else
                        {
                            std::optional<std::string> type =
                                location_util::getLocationType(interface);
                            if (type)
                            {
                                assembliesJson[assemblyIndex]["Location"]
                                              ["PartLocation"]["LocationType"] = *type;
                            }
                        }
                    }
                }
            },
            "xyz.openbmc_project.ObjectMapper",
            "/xyz/openbmc_project/object_mapper",
            "xyz.openbmc_project.ObjectMapper", "GetObject", assembly,
            std::to_array<std::string>(
                {"xyz.openbmc_project.Inventory.Decorator.Asset",
                 "xyz.openbmc_project.Inventory.Decorator.LocationCode",
                 "xyz.openbmc_project.Inventory.Connector.Embedded",
                 "xyz.openbmc_project.Inventory.Connector.Slot"}));
    }
}

/**
 * @brief Api to get assembly endpoints from mapper.
 * @param[in] aResp - Shared pointer for asynchronous calls.
 * @param[in] assemblyId - Assembly resource ID.
 * @param[in] assemblyPath - DBus path of assembly association.
 *
 * @return None.
 */
inline void
    getAssemblyEndpoints(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                         const boost::urls::url& assemblyId,
                         const std::string& assemblyPath)
{
    // if there is assembly association, look
    // for endpoints
    sdbusplus::asio::getProperty<std::vector<std::string>>(
        *crow::connections::systemBus, "xyz.openbmc_project.ObjectMapper",
        assemblyPath, "xyz.openbmc_project.Association", "endpoints",
        [aResp, assemblyId](const boost::system::error_code ec,
                            const std::vector<std::string>& endpoints) {
            if (ec)
            {
                BMCWEB_LOG_DEBUG << "DBUS response error";
                messages::internalError(aResp->res);
                return;
            }

            std::vector<std::string> sortedAssemblyList = endpoints;
            std::sort(sortedAssemblyList.begin(), sortedAssemblyList.end(),
                      AlphanumLess<std::string>());

            getAssemblyProperties(aResp, assemblyId, sortedAssemblyList);
        });
}

/**
 * @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;

    // check if this chassis hosts any association
    crow::connections::systemBus->async_method_call(
        [aResp, assemblyId](const boost::system::error_code ec,
                            const std::vector<std::string>& paths) {
            if (ec)
            {
                BMCWEB_LOG_DEBUG << "DBUS response error";
                messages::internalError(aResp->res);
                return;
            }
            for (const std::string& path : paths)
            {
                if (sdbusplus::message::object_path(path).filename() ==
                    "assembly")
                {
                    getAssemblyEndpoints(aResp, assemblyId, path);
                    return;
                }
            }
        },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", parentPath, 0,
        std::array<const char*, 1>{"xyz.openbmc_project.Association"});
}

} // namespace redfish
