#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 "chassis_utils.hpp"
#include "collection.hpp"
#include "dbus_utils.hpp"
#include "hex_utils.hpp"
#include "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 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 uint64_t* authRecordCapabilities = nullptr;
    const bool* secureBootEnforced = nullptr;

    const uint32_t* keyRotationVersion = nullptr;
    const uint16_t* keyRotationImageFamily = nullptr;
    const uint16_t* keyRotationImageFamilyVariant = nullptr;
    const uint32_t* keyRotationValidationMethod = nullptr;
    const uint32_t* keyRotationValidationKeyData = nullptr;
    const uint32_t* keyRotationValidationHashData = 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, "SecureBootEnforced",
        secureBootEnforced, "KeyRotationVersion", keyRotationVersion,
        "KeyRotationImageFamily", keyRotationImageFamily,
        "KeyRotationImageFamilyVariant", keyRotationImageFamilyVariant,
        "KeyRotationValidationMethod", keyRotationValidationMethod,
        "KeyRotationValidationKeyData", keyRotationValidationKeyData,
        "KeyRotationValidationHashData", keyRotationValidationHashData);

    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;
    }
    if (secureBootEnforced != nullptr)
    {
        asyncResp->res.jsonValue["Status"]["Oem"]["SecureBootEnforced"] =
            *secureBootEnforced;
    }
    if (keyRotationVersion != nullptr)
    {
        asyncResp->res.jsonValue["Status"]["Oem"]["KeyRotation"]["Version"] =
            *keyRotationVersion;
    }
    if (keyRotationImageFamily != nullptr)
    {
        asyncResp->res
            .jsonValue["Status"]["Oem"]["KeyRotation"]["ImageFamily"] =
            *keyRotationImageFamily;
    }
    if (keyRotationImageFamilyVariant != nullptr)
    {
        asyncResp->res
            .jsonValue["Status"]["Oem"]["KeyRotation"]["ImageFamilyVariant"] =
            *keyRotationImageFamilyVariant;
    }
    if (keyRotationValidationMethod != nullptr)
    {
        asyncResp->res
            .jsonValue["Status"]["Oem"]["KeyRotation"]["ValidationMethod"] =
            *keyRotationValidationMethod;
    }
    if (keyRotationValidationKeyData != nullptr)
    {
        asyncResp->res
            .jsonValue["Status"]["Oem"]["KeyRotation"]["ValidationKeyData"] =
            *keyRotationValidationKeyData;
    }
    if (keyRotationValidationHashData != nullptr)
    {
        asyncResp->res
            .jsonValue["Status"]["Oem"]["KeyRotation"]["ValidationHashData"] =
            *keyRotationValidationHashData;
    }
}

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
