#pragma once

#include "app.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "managed_store.hpp"
#include "query.hpp"
#include "utils/chassis_utils.hpp"
#include "utils/collection.hpp"
#include "utils/dbus_utils.hpp"
#include "utils/hex_utils.hpp"
#include "utils/json_utils.hpp"

#include <boost/system/error_code.hpp>
#include <nlohmann/json.hpp>

#include <array>
#include <regex>
#include <string_view>
#include <vector>

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

namespace crow
{
namespace google_api
{

inline void
    handleGoogleV1Get(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"] =
        "#GoogleServiceRoot.v1_0_0.GoogleServiceRoot";
    asyncResp->res.jsonValue["@odata.id"] = "/google/v1";
    asyncResp->res.jsonValue["Id"] = "Google Rest RootService";
    asyncResp->res.jsonValue["Name"] = "Google Service Root";
    asyncResp->res.jsonValue["Version"] = "1.0.0";
    asyncResp->res.jsonValue["RootOfTrustCollection"]["@odata.id"] =
        "/google/v1/RootOfTrustCollection";
    asyncResp->res.jsonValue["NVMe"]["@odata.id"] = "/google/v1/NVMe";
}

inline void handleRootOfTrustCollectionGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    asyncResp->res.jsonValue["@odata.id"] = "/google/v1/RootOfTrustCollection";
    asyncResp->res.jsonValue["@odata.type"] =
        "#RootOfTrustCollection.RootOfTrustCollection";
    const std::array<std::string_view, 1> interfaces{
        "xyz.openbmc_project.Control.Hoth"};
    redfish::collection_util::getCollectionMembers(
        asyncResp, boost::urls::url("/google/v1/RootOfTrustCollection"),
        interfaces, "/xyz/openbmc_project");
}

// Helper struct to identify a resolved D-Bus object interface
struct ResolvedEntity
{
    std::string id;
    std::string service;
    std::string object;
    std::string interface;
};

using ResolvedEntityHandler = std::function<void(
    const std::string&, const std::shared_ptr<bmcweb::AsyncResp>&,
    const ResolvedEntity&)>;

inline void hothGetSubtreeCallback(
    const std::string& command,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& rotId, const ResolvedEntityHandler& entityHandler,
    const boost::system::error_code& ec,
    const dbus::utility::MapperGetSubTreeResponse& subtree)
{
    if (ec)
    {
        redfish::messages::internalError(asyncResp->res);
        return;
    }
    for (const auto& [path, services] : subtree)
    {
        sdbusplus::message::object_path objPath(path);
        if (objPath.filename() != rotId || services.empty())
        {
            continue;
        }

        ResolvedEntity resolvedEntity = {
            .id = rotId,
            .service = services[0].first,
            .object = path,
            .interface = "xyz.openbmc_project.Control.Hoth"};
        entityHandler(command, asyncResp, resolvedEntity);
        return;
    }

    // Couldn't find an object with that name.  return an error
    redfish::messages::resourceNotFound(asyncResp->res, "RootOfTrust", rotId);
}

inline void resolveRoT(const std::string& command,
                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                       const std::string& rotId,
                       ResolvedEntityHandler&& entityHandler)
{
    constexpr std::array<std::string_view, 1> hothIfaces = {
        "xyz.openbmc_project.Control.Hoth"};
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getSubTree(
        "/xyz/openbmc_project", 0, hothIfaces, requestContext,
        [command, asyncResp, rotId,
         entityHandler{std::forward<ResolvedEntityHandler>(entityHandler)}](
            const boost::system::error_code& ec,
            const dbus::utility::MapperGetSubTreeResponse& subtree) {
        hothGetSubtreeCallback(command, asyncResp, rotId, entityHandler, ec,
                               subtree);
    });
}

inline void populateRootOfTrustState(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const dbus::utility::DBusPropertiesMap& properties)
{
    const uint64_t* authRecordCapabilities = nullptr;
    const uint32_t* bootloaderUpdateFailureCode = nullptr;
    const uint32_t* firmwareUpdateFailedMinor = nullptr;
    const uint32_t* firmwareUpdateFailureCode = nullptr;
    const uint32_t* payloadConfirmFailureCode = nullptr;
    const uint32_t* payloadUpdateFailureCode = nullptr;
    const uint32_t* resetFlags = nullptr;
    const uint32_t* roInfoStrikes = nullptr;
    const uint32_t* rwInfoStrikes = nullptr;
    const uint64_t* upTime = nullptr;
    const bool* hasPersistentPanicInfo = nullptr;
    const bool* hasValidAuthRecord = nullptr;

    const bool success = sdbusplus::unpackPropertiesNoThrow(
        redfish::dbus_utils::UnpackErrorPrinter(), properties,
        "BootloaderUpdateFailureCode", bootloaderUpdateFailureCode,
        "FirmwareUpdateFailedMinor", firmwareUpdateFailedMinor,
        "FirmwareUpdateFailureCode", firmwareUpdateFailureCode,
        "PayloadConfirmFailureCode", payloadConfirmFailureCode,
        "PayloadUpdateFailureCode", payloadUpdateFailureCode, "ResetFlags",
        resetFlags, "RoInfoStrikes", roInfoStrikes, "RwInfoStrikes",
        rwInfoStrikes, "UpTime", upTime, "HasPersistentPanicInfo",
        hasPersistentPanicInfo, "HasValidAuthRecord", hasValidAuthRecord,
        "AuthRecordCapabilities", authRecordCapabilities);

    if (!success)
    {
        BMCWEB_LOG_ERROR << "Failed to populate RootOfTrustState";
        redfish::messages::internalError(asyncResp->res);
        return;
    }

    if (bootloaderUpdateFailureCode != nullptr)
    {
        asyncResp->res
            .jsonValue["Status"]["Oem"]["BootloaderUpdateFailureCode"] =
            *bootloaderUpdateFailureCode;
    }
    if (firmwareUpdateFailedMinor != nullptr)
    {
        asyncResp->res.jsonValue["Status"]["Oem"]["FirmwareUpdateFailedMinor"] =
            *firmwareUpdateFailedMinor;
    }
    if (firmwareUpdateFailureCode != nullptr)
    {
        asyncResp->res.jsonValue["Status"]["Oem"]["FirmwareUpdateFailureCode"] =
            *firmwareUpdateFailureCode;
    }
    if (resetFlags != nullptr)
    {
        asyncResp->res.jsonValue["Status"]["Oem"]["ResetFlags"] = *resetFlags;
    }
    if (roInfoStrikes != nullptr)
    {
        asyncResp->res.jsonValue["Status"]["Oem"]["RoInfoStrikes"] =
            *roInfoStrikes;
    }
    if (rwInfoStrikes != nullptr)
    {
        asyncResp->res.jsonValue["Status"]["Oem"]["RwInfoStrikes"] =
            *rwInfoStrikes;
    }
    if (upTime != nullptr)
    {
        asyncResp->res.jsonValue["Status"]["Oem"]["UpTime"] = *upTime;
    }
    if (hasPersistentPanicInfo != nullptr)
    {
        asyncResp->res.jsonValue["Status"]["Oem"]["HasPersistentPanicInfo"] =
            *hasPersistentPanicInfo;
    }

    if (payloadConfirmFailureCode != nullptr)
    {
        asyncResp->res
            .jsonValue["Status"]["Oem"]["Payload"]["ConfirmFailureCode"] =
            *payloadConfirmFailureCode;
    }
    if (payloadUpdateFailureCode != nullptr)
    {
        asyncResp->res
            .jsonValue["Status"]["Oem"]["Payload"]["UpdateFailureCode"] =
            *payloadUpdateFailureCode;
    }
    if (hasValidAuthRecord != nullptr)
    {
        asyncResp->res.jsonValue["Status"]["Oem"]["Authorization"]["Valid"] =
            *hasValidAuthRecord;
    }
    if (authRecordCapabilities != nullptr)
    {
        asyncResp->res.jsonValue["Status"]["Oem"]["Authorization"]["Capabilities"] =
            *authRecordCapabilities;
    }
}

inline void populateRootOfTrustEntity(
    const std::string& /*unused*/,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const ResolvedEntity& resolvedEntity)
{
    asyncResp->res.jsonValue["@odata.type"] = "#RootOfTrust.v1_0_0.RootOfTrust";
    asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
        "google", "v1", "RootOfTrustCollection", resolvedEntity.id);

    asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
    asyncResp->res.jsonValue["Id"] = resolvedEntity.id;
    // Need to fix this later to a stabler property.
    asyncResp->res.jsonValue["Name"] = resolvedEntity.id;
    asyncResp->res.jsonValue["Description"] = "Google Root Of Trust";
    asyncResp->res.jsonValue["Actions"]["#RootOfTrust.SendCommand"]["target"] =
        "/google/v1/RootOfTrustCollection/" + resolvedEntity.id +
        "/Actions/RootOfTrust.SendCommand";

    asyncResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
        resolvedEntity.id;
    asyncResp->res.jsonValue["Location"]["PartLocation"]["LocationType"] =
        "Embedded";

    // Only link to RW firmware inventory.
    //
    // For USB-Hoth, FirmwareInventory URI is "hoth_${hothId}_rw".
    // For non-USB Hoth, FirmwareInventory URI is "hoth_rw".
    std::string hothFirmware = resolvedEntity.id == "Hoth"
                                   ? "hoth_rw"
                                   : "hoth_" + resolvedEntity.id + "_rw";
    asyncResp->res.jsonValue["Links"]["ActiveSoftwareImage"]["@odata.id"] =
        "/redfish/v1/UpdateService/FirmwareInventory/" + hothFirmware;

    // Temporary hack to get the Hoth firmware family as "Model", by stripping
    // the USB suffix from hothId.
    //
    // Non-USB Hoth has resolvedEntity.id="Hoth" as model name.
    //
    // Once we have SoftwareInventory 1.9.0 supported everywhere, the firmware
    // family should reside there and the model here should be the chip's part
    // number.
    static std::regex hothIdSuffixRe("_[0-9_]+$");
    asyncResp->res.jsonValue["Model"] =
        std::regex_replace(resolvedEntity.id, hothIdSuffixRe, "");

    // Get Hoth properties from Dbus.
    managedStore::ManagedObjectStoreContext context(asyncResp);
    managedStore::GetManagedObjectStore()->getAllProperties(
        resolvedEntity.service, resolvedEntity.object,
        "xyz.openbmc_project.Control.Hoth.State", context,
        [asyncResp](const boost::system::error_code ec2,
                    const dbus::utility::DBusPropertiesMap& properties) {
        if (ec2)
        {
            BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
            return;
        }
        populateRootOfTrustState(asyncResp, properties);
    });

    // Get Chassis Link for Devpath from DBus
    managedStore::ManagedObjectStoreContext context2(asyncResp);
    managedStore::GetManagedObjectStore()->getAssociatedSubTreePaths(
        sdbusplus::message::object_path(resolvedEntity.object) / "contained_by",
        sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
        redfish::chassis_utils::chassisInterfaces, context2,
        [asyncResp](
            const boost::system::error_code& ec,
            const dbus::utility::MapperGetSubTreePathsResponse& chassisPaths) {
        if (ec)
        {
            BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
            return;
        }

        if (!chassisPaths.empty())
        {
            asyncResp->res.jsonValue["RelatedItem"] = nlohmann::json::array();
        }
        for (const auto& str : chassisPaths)
        {
            std::filesystem::path chassisPath(str);
            nlohmann::json::object_t relatedChassis;
            relatedChassis["@odata.id"] = crow::utility::urlFromPieces(
                "redfish", "v1", "Chassis", chassisPath.filename().c_str());
            asyncResp->res.jsonValue["RelatedItem"].emplace_back(
                relatedChassis);

            // Get PartLocationContext from Chassis LocationCode interface
            managedStore::ManagedObjectStoreContext context(asyncResp);
            redfish::dbus_utils::getProperty<std::string>(
                "xyz.openbmc_project.EntityManager", chassisPath.c_str(),
                "xyz.openbmc_project.Inventory.Decorator.LocationCode",
                "LocationCode", context,
                [asyncResp](const boost::system::error_code ec,
                            const std::string& locationCode) {
                if (ec)
                {
                    BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
                    return;
                }
                asyncResp->res.jsonValue["Location"]["PartLocationContext"] =
                    locationCode;
            });
        }
    }

    );
}

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

inline void
    invocationCallback(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                       const boost::system::error_code& ec,
                       const std::vector<uint8_t>& responseBytes)
{
    if (ec)
    {
        BMCWEB_LOG_ERROR << "RootOfTrust.Actions.SendCommand failed: "
                         << ec.message();
        redfish::messages::internalError(asyncResp->res);
        return;
    }

    asyncResp->res.jsonValue["CommandResponse"] =
        bytesToHexString(responseBytes);
}

inline void
    invokeRoTCommand(const std::string& command,
                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                     const ResolvedEntity& resolvedEntity)
{
    std::vector<uint8_t> bytes = hexStringToBytes(command);
    if (bytes.empty())
    {
        BMCWEB_LOG_DEBUG << "Invalid command: " << command;
        redfish::messages::actionParameterValueTypeError(command, "Command",
                                                         "SendCommand");
        return;
    }

    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        asyncResp->strand_,
        [asyncResp{asyncResp}](const boost::system::error_code& ec,
                               const std::vector<uint8_t>& responseBytes) {
        invocationCallback(asyncResp, ec, responseBytes);
    },
        resolvedEntity.service, resolvedEntity.object, resolvedEntity.interface,
        "SendHostCommand", bytes);
}

inline void handleRoTSendCommandPost(
    App& app, const crow::Request& request,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& rotId)
{
    if (!redfish::setUpRedfishRoute(app, request, asyncResp))
    {
        return;
    }
    std::string command;
    if (!redfish::json_util::readJsonAction(request, asyncResp->res, "Command",
                                            command))
    {
        BMCWEB_LOG_DEBUG << "Missing property Command.";
        redfish::messages::actionParameterMissing(asyncResp->res, "SendCommand",
                                                  "Command");
        return;
    }

    resolveRoT(command, asyncResp, rotId, invokeRoTCommand);
}

inline void requestRoutes(App& app)
{
    BMCWEB_ROUTE(app, "/google/v1/")
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleGoogleV1Get, std::ref(app)));

    BMCWEB_ROUTE(app, "/google/v1/RootOfTrustCollection/")
        .privileges({{"ConfigureManager"}})
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleRootOfTrustCollectionGet, std::ref(app)));

    BMCWEB_ROUTE(app, "/google/v1/RootOfTrustCollection/<str>/")
        .privileges({{"ConfigureManager"}})
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleRootOfTrustGet, std::ref(app)));

    BMCWEB_ROUTE(
        app,
        "/google/v1/RootOfTrustCollection/<str>/Actions/RootOfTrust.SendCommand/")
        .privileges({{"ConfigureManager"}})
        .methods(boost::beast::http::verb::post)(
            std::bind_front(handleRoTSendCommandPost, std::ref(app)));
}

} // namespace google_api
} // namespace crow
