#pragma once
#include "bmcweb_config.h"

#include "dbus_utility.hpp"
#include "managed_store_types.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/collection.hpp"
#include "utils/dbus_utils.hpp"
#include "utils/json_utils.hpp"
#include "utils/location_utils.hpp"

#include <boost/system/error_code.hpp>
#include <sdbusplus/asio/property.hpp>
#include <sdbusplus/unpack_properties.hpp>

#include <array>
#include <string_view>

#include "managed_store.hpp"

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

namespace redfish
{

/**
 * @brief Get Cable's asset properties.
 * @param[in,out]   resp        HTTP response.
 * @param[in]       service     Cable's service name.
 * @param[in]       path        Cable's path.
 */
inline void getCableAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          const std::string& service, const std::string& path)
{
    managedStore::ManagedObjectStoreContext context(asyncResp);
    managedStore::GetManagedObjectStore()->getAllProperties(
        service, path, "xyz.openbmc_project.Inventory.Decorator.Asset", context,
        [path, asyncResp](const boost::system::error_code& ec,
                          const dbus::utility::DBusPropertiesMap& assetList) {
        if (ec)
        {
            if (ec.value() != EBADR)
            {
                BMCWEB_LOG_ERROR << "DBUS response error for Properties"
                                 << ec.value();
                messages::internalError(asyncResp->res);
            }
            return;
        }
        const std::string* model = nullptr;
        const std::string* manufacturer = nullptr;
        const std::string* partNumber = nullptr;
        const std::string* serialNumber = nullptr;

        const bool success = sdbusplus::unpackPropertiesNoThrow(
            dbus_utils::UnpackErrorPrinter(), assetList, "Model", model,
            "Manufacturer", manufacturer, "PartNumber", partNumber,
            "SerialNumber", serialNumber);
        if (!success)
        {
            messages::internalError(asyncResp->res);
            return;
        }
        if (model != nullptr)
        {
            asyncResp->res.jsonValue["Model"] = *model;
        }
        if (manufacturer != nullptr)
        {
            asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
        }
        if (partNumber != nullptr)
        {
            asyncResp->res.jsonValue["PartNumber"] = *partNumber;
        }
        if (serialNumber != nullptr)
        {
            asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
        }
    });
}

/**
 * @brief Fill cable specific properties.
 * @param[in,out]   resp        HTTP response.
 * @param[in]       ec          Error code corresponding to Async method call.
 * @param[in]       properties  List of Cable Properties key/value pairs.
 */
inline void
    fillCableProperties(crow::Response& resp,
                        const boost::system::error_code& ec,
                        const dbus::utility::DBusPropertiesMap& properties)
{
    if (ec)
    {
        BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
        messages::internalError(resp);
        return;
    }

    const std::string* cableTypeDescription = nullptr;
    const double* length = nullptr;

    const bool success = sdbusplus::unpackPropertiesNoThrow(
        dbus_utils::UnpackErrorPrinter(), properties, "CableTypeDescription",
        cableTypeDescription, "Length", length);

    if (!success)
    {
        messages::internalError(resp);
        return;
    }

    if (cableTypeDescription != nullptr)
    {
        resp.jsonValue["CableType"] = *cableTypeDescription;
    }

    if (length != nullptr)
    {
        if (!std::isfinite(*length))
        {
            // Cable length is NaN by default, do not throw an error
            if (!std::isnan(*length))
            {
                messages::internalError(resp);
                return;
            }
        }
        else
        {
            resp.jsonValue["LengthMeters"] = *length;
        }
    }
}

/**
 * @brief Create Links for Chassis in Cable resource.
 * @param[in,out]   asyncResp            Async HTTP response.
 * @param[in]       associationPath      Cable association path.
 * @param[in]       chassisPropertyName  Chassis of PropertyName of Cable.
 */
inline void getCableChassisAssociation(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& associationPath, const std::string& chassisPropertyName)
{
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    dbus_utils::getProperty<std::vector<std::string>>(
        "xyz.openbmc_project.ObjectMapper", associationPath,
        "xyz.openbmc_project.Association", "endpoints", requestContext,
        [asyncResp, chassisPropertyName](const boost::system::error_code ec,
                                         const std::vector<std::string>& resp) {
        if (ec)
        {
            return; // no downstream_chassis = no failures
        }
        nlohmann::json& chassis =
            asyncResp->res.jsonValue["Links"][chassisPropertyName];
        chassis = nlohmann::json::array();
        const std::string chassisCollectionPath = "/redfish/v1/Chassis";
        for (const std::string& chassisPath : resp)
        {
            BMCWEB_LOG_INFO << chassisPath << "chassis path";
            sdbusplus::message::object_path path(chassisPath);
            std::string leaf = path.filename();
            if (leaf.empty())
            {
                continue;
            }
            std::string newPath = chassisCollectionPath;
            newPath += "/";
            newPath += leaf;
            chassis.emplace_back(nlohmann::json({{"@odata.id", std::move(newPath)}}));
        }
        });
}

/**
 * @brief Api to get Cable properties.
 * @param[in,out]   asyncResp       Async HTTP response.
 * @param[in]       cableObjectPath Object path of the Cable.
 * @param[in]       serviceMap      A map to hold Service and corresponding
 * interface list for the given cable id.
 */
inline void
    getCableProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                       const std::string& cableObjectPath,
                       const dbus::utility::MapperServiceMap& serviceMap)
{
    BMCWEB_LOG_DEBUG << "Get Properties for cable " << cableObjectPath;

    for (const auto& [service, interfaces] : serviceMap)
    {
        for (const auto& interface : interfaces)
        {
            if (interface == "xyz.openbmc_project.Inventory.Item.Cable")
            {
                managedStore::ManagedObjectStoreContext context(asyncResp);
                managedStore::GetManagedObjectStore()->getAllProperties(
                    service, cableObjectPath, interface, context,
                    [asyncResp](
                        const boost::system::error_code ec,
                        const dbus::utility::DBusPropertiesMap& properties) {
                    fillCableProperties(asyncResp->res, ec, properties);
                    });
            }
            else if (interface ==
                     "xyz.openbmc_project.Inventory.Decorator.LocationCode")
            {
                location_util::getLocationCode(asyncResp, service,
                                               cableObjectPath,
                                               "/Location"_json_pointer);
                location_util::getPartLocationContext(
                    asyncResp, "/Location"_json_pointer,
                    cableObjectPath + "/upstream_chassis");
            }
            else if (location_util::isConnector(interface))
            {
                std::optional<std::string> locationType =
                    location_util::getLocationType(interface);
                if (!locationType)
                {
                    BMCWEB_LOG_DEBUG << "getLocationType for Cable failed for "
                                     << interface;
                    continue;
                }

                asyncResp->res
                    .jsonValue["Location"]["PartLocation"]["LocationType"] =
                    *locationType;
            }
            else if (interface ==
                     "xyz.openbmc_project.Inventory.Decorator.Asset")
            {
                getCableAsset(asyncResp, service, cableObjectPath);
            }
            else if (interface == "xyz.openbmc_project.Inventory.Item")
            {
                managedStore::ManagedObjectStoreContext requestContext(
                    asyncResp);
                dbus_utils::getProperty<bool>(
                    service, cableObjectPath, interface, "Present",
                    requestContext,
                    [asyncResp, cableObjectPath](
                        const boost::system::error_code& ec, bool present) {
                    if (ec)
                    {
                        BMCWEB_LOG_DEBUG << "get presence failed for Cable "
                                         << cableObjectPath << "with error "
                                         << ec;
                        return;
                    }

                    if (!present)
                    {
                        asyncResp->res.jsonValue["Status"]["State"] = "Absent";
                    }
                });
            }
        }
    }
}

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

    BMCWEB_LOG_DEBUG << "Cable Id: " << cableId;
    constexpr std::array<std::string_view, 1> interfaces = {
        "xyz.openbmc_project.Inventory.Item.Cable"};

    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getSubTree(
        "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
        [asyncResp,
         cableId](const boost::system::error_code& ec,
                  const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec.value() == EBADR)
        {
            messages::resourceNotFound(asyncResp->res, "Cable", cableId);
            return;
        }

        if (ec)
        {
            BMCWEB_LOG_ERROR << "DBUS response error " << ec;
            messages::internalError(asyncResp->res);
            return;
        }

        for (const auto& [objectPath, serviceMap] : subtree)
        {
            sdbusplus::message::object_path path(objectPath);
            if (path.filename() != cableId)
            {
                continue;
            }

            if constexpr (enablePlatform9)
            {
                // Hardcode relations
                if (cableId == "cat5_cable")
                {
                    nlohmann::json::array_t upArray;
                    nlohmann::json::object_t upObj;
                    upObj["@odata.id"] =
                        "/redfish/v1/Chassis/" + std::string(platform9Chassis0);
                    upArray.emplace_back(std::move(upObj));
                    asyncResp->res.jsonValue["Links"]["UpstreamChassis"] =
                        std::move(upArray);
                }
                if (cableId == platform9Cable0)
                {
                    nlohmann::json::array_t downArray;
                    nlohmann::json::array_t upArray;
                    nlohmann::json::object_t downObj;
                    nlohmann::json::object_t upObj;
                    downObj["@odata.id"] =
                        "/redfish/v1/Cables/" + std::string(platform9Cable1);
                    downArray.emplace_back(std::move(downObj));
                    asyncResp->res.jsonValue["Links"]["DownstreamResources"] =
                        std::move(downArray);

                    upObj["@odata.id"] =
                        "/redfish/v1/Chassis/" + std::string(platform9Chassis0);
                    upArray.emplace_back(std::move(upObj));
                    asyncResp->res.jsonValue["Links"]["UpstreamChassis"] =
                        std::move(upArray);
                }
                if (cableId == platform9Cable1)
                {
                    nlohmann::json::array_t downArray;
                    nlohmann::json::array_t upArray;
                    nlohmann::json::object_t downObj;
                    nlohmann::json::object_t upObj;
                    downObj["@odata.id"] =
                        "/redfish/v1/Cables/" + std::string(platform9Cable2);
                    downArray.emplace_back(std::move(downObj));
                    asyncResp->res.jsonValue["Links"]["DownstreamResources"] =
                        std::move(downArray);

                    upObj["@odata.id"] =
                        "/redfish/v1/Cables/" + std::string(platform9Cable0);
                    upArray.emplace_back(std::move(upObj));
                    asyncResp->res.jsonValue["Links"]["UpstreamResources"] =
                        std::move(upArray);
                }
                if (cableId == platform9Cable2)
                {
                    nlohmann::json::array_t downArray;
                    nlohmann::json::array_t upArray;
                    nlohmann::json::object_t downObj;
                    nlohmann::json::object_t upObj;
                    downObj["@odata.id"] =
                        "/redfish/v1/Chassis/" + std::string(platform9Chassis3);
                    downArray.emplace_back(std::move(downObj));
                    asyncResp->res.jsonValue["Links"]["DownstreamResources"] =
                        std::move(downArray);

                    upObj["@odata.id"] =
                        "/redfish/v1/Cables/" + std::string(platform9Cable1);
                    upArray.emplace_back(std::move(upObj));
                    asyncResp->res.jsonValue["Links"]["UpstreamResources"] =
                        std::move(upArray);
                }
                if (cableId == platform9Cable3)
                {
                    nlohmann::json::array_t downArray;
                    nlohmann::json::array_t upArray;
                    nlohmann::json::object_t downObj;
                    nlohmann::json::object_t upObj;
                    downObj["@odata.id"] =
                        "/redfish/v1/Cables/" + std::string(platform9Cable4);
                    downArray.emplace_back(std::move(downObj));
                    asyncResp->res.jsonValue["Links"]["DownstreamResources"] =
                        std::move(downArray);

                    upObj["@odata.id"] =
                        "/redfish/v1/Chassis/" + std::string(platform9Chassis3);
                    upArray.emplace_back(std::move(upObj));
                    asyncResp->res.jsonValue["Links"]["UpstreamResources"] =
                        std::move(upArray);
                }
                if (cableId == platform9Cable4)
                {
                    nlohmann::json::array_t downArray;
                    nlohmann::json::array_t upArray;
                    nlohmann::json::object_t downObj;
                    nlohmann::json::object_t upObj;
                    downObj["@odata.id"] =
                        "/redfish/v1/Chassis/" + std::string(platform9Chassis2);
                    downArray.emplace_back(std::move(downObj));
                    asyncResp->res.jsonValue["Links"]["DownstreamResources"] =
                        std::move(downArray);

                    upObj["@odata.id"] =
                        "/redfish/v1/Cables/" + std::string(platform9Cable3);
                    upArray.emplace_back(std::move(upObj));
                    asyncResp->res.jsonValue["Links"]["UpstreamResources"] =
                        std::move(upArray);
                }
            }

            asyncResp->res.jsonValue["@odata.type"] = "#Cable.v1_0_0.Cable";
            asyncResp->res.jsonValue["@odata.id"] =
                crow::utility::urlFromPieces("redfish", "v1", "Cables",
                                             cableId);
            asyncResp->res.jsonValue["Id"] = cableId;
            asyncResp->res.jsonValue["Name"] = "Cable";
            asyncResp->res.jsonValue["Status"]["State"] = "Enabled";

            getCableProperties(asyncResp, objectPath, serviceMap);
            getCableChassisAssociation(asyncResp,
                                       objectPath + "/downstream_chassis",
                                       "DownstreamChassis");
            getCableChassisAssociation(
                asyncResp, objectPath + "/upstream_chassis", "UpstreamChassis");
            return;
        }
        messages::resourceNotFound(asyncResp->res, "Cable", cableId);
    });
}

/**
 * The Cable schema
 */
inline void requestRoutesCable(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Cables/<str>/")
        .privileges(redfish::privileges::getCable)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleCableGet, std::ref(app)));
}

inline void handleCableCollectionGet(
    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"] =
        "#CableCollection.CableCollection";
    asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Cables";
    asyncResp->res.jsonValue["Name"] = "Cable Collection";
    asyncResp->res.jsonValue["Description"] = "Collection of Cable Entries";
    constexpr std::array<std::string_view, 1> interfaces{
        "xyz.openbmc_project.Inventory.Item.Cable"};
    collection_util::getCollectionMembers(
        asyncResp, boost::urls::url("/redfish/v1/Cables"), interfaces);
}

/**
 * Collection of Cable resource instances
 */
inline void requestRoutesCableCollection(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Cables/")
        .privileges(redfish::privileges::getCableCollection)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleCableCollectionGet, std::ref(app)));
}

} // namespace redfish
