#ifndef THIRD_PARTY_GBMCWEB_INCLUDE_GOOGLE_GOOGLE_SERVICE_NVME_H_
#define THIRD_PARTY_GBMCWEB_INCLUDE_GOOGLE_GOOGLE_SERVICE_NVME_H_

#include <systemd/sd-bus.h>

#include <array>
#include <cstddef>
#include <cstdint>
#include <filesystem>  // NOLINT
#include <functional>
#include <memory>
#include <optional>
#include <span>  // NOLINT
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "bmcweb_config.h"
#include "app.hpp"
#include "http_request.hpp"
#include "logging.hpp"
#include "utility.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "query.hpp"
#include "dbus_utils.hpp"
#include "json_utils.hpp"
#include "storage_utils.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/message.hpp"
#include "sdbusplus/message/native_types.hpp"

namespace crow {
namespace google_api {

using NVMeControllerHandlerCb = std::function<void(
    const boost::system::error_code ec, const std::string& storagePath,
    const std::vector<std::string>& controllerList)>;

using boost::asio::posix::stream_descriptor;

static std::shared_ptr<boost::asio::io_context> fdIOContext;  // NOLINT

static void fetchFile(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::shared_ptr<stream_descriptor>& fileConn,
    const std::shared_ptr<std::array<char, 1024>>& readBuffer =
        std::make_shared<std::array<char, 1024>>(),
    const std::shared_ptr<std::string>& output =
        std::make_shared<std::string>()) {
  if (!fileConn) {
    BMCWEB_LOG_ERROR << "Fetch File Context is not setup properly";
    redfish::messages::internalError(asyncResp->res);
    return;
  }

  fileConn->async_read_some(
      boost::asio::buffer(*readBuffer),
      [asyncResp, fileConn, readBuffer, output](
          const boost::system::error_code& ec,
          const std::size_t& bytesTransferred) {
        if (ec == boost::asio::error::eof) {
          asyncResp->res.stringResponse->clear();
          asyncResp->res.addHeader(boost::beast::http::field::content_type,
                                   "application/octet-stream");
          asyncResp->res.body() = std::move(*output);
          fileConn->close();
          return;
        }
        if (ec) {
          BMCWEB_LOG_ERROR << "Failed to async_read_some" << ec.message();
          redfish::messages::internalError(asyncResp->res);
          return;
        }
        *output += std::string(readBuffer->begin(),
                               readBuffer->begin() + bytesTransferred);
        fetchFile(asyncResp, fileConn, readBuffer, output);
      });
}

inline void populateCustomNVMeControllerLink(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& storageId,
    const sdbusplus::message::object_path& controllerPath) {
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Inventory.Item.StorageController"};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getAssociatedSubTreePaths(
      controllerPath / customNVMeAssociation,
      sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
      interfaces, requestContext,
      [asyncResp, systemName, storageId, controllerPath](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreePathsResponse& customNVMeList) {
        if (ec && ec.value() != EBADR) {
          BMCWEB_LOG_ERROR << "Failed to get " << customNVMe
                           << "Controllers for controller "
                           << controllerPath.str;
          redfish::messages::internalError(asyncResp->res);
          return;
        }

        if (customNVMeList.size() > 1) {
          BMCWEB_LOG_ERROR << "More than 1 " << customNVMe
                           << "Controller for controller "
                           << controllerPath.str;
          redfish::messages::internalError(asyncResp->res);
          return;
        }

        if (customNVMeList.empty()) {
          return;
        }

        const sdbusplus::message::object_path path{customNVMeList[0]};

        redfish::storage_utils::findStorageForController(
            asyncResp, storageId, path,
            [asyncResp, systemName,
             path](const std::optional<sdbusplus::message::object_path>&
                       canonStoragePath) {
              if (canonStoragePath) {
                const std::string canonStorageId = canonStoragePath->filename();
                const std::string id = path.filename();
                asyncResp->res.jsonValue[std::string(customNVMe) + "Controller"]
                                        ["@odata.id"] =
                    crow::utility::urlFromPieces(
                        "redfish", "v1", "Systems", systemName, "Storage",
                        canonStorageId, "Controllers", id);
              }
            });
      });
}

inline void checkPrimary(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const sdbusplus::message::object_path& controllerPath) {
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Inventory.Item.StorageController"};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);

  managedStore::GetManagedObjectStore()->getAssociatedSubTreePaths(
      controllerPath / "primary",
      sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
      interfaces, requestContext,
      [asyncResp, controllerPath](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreePathsResponse& controllerList) {
        if (ec) {
          BMCWEB_LOG_ERROR << "getAssociatedSubTreePaths for path "
                           << controllerPath.str << " failed with code " << ec;
          redfish::messages::internalError(asyncResp->res);
          return;
        }

        asyncResp->res.jsonValue["ControllerType"] =
            controllerList.empty() ? "Primary" : "Secondary";
      });
}

inline void populateNVMeController(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& nvmeId,
    const std::string& controllerId, const std::string& controllerPath) {
  constexpr std::array<std::string_view, 1> interfaces{
      "xyz.openbmc_project.NVMe.NVMeAdmin"};
  managedStore::ManagedObjectStoreContext context(asyncResp);
  managedStore::GetManagedObjectStore()->getDbusObject(
      controllerPath, interfaces, context,
      [asyncResp, systemName, nvmeId, controllerId, controllerPath](
          const boost::system::error_code ec,
          const dbus::utility::MapperGetObject& objects) {
        if (ec) {
          BMCWEB_LOG_ERROR << "GetObject for path " << controllerPath
                           << " failed with code " << ec;
          redfish::messages::internalError(asyncResp->res);
          return;
        }

        if (objects.size() != 1) {
          redfish::messages::internalError(asyncResp->res);
          BMCWEB_LOG_ERROR << "Service supporting " << controllerPath
                           << " is not equal to 1";
          return;
        }

        asyncResp->res.jsonValue["@odata.type"] =
            "#NVMeController.v1_0_0.NVMeController";
        asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
            "google", "v1", "NVMe", nvmeId, "Controllers", controllerId);
        asyncResp->res.jsonValue["Name"] = "Google NVMe Controller";

        // NVMe actions
        asyncResp->res
            .jsonValue["Actions"]["#NVMeController.AdminNonDataCmd"]["target"] =
            crow::utility::urlFromPieces("google", "v1", "NVMe", nvmeId,
                                         "Controllers", controllerId, "Actions",
                                         "NVMeController.AdminNonDataCmd");
        asyncResp->res
            .jsonValue["Actions"]["#NVMeController.LockdownInband"]["target"] =
            crow::utility::urlFromPieces("google", "v1", "NVMe", nvmeId,
                                         "Controllers", controllerId, "Actions",
                                         "NVMeController.LockdownInband");
        asyncResp->res
            .jsonValue["Actions"]["#NVMeController.GetLogPage"]["target"] =
            crow::utility::urlFromPieces("google", "v1", "NVMe", nvmeId,
                                         "Controllers", controllerId, "Actions",
                                         "NVMeController.GetLogPage");
        asyncResp->res
            .jsonValue["Actions"]["#NVMeController.Identify"]["target"] =
            crow::utility::urlFromPieces("google", "v1", "NVMe", nvmeId,
                                         "Controllers", controllerId, "Actions",
                                         "NVMeController.Identify");
        asyncResp->res.jsonValue["Links"]["NVMe"]["@odata.id"] =
            crow::utility::urlFromPieces("google", "v1", "NVMe", nvmeId);
        asyncResp->res.jsonValue["StorageController"]["@odata.id"] =
            crow::utility::urlFromPieces("redfish", "v1", "Systems", systemName,
                                         "Storage", nvmeId, "Controllers",
                                         controllerId);
        if (enableCustomNVMe) {
          asyncResp->res.jsonValue["Actions"]["#NVMeController." +
                                              std::string(customNVMe) +
                                              "Identify"]["target"] =
              crow::utility::urlFromPieces(
                  "google", "v1", "NVMe", nvmeId, "Controllers", controllerId,
                  "Actions",
                  "NVMeController." + std::string(customNVMe) + "Identify");
          populateCustomNVMeControllerLink(asyncResp, systemName, nvmeId,
                                           controllerPath);
          checkPrimary(asyncResp, controllerPath);
        }
      });
}

inline void setupNVMeController(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& nvmeId,
    const std::string& controllerId,
    const std::vector<std::string>& controllerList) {
  if (controllerList.empty()) {
    redfish::messages::internalError(asyncResp->res);
    return;
  }

  for (const auto& controller : controllerList) {
    if (sdbusplus::message::object_path(controller).filename() !=
        controllerId) {
      continue;
    }
    populateNVMeController(asyncResp, systemName, nvmeId, controllerId,
                           controller);
    return;
  }

  redfish::messages::internalError(asyncResp->res);
}

inline void populateNVMeControllerCollection(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& nvme, const boost::system::error_code ec,
    const nlohmann::json::json_pointer& jsonPtr,
    const std::vector<std::string>& controllerList) {
  if (ec == boost::system::errc::io_error || controllerList.empty()) {
    auto controllers = nlohmann::json::object();
    controllers["Name"] = "Google NVMe Controller Collection";
    controllers["@odata.id"] = crow::utility::urlFromPieces(
        "google", "v1", "NVMe", nvme, "Controllers");
    controllers["Members"] = nlohmann::json::array();
    controllers["Members@odata.count"] = 0;
    asyncResp->res.jsonValue[jsonPtr] = std::move(controllers);
    return;
  }

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

  auto controllers = nlohmann::json::object();
  controllers["Name"] = "Google NVMe Controller Collection";
  controllers["@odata.id"] =
      crow::utility::urlFromPieces("google", "v1", "NVMe", nvme, "Controllers");
  nlohmann::json members = nlohmann::json::array();
  for (const std::string& controller : controllerList) {
    std::string name = sdbusplus::message::object_path(controller).filename();
    if (name.empty()) {
      continue;
    }
    nlohmann::json::object_t member;
    member["@odata.id"] = crow::utility::urlFromPieces(
        "google", "v1", "NVMe", nvme, "Controllers", name);
    members.push_back(std::move(member));
  }
  controllers["Members@odata.count"] = members.size();
  controllers["Members"] = std::move(members);
  asyncResp->res.jsonValue[jsonPtr] = std::move(controllers);
}

inline void processDriveResource(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::optional<std::string>& nvme,
    std::function<void(const std::string&)>&& cb) {
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  constexpr std::array<std::string_view, 1> interfaces{
      "xyz.openbmc_project.Inventory.Item.Drive"};
  managedStore::GetManagedObjectStore()->getSubTree(
      "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
      [asyncResp, nvme, requestContext,
       cb{std::forward<std::function<void(const std::string&)>>(cb)}](
          const boost::system::error_code ec,
          const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          BMCWEB_LOG_INFO << "DBUS error: no matched iface for Drive: "
                          << ec.message();
          redfish::messages::internalError(asyncResp->res);
          return;
        }

        for (const auto& [path, services] : subtree) {
          if (nvme.has_value() &&
              sdbusplus::message::object_path(path).filename() != *nvme) {
            continue;
          }

          for (const auto& [service, interfaces] : services) {
            for (const std::string& interface : interfaces) {
              if (interface != "xyz.openbmc_project.Inventory.Item.Drive") {
                continue;
              }

              redfish::dbus_utils::getProperty<std::string>(
                  service, path, interface, "Protocol", requestContext,
                  [path{path}, cb](const boost::system::error_code ec2,
                                   const std::string& driveProtocol) {
                    if (ec2) {
                      return;
                    }

                    if (driveProtocol !=
                        "xyz.openbmc_project.Inventory.Item.Drive."
                        "DriveProtocol.NVMe") {
                      return;
                    }

                    cb(path);
                  });

              // If expecting valid NVMe, return after finding the first
              // NVMe.
              if (nvme.has_value()) {
                return;
              }
            }
          }
        }
        // Expecting valid NVMe
        if (nvme.has_value()) {
          redfish::messages::internalError(asyncResp->res);
        }
      });
}

inline void handleGoogleNvmeController(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& nvme, NVMeControllerHandlerCb&& cb) {
  processDriveResource(
      asyncResp, nvme,
      [asyncResp, cb{std::forward<NVMeControllerHandlerCb>(cb)}](
          const std::string& path) mutable {
        managedStore::ManagedObjectStoreContext requestContext(asyncResp);
        redfish::dbus_utils::getProperty<std::vector<std::string>>(
            "xyz.openbmc_project.ObjectMapper", path + "/storage_controller",
            "xyz.openbmc_project.Association", "endpoints", requestContext,
            [cb{std::move(cb)}, path](
                const boost::system::error_code ec,
                const std::vector<std::string>& controllerList) {
              cb(ec, path, controllerList);
            });
      });
}

inline void populateNVMe(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                         const std::string& path, const std::string& nvmeId) {
  asyncResp->res.jsonValue["@odata.type"] = "#NVMe.v1_0_0.NVMe";
  asyncResp->res.jsonValue["@odata.id"] =
      crow::utility::urlFromPieces("google", "v1", "NVMe", nvmeId);
  asyncResp->res.jsonValue["Name"] = nvmeId;

  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  redfish::dbus_utils::getProperty<std::vector<std::string>>(
      "xyz.openbmc_project.ObjectMapper", path + "/storage",
      "xyz.openbmc_project.Association", "endpoints", requestContext,
      [asyncResp, nvmeId, requestContext](
          const boost::system::error_code ec,
          const std::vector<std::string>& storageList) {
        if (ec || storageList.empty()) {
          BMCWEB_LOG_DEBUG << "Failed to find storage that is associated with "
                           << nvmeId;
          return;
        }
        if (storageList.size() > 1) {
          BMCWEB_LOG_DEBUG << nvmeId << " is associated with mutliple storages";
          return;
        }

        sdbusplus::message::object_path storagePath(storageList[0]);
        std::string storageId = storagePath.filename();
        if (storageId.empty()) {
          BMCWEB_LOG_ERROR << "filename() is empty in " << storagePath.str;
          return;
        }
        redfish::storage_utils::getSystemPathFromStorage(
            asyncResp, storagePath,
            [asyncResp, storageId](std::optional<std::string_view> systemPath) {
              std::string systemName =
                  systemPath ? std::filesystem::path(*systemPath).filename()
                             : "system";
              asyncResp->res.jsonValue["Links"]["Storage"]["@odata.id"] =
                  crow::utility::urlFromPieces("redfish", "v1", "Systems",
                                               systemName, "Storage",
                                               storageId);
            });
      });

  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.NVMe.NVMeAdmin"};
  managedStore::GetManagedObjectStore()->getAssociatedSubTreePaths(
      path + "/storage_controller",
      sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
      interfaces, requestContext,
      [asyncResp, nvmeId](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreePathsResponse& controllerList) {
        populateNVMeControllerCollection(
            asyncResp, nvmeId, ec, "/Controllers"_json_pointer, controllerList);
      });
}

inline void handleGoogleNvme(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& nvme) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  processDriveResource(asyncResp, nvme,
                       [asyncResp, nvme](const std::string& path) {
                         populateNVMe(asyncResp, path, nvme);
                       });
}

inline void handleGoogleNvmeControllerCollection(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& nvme) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  processDriveResource(
      asyncResp, nvme, [asyncResp, nvme](const std::string& path) {
        constexpr std::array<std::string_view, 1> interfaces = {
            "xyz.openbmc_project.NVMe.NVMeAdmin"};
        managedStore::ManagedObjectStoreContext requestContext(asyncResp);
        managedStore::GetManagedObjectStore()->getAssociatedSubTreePaths(
            path + "/storage_controller",
            sdbusplus::message::object_path("/xyz/openbmc_project/inventory"),
            0, interfaces, requestContext,
            [asyncResp, nvme](
                const boost::system::error_code& ec,
                const dbus::utility::MapperGetSubTreePathsResponse&
                    controllerList) {
              populateNVMeControllerCollection(asyncResp, nvme, ec,
                                               ""_json_pointer, controllerList);
            });
      });
}

inline void handleGoogleNvmeCollection(
    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"] =
      "#NVMeCollection.v1_0_0.NVMeCollection";
  asyncResp->res.jsonValue["@odata.id"] = "/google/v1/NVMe";
  asyncResp->res.jsonValue["Name"] = "Google NVMe Collection";

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

  processDriveResource(
      asyncResp, std::nullopt, [asyncResp](const std::string& path) {
        std::string id = sdbusplus::message::object_path(path).filename();
        if (id.empty()) {
          return;
        }

        nlohmann::json& members = asyncResp->res.jsonValue["Members"];
        nlohmann::json::object_t member;
        member["@odata.id"] =
            crow::utility::urlFromPieces("google", "v1", "NVMe", id);
        members.push_back(std::move(member));
        asyncResp->res.jsonValue["Members@odata.count"] = members.size();
      });
}

inline void getIdentity(
    uint8_t cns, uint16_t cntid, uint32_t nsid,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& controllerId, const boost::system::error_code ec,
    const std::vector<std::string>& controllerList,
    const std::string& adminInterface = "xyz.openbmc_project.NVMe.NVMeAdmin") {
  if (ec || controllerList.empty()) {
    redfish::messages::internalError(asyncResp->res);
    return;
  }

  std::string controllerPath;
  for (const std::string& controller : controllerList) {
    if (sdbusplus::message::object_path(controller).filename() ==
        controllerId) {
      controllerPath = controller;
      break;
    }
  }

  if (controllerPath.empty()) {
    redfish::messages::internalError(asyncResp->res);
    return;
  }

  managedStore::ManagedObjectStoreContext context(asyncResp);
  const std::string_view adminInterfaceView = adminInterface;
  std::span<const std::string_view> interfaces(&adminInterfaceView, 1);
  managedStore::GetManagedObjectStore()->getDbusObject(
      controllerPath, interfaces, context,
      [asyncResp, cns, cntid, nsid, controllerPath, adminInterface](
          const boost::system::error_code ec2,
          const dbus::utility::MapperGetObject& objects) {
        if (ec2) {
          BMCWEB_LOG_ERROR << "GetObject for path " << controllerPath
                           << " failed with code " << ec2;
          return;
        }

        if (objects.size() != 1) {
          redfish::messages::internalError(asyncResp->res);
          BMCWEB_LOG_ERROR << "Service supporting " << controllerPath
                           << " is not equal to 1";
          return;
        }

        managedStore::GetManagedObjectStore()
            ->PostDbusCallToIoContextThreadSafe(
                asyncResp->strand_,
                [asyncResp, objects, controllerPath](
                    const boost::system::error_code ec3,
                    const sdbusplus::message::unix_fd& fd) {
                  if (ec3) {
                    BMCWEB_LOG_ERROR << "Failed to call NVMe Identity: "
                                     << ec3.message();
                    redfish::messages::internalError(asyncResp->res);
                    return;
                  }

                  int dupFd = dup(fd.fd);
                  fetchFile(asyncResp, std::make_shared<stream_descriptor>(
                                           *fdIOContext, dupFd));
                },
                objects[0].first, controllerPath, adminInterface, "Identify",
                cns, nsid, cntid);
      });
}

inline void handleGoogleNvmeControllerCustomNVMeIdentifyAction(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& nvmeId, const std::string& controllerId) {
  uint8_t cns = 0;     // Controller or Namespace Structure
  uint16_t cntid = 0;  // Controller Identifier
  uint32_t nsid = 0;   // Namespace Identifier

  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }

  if (!redfish::json_util::readJsonAction(req, asyncResp->res, "CNS", cns,
                                          "CNTID", cntid, "NSID", nsid)) {
    redfish::messages::actionParameterMissing(
        asyncResp->res, "ControllerNamespace", "ControllerNamespaceId");
    return;
  }
  handleGoogleNvmeController(
      asyncResp, nvmeId,
      [cns, cntid, nsid, asyncResp, controllerId](
          const boost::system::error_code ec,
          const std::string& /* storagePath */,
          const std::vector<std::string>& controllerList) {
        getIdentity(
            cns, cntid, nsid, asyncResp, controllerId, ec, controllerList,
            "xyz.openbmc_project.NVMe." + std::string(customNVMe) + "Admin");
      });
}

inline void handleGoogleNvmeControllerIdentifyAction(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& nvmeId, const std::string& controllerId) {
  uint8_t cns = 0;     // Controller or Namespace Structure
  uint16_t cntid = 0;  // Controller Identifier
  uint32_t nsid = 0;   // Namespace Identifier

  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }

  if (!redfish::json_util::readJsonAction(req, asyncResp->res, "CNS", cns,
                                          "CNTID", cntid, "NSID", nsid)) {
    redfish::messages::actionParameterMissing(
        asyncResp->res, "ControllerNamespace", "ControllerNamespaceId");
    return;
  }
  handleGoogleNvmeController(
      asyncResp, nvmeId,
      [cns, cntid, nsid, asyncResp, controllerId](
          const boost::system::error_code ec,
          const std::string& /* storagePath */,
          const std::vector<std::string>& controllerList) {
        getIdentity(cns, cntid, nsid, asyncResp, controllerId, ec,
                    controllerList);
      });
}

inline void adminNonDataCmd(
    [[maybe_unused]] uint8_t opcode, [[maybe_unused]] uint32_t cdw1,
    [[maybe_unused]] uint32_t cdw2, [[maybe_unused]] uint32_t cdw3,
    [[maybe_unused]] uint32_t cdw10, [[maybe_unused]] uint32_t cdw11,
    [[maybe_unused]] uint32_t cdw12, [[maybe_unused]] uint32_t cdw13,
    [[maybe_unused]] uint32_t cdw14, [[maybe_unused]] uint32_t cdw15,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& controllerId, const boost::system::error_code ec,
    const std::vector<std::string>& controllerList) {
  if (ec || controllerList.empty()) {
    redfish::messages::internalError(asyncResp->res);
    return;
  }

  std::string controllerPath;
  for (const std::string& controller : controllerList) {
    if (sdbusplus::message::object_path(controller).filename() ==
        controllerId) {
      controllerPath = controller;
      break;
    }
  }

  if (controllerPath.empty()) {
    BMCWEB_LOG_ERROR << "failed to find DBus controller path for "
                     << controllerId;
    redfish::messages::internalError(asyncResp->res);
    return;
  }

// The PostDbusCallToIoContextThreadSafe is NOT unitestable. MOCK_METHOD dosent
// work with this many params. If we want to unit test this funciton, we
// probably will have to change dbus.
#ifndef UNIT_TEST_BUILD

  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.NVMe.Passthru"};

  managedStore::ManagedObjectStoreContext context(asyncResp);
  managedStore::GetManagedObjectStore()->getDbusObject(
      controllerPath, interfaces, context,
      [asyncResp, opcode, cdw1, cdw2, cdw3, cdw10, cdw11, cdw12, cdw13, cdw14,
       cdw15, controllerPath](const boost::system::error_code ec2,
                              const dbus::utility::MapperGetObject& objects) {
        if (ec2) {
          BMCWEB_LOG_ERROR << "GetObject for path " << controllerPath
                           << " failed with code " << ec2;
          return;
        }

        if (objects.size() != 1) {
          redfish::messages::internalError(asyncResp->res);
          BMCWEB_LOG_ERROR << "Service supporting " << controllerPath
                           << " is not equal to 1";
          return;
        }

        const std::string& service{objects[0].first};

        managedStore::GetManagedObjectStore()
            ->PostDbusCallToIoContextThreadSafe(
                asyncResp->strand_,
                [asyncResp](
                    const boost::system::error_code ec3,
                    const sdbusplus::message_t& msg,
                    const std::tuple<uint32_t, uint32_t, uint32_t>& response) {
                  const ::sd_bus_error* sd_err = msg.get_error();
                  if (sd_err != nullptr) {
                    redfish::messages::generalError(asyncResp->res);
                    if (sd_err->message != nullptr) {
                      BMCWEB_LOG_ERROR << "Error: " << sd_err->name
                                       << " message " << sd_err->message;
                      asyncResp->res.jsonValue["error"]["message"] =
                          sd_err->message;
                    }
                    return;
                  }

                  if (ec3) {
                    BMCWEB_LOG_ERROR << "AdminNonDataCmd dbus error " << ec3;
                    redfish::messages::internalError(asyncResp->res);
                    return;
                  }

                  // Success
                  asyncResp->res.jsonValue["MIStatus"] = std::get<0>(response);
                  asyncResp->res.jsonValue["AdminStatus"] =
                      std::get<1>(response);
                  asyncResp->res.jsonValue["CompletionDW0"] =
                      std::get<2>(response);
                },
                service, controllerPath, "xyz.openbmc_project.NVMe.Passthru",
                "AdminNonDataCmd", opcode, cdw1, cdw2, cdw3, cdw10, cdw11,
                cdw12, cdw13, cdw14, cdw15);
      });
#endif
}

inline void lockdownInband(const uint8_t prohibit,
                           const std::vector<uint8_t>& adminCmds,
                           const std::vector<uint8_t>& features,
                           const std::vector<uint8_t>& logPages,
                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                           const std::string& controllerId,
                           const boost::system::error_code& ec,
                           const std::vector<std::string>& controllerList) {
  if (ec || controllerList.empty()) {
    redfish::messages::internalError(asyncResp->res);
    return;
  }

  std::string controllerPath;
  for (const std::string& controller : controllerList) {
    if (sdbusplus::message::object_path(controller).filename() ==
        controllerId) {
      controllerPath = controller;
      break;
    }
  }

  if (controllerPath.empty()) {
    BMCWEB_LOG_ERROR << "failed to find DBus controller path for "
                     << controllerId;
    redfish::messages::internalError(asyncResp->res);
    return;
  }

  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.NVMe.Lockdown"};

  managedStore::ManagedObjectStoreContext context(asyncResp);
  managedStore::GetManagedObjectStore()->getDbusObject(
      controllerPath, interfaces, context,
      [asyncResp, prohibit, adminCmds, features, logPages, controllerPath](
          const boost::system::error_code& ec2,
          const dbus::utility::MapperGetObject& objects) {
        if (ec2) {
          BMCWEB_LOG_ERROR << "GetObject for path " << controllerPath
                           << " failed with code " << ec2;
          return;
        }

        if (objects.size() != 1) {
          redfish::messages::internalError(asyncResp->res);
          BMCWEB_LOG_ERROR << "Service supporting " << controllerPath
                           << " is not equal to 1";
          return;
        }

        const std::string& service{objects[0].first};

        managedStore::GetManagedObjectStore()
            ->PostDbusCallToIoContextThreadSafe(
                asyncResp->strand_,
                absl::AnyInvocable<void(
                    const boost::system::error_code&,
                    const sdbusplus::message_t&,
                    const std::tuple<uint32_t, uint32_t, uint32_t, std::string,
                                     uint32_t>&)>(
                    [asyncResp](
                        const boost::system::error_code& ec3,
                        const sdbusplus::message_t& msg,
                        const std::tuple<uint32_t, uint32_t, uint32_t,
                                         std::string, uint32_t>& response) {
                      const ::sd_bus_error* sdErr = msg.get_error();
                      if (sdErr != nullptr) {
                        redfish::messages::generalError(asyncResp->res);
                        if (sdErr->message != nullptr) {
                          BMCWEB_LOG_ERROR << "Error: " << sdErr->name
                                           << " message " << sdErr->message;
                          asyncResp->res.jsonValue["error"]["message"] =
                              sdErr->message;
                        }
                        return;
                      }

                      if (ec3) {
                        BMCWEB_LOG_ERROR << "LockdownInband dbus error " << ec3;
                        redfish::messages::internalError(asyncResp->res);
                        return;
                      }

                      // Success
                      uint32_t miStatus = std::get<0>(response);
                      uint32_t adminStatus = std::get<1>(response);
                      asyncResp->res.jsonValue["MIStatus"] = miStatus;
                      asyncResp->res.jsonValue["AdminStatus"] = adminStatus;
                      asyncResp->res.jsonValue["CompletionDW0"] =
                          std::get<2>(response);
                      if (miStatus != 0 || adminStatus != 0) {
                        asyncResp->res.jsonValue["FailureScope"] =
                            std::get<3>(response);
                        asyncResp->res.jsonValue["FailureId"] =
                            std::get<4>(response);
                      }
                    }),
                service, controllerPath, "xyz.openbmc_project.NVMe.Lockdown",
                "LockdownInband", prohibit, adminCmds, features, logPages);
      });
}

inline void getLogPage(
    uint8_t lid,  // Log Page Identifier, Command Dword 10 bits[07:00]
    uint32_t nsid,
    uint8_t lsp,   // Log Specific Field,  Command Dword 10 bits[14:08]
    uint16_t lsi,  // Log Specific Identifier, Command Dword 11 bits[31:16]
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& controllerId, const boost::system::error_code ec,
    const std::vector<std::string>& controllerList) {
  if (ec || controllerList.empty()) {
    redfish::messages::internalError(asyncResp->res);
    return;
  }

  std::string controllerPath;
  for (const std::string& controller : controllerList) {
    if (sdbusplus::message::object_path(controller).filename() ==
        controllerId) {
      controllerPath = controller;
      break;
    }
  }

  if (controllerPath.empty()) {
    redfish::messages::internalError(asyncResp->res);
    return;
  }

  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.NVMe.NVMeAdmin"};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getDbusObject(
      controllerPath, interfaces, requestContext,
      [asyncResp, lid, nsid, lsp, lsi, controllerPath](
          const boost::system::error_code ec2,
          const dbus::utility::MapperGetObject& objects) {
        if (ec2) {
          BMCWEB_LOG_ERROR << "GetObject for path " << controllerPath
                           << " failed with code " << ec2;
          return;
        }

        if (objects.size() != 1) {
          BMCWEB_LOG_ERROR << "Service supporting " << controllerPath
                           << " is not equal to 1";
          redfish::messages::internalError(asyncResp->res);
          return;
        }

        managedStore::GetManagedObjectStore()
            ->PostDbusCallToIoContextThreadSafe(
                asyncResp->strand_,
                [asyncResp, objects, controllerPath](
                    const boost::system::error_code ec3,
                    const sdbusplus::message::unix_fd& fd) {
                  if (ec3) {
                    BMCWEB_LOG_INFO << "Failed to call NVMe Log "
                                    << ec3.message();
                    redfish::messages::internalError(asyncResp->res);
                    return;
                  }

                  int dupFd = dup(fd.fd);
                  fetchFile(asyncResp, std::make_shared<stream_descriptor>(
                                           *fdIOContext, dupFd));
                },
                objects[0].first, controllerPath,
                "xyz.openbmc_project.NVMe.NVMeAdmin", "GetLogPage", lid, nsid,
                lsp, lsi);
      });
}

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

  uint8_t lid = 0;  // Log Page Identifier, Command Dword 10 bits[07:00]
  uint32_t nsid = 0;
  uint8_t lsp = 0;   // Log Specific Field,  Command Dword 10 bits[14:08]
  uint16_t lsi = 0;  // Log Specific Identifier, Command Dword 11 bits[31:16]

  if (!redfish::json_util::readJsonAction(req, asyncResp->res, "LID", lid,
                                          "NSID", nsid, "LSP", lsp, "LSI",
                                          lsi)) {
    redfish::messages::actionParameterMissing(asyncResp->res, "LogSpecificId",
                                              "LogId");
    return;
  }

  handleGoogleNvmeController(
      asyncResp, nvmeId,
      [lid, nsid, lsp, lsi, asyncResp, controllerId](
          const boost::system::error_code ec,
          const std::string& /* storagePath */,
          const std::vector<std::string>& controllerList) {
        getLogPage(lid, nsid, lsp, lsi, asyncResp, controllerId, ec,
                   controllerList);
      });
}

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

  // Only opcode is mandatory
  uint8_t opcode = 0;
  std::optional<uint32_t> cdw1;
  std::optional<uint32_t> cdw2;
  std::optional<uint32_t> cdw3;
  std::optional<uint32_t> cdw10;
  std::optional<uint32_t> cdw11;
  std::optional<uint32_t> cdw12;
  std::optional<uint32_t> cdw13;
  std::optional<uint32_t> cdw14;
  std::optional<uint32_t> cdw15;

  if (!redfish::json_util::readJsonAction(
          req, asyncResp->res, "opcode", opcode, "cdw1", cdw1, "cdw2", cdw2,
          "cdw3", cdw3, "cdw10", cdw10, "cdw11", cdw11, "cdw12", cdw12, "cdw13",
          cdw13, "cdw14", cdw14, "cdw15", cdw15)) {
    redfish::messages::actionParameterMissing(
        asyncResp->res, "NVMeController.AdminNonDataCmd", "opcode");
    return;
  }

  handleGoogleNvmeController(
      asyncResp, nvmeId,
      [opcode, cdw1{cdw1.value_or(0)}, cdw2{cdw2.value_or(0)},
       cdw3{cdw3.value_or(0)}, cdw10{cdw10.value_or(0)},
       cdw11{cdw11.value_or(0)}, cdw12{cdw12.value_or(0)},
       cdw13{cdw13.value_or(0)}, cdw14{cdw14.value_or(0)},
       cdw15{cdw15.value_or(0)}, asyncResp,
       controllerId](const boost::system::error_code ec,
                     const std::string& /* storagePath */,
                     const std::vector<std::string>& controllerList) {
        adminNonDataCmd(opcode, cdw1, cdw2, cdw3, cdw10, cdw11, cdw12, cdw13,
                        cdw14, cdw15, asyncResp, controllerId, ec,
                        controllerList);
      });
}

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

  bool prohibit = false;
  std::optional<std::vector<uint8_t>> adminCmds;
  std::optional<std::vector<uint8_t>> features;
  std::optional<std::vector<uint8_t>> logPages;

  if (!redfish::json_util::readJsonAction(
          req, asyncResp->res, "Prohibit", prohibit, "AdminCmds", adminCmds,
          "Features", features, "LogPages", logPages)) {
    redfish::messages::actionParameterMissing(
        asyncResp->res, "NVMeController.LockdownInband", "Prohibit");
    return;
  }

  handleGoogleNvmeController(
      asyncResp, nvmeId,
      [prohibit, adminCmds, features, logPages, asyncResp, controllerId](
          const boost::system::error_code& ec,
          const std::string& /* storagePath */,
          const std::vector<std::string>& controllerList) {
        lockdownInband(prohibit ? 1 : 0,
                       adminCmds.value_or(std::vector<uint8_t>{}),
                       features.value_or(std::vector<uint8_t>{}),
                       logPages.value_or(std::vector<uint8_t>{}), asyncResp,
                       controllerId, ec, controllerList);
      });
}
inline void setupGoogleNVMeFdFetchIOContext(
    const std::shared_ptr<boost::asio::io_context>& ioc) {
  fdIOContext = ioc;
}

inline void requestGoogleNVMeControllerActionCustomNVMeIdentify(App& app) {
  BMCWEB_ROUTE(
      app, "/google/v1/NVMe/<str>/Controllers/<str>/Actions/NVMeController." +
               std::string(customNVMe) + "Identify")
      .privileges({{"ConfigureManager"}})
      .methods(boost::beast::http::verb::post)(std::bind_front(
          handleGoogleNvmeControllerCustomNVMeIdentifyAction, std::ref(app)));
}

inline void requestGoogleNVMeControllerActionIdentify(App& app) {
  BMCWEB_ROUTE(
      app,
      "/google/v1/NVMe/<str>/Controllers/<str>/Actions/NVMeController.Identify")
      .privileges({{"ConfigureManager"}})
      .methods(boost::beast::http::verb::post)(std::bind_front(
          handleGoogleNvmeControllerIdentifyAction, std::ref(app)));
}

inline void requestGoogleNVMeControllerActionLog(App& app) {
  BMCWEB_ROUTE(app,
               "/google/v1/NVMe/<str>/Controllers/<str>/Actions/"
               "NVMeController.GetLogPage")
      .privileges({{"ConfigureManager"}})
      .methods(boost::beast::http::verb::post)(
          std::bind_front(handleGoogleNvmeControllerLogAction, std::ref(app)));
}

inline void requestGoogleNVMeControllerActionAdminNonData(App& app) {
  BMCWEB_ROUTE(app,
               "/google/v1/NVMe/<str>/Controllers/<str>/Actions/"
               "NVMeController.AdminNonDataCmd")
      .privileges({{"ConfigureManager"}})
      .methods(boost::beast::http::verb::post)(std::bind_front(
          handleGoogleNvmeControllerAdminNonDataAction, std::ref(app)));
}

inline void requestGoogleNVMeControllerActionLockdownInband(App& app) {
  BMCWEB_ROUTE(app,
               "/google/v1/NVMe/<str>/Controllers/<str>/Actions/"
               "NVMeController.LockdownInband")
      .privileges({{"ConfigureManager"}})
      .methods(boost::beast::http::verb::post)(std::bind_front(
          handleGoogleNvmeControllerLockdownInband, std::ref(app)));
}

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

  handleGoogleNvmeController(
      asyncResp, nvmeId,
      [asyncResp, nvmeId, controllerId](
          const boost::system::error_code ec, const std::string& storagePath,
          const std::vector<std::string>& controllerList) {
        if (ec) {
          redfish::messages::internalError(asyncResp->res);
          return;
        }
        redfish::storage_utils::getSystemPathFromStorage(
            asyncResp, storagePath,
            [asyncResp, nvmeId, controllerId,
             controllerList](std::optional<std::string_view> systemPath) {
              std::string systemName =
                  systemPath ? std::filesystem::path(*systemPath).filename()
                             : "system";
              setupNVMeController(asyncResp, systemName, nvmeId, controllerId,
                                  controllerList);
            });
      });
}

inline void requestGoogleNVMeController(App& app) {
  BMCWEB_ROUTE(app, "/google/v1/NVMe/<str>/Controllers/<str>")
      .privileges({{"ConfigureManager"}})
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGoogleNVMeControllerGet, std::ref(app)));
}

inline void requestGoogleNVMeControllerCollection(App& app) {
  BMCWEB_ROUTE(app, "/google/v1/NVMe/<str>/Controllers")
      .privileges({{"ConfigureManager"}})
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGoogleNvmeControllerCollection, std::ref(app)));
}

inline void requestGoogleNVMe(App& app) {
  BMCWEB_ROUTE(app, "/google/v1/NVMe/<str>")
      .privileges({{"ConfigureManager"}})
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGoogleNvme, std::ref(app)));
}

inline void requestGoogleNVMeCollection(App& app) {
  BMCWEB_ROUTE(app, "/google/v1/NVMe")
      .privileges({{"ConfigureManager"}})
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGoogleNvmeCollection, std::ref(app)));
}

}  // namespace google_api
}  // namespace crow

#endif  // THIRD_PARTY_GBMCWEB_INCLUDE_GOOGLE_GOOGLE_SERVICE_NVME_H_
