#ifndef THIRD_PARTY_MILOTIC_INTERNAL_CC_BMCWEB_MOCK_MANAGED_STORE_H_
#define THIRD_PARTY_MILOTIC_INTERNAL_CC_BMCWEB_MOCK_MANAGED_STORE_H_

#include <type_traits>
#pragma GCC diagnostic push
#pragma GCC diagnostic warning \
    "-Wdeprecated-declarations"  // tests still access deprecated methods

#include <array>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <thread>
#include <tuple>
#include <utility>
#include <variant>
#include <vector>

#include <gmock/gmock.h>
#include "absl/functional/any_invocable.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/str_format.h"
#include "absl/synchronization/mutex.h"
#include "boost/asio/post.hpp"
#include "boost/container/flat_map.hpp"
#include "boost/system/errc.hpp"
#include "subscription.h"
#include "dbus_utility.hpp" // NOLINT
#include "async_resp.hpp" // NOLINT
#include "http_request.hpp" // NOLINT
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/asio/connection.hpp"
#include "sdbusplus/message.hpp"
#include "sdbusplus/message/native_types.hpp"

namespace managedStore {

class MockManagedObjectStore : public ManagedObjectStore {
 public:
  MockManagedObjectStore(
      const ManagedObjectStoreConfig& cfg, boost::asio::io_context& io,
      std::thread::id main_thread_id,
      const std::shared_ptr<boost::asio::io_context>& io_context_worker_threads,
      ecclesia::SubscriptionService* ss = nullptr,
      sdbusplus::asio::connection* systemBus = nullptr)
      : ManagedObjectStore(cfg, io, main_thread_id, io_context_worker_threads,
                           ss, systemBus) {}

  // copybara:strip_begin(Using deprecated functions wont compile in gerrit)
  const ManagedObjectsMap& getManagedObjectsFromStore() const {
    return this->getManagedObjects();
  }

  const ManagedStorePriorityQueue& getManagedStorePriorityQueue() const {
    return this->getPriorityQueue();
  }
  // copybara:strip_end

  ManagedStoreTracker getManagedStoreTracker() {
    return this->getStoreTracker();
  }

  // due to sdbusplus's design, its not possible to create a system bus at all
  // as the dbus daemon is not running. so we will hack the pointer to test the
  // logic. DO NOT ACCESS THIS POINTER.
  // THIS IS ONLY USED TO INITIALIZE THE MANAGESTORE DO NOT USE THE CONNECTION

  // The only other alternative is not unit testing the initialize code
  inline static sdbusplus::asio::connection*
  GetBadPointerToSystemBusWhichShouldNeverBeUsedOtherThanInitializeManagedStoreForUnitTests() {
    static sdbusplus::asio::connection* system_bus =
        reinterpret_cast<sdbusplus::asio::connection*>(0x2489);
    return system_bus;
  }

  MOCK_METHOD(void, getManagedObjectsFromDbusService,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               const std::string&, const sdbusplus::message::object_path&,
               ManagedStoreCb, std::optional<uint64_t>),
              (override));
  MOCK_METHOD(void, getManagedPropertiesMapFromDbusService,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               const std::string&, const sdbusplus::message::object_path&,
               const std::string&, ManagedStoreCb, std::optional<uint64_t>),
              (override));
  MOCK_METHOD(void, getManagedMapperObjectFromDbusService,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               const sdbusplus::message::object_path&,
               const std::vector<std::string>&, ManagedStoreCb,
               std::optional<uint64_t>),
              (override));
  MOCK_METHOD(void, getSystemdUnitsFromDbusService,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               ManagedStoreCb, std::optional<uint64_t>),
              (override));

  MOCK_METHOD(void, getManagedSubtreePathsFromDbusService,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               const sdbusplus::message::object_path& path, int32_t depth,
               const std::vector<std::string>& interfaces,
               ManagedStoreCb callback, std::optional<uint64_t>),
              (override));
  MOCK_METHOD(void, getManagedSubtreeFromDbusService,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               const sdbusplus::message::object_path& path, int32_t depth,
               const std::vector<std::string>& interfaces,
               ManagedStoreCb callback, std::optional<uint64_t>),
              (override));
  MOCK_METHOD(void, getManagedAssociatedSubtreePathsFromDbusService,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               const sdbusplus::message::object_path& associatedPath,
               const sdbusplus::message::object_path& path, int32_t depth,
               const std::vector<std::string>& interfaces,
               ManagedStoreCb callback, std::optional<uint64_t>),
              (override));
  MOCK_METHOD(void, getManagedAssociatedSubtreeFromDbusService,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               const sdbusplus::message::object_path& associatedPath,
               const sdbusplus::message::object_path& path, int32_t depth,
               const std::vector<std::string>& interfaces,
               ManagedStoreCb callback, std::optional<uint64_t>),
              (override));
  MOCK_METHOD(void, getManagedPropertiesFromDbusService,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               const std::string& service,
               const sdbusplus::message::object_path& path,
               const std::string& interface, const std::string& property,
               ManagedStoreCb callback, std::optional<uint64_t>),
              (override));
};

class MockManagedObjectStoreWithControlledCache
    : public MockManagedObjectStore {
 public:
  MockManagedObjectStoreWithControlledCache(
      const ManagedObjectStoreConfig& cfg, boost::asio::io_context& io,
      std::thread::id main_thread_id,
      const std::shared_ptr<boost::asio::io_context>& io_context_worker_threads,
      ecclesia::SubscriptionService* ss = nullptr,
      sdbusplus::asio::connection* systemBus = nullptr)
      : MockManagedObjectStore(cfg, io, main_thread_id,
                               io_context_worker_threads, ss, systemBus) {
    ON_CALL(*this, IsManagedObjectCurrentAndTracked)
        .WillByDefault([this](const std::string& key_id, const KeyType& keyType,
                              const ManagedObjectStoreContext& requestContext) {
          return ManagedObjectStore::IsManagedObjectCurrentAndTracked(
              key_id, keyType, requestContext);
        });
  }

  template <typename Callback, typename... DbusCallArgs>
  void PostDbusCallToIoContextThreadSafe(
      [[maybe_unused]] const std::shared_ptr<boost::asio::io_context::strand>&
          strand,
      Callback&& callback, const std::string& service,
      const std::string& objpath, const std::string& interf,
      const std::string& method, DbusCallArgs&&... dbusCallArgs) {
    boost::asio::post(
        io_context_main_thread_,
        [this, callback(std::forward<Callback>(callback)), service, objpath,
         interf, method,
         ... dbusCallArgs(std::forward<DbusCallArgs>(dbusCallArgs))]() mutable {
          boost::system::error_code ec = boost::system::errc::make_error_code(
              boost::system::errc::success);

          using CallbackReturnType = std::decay_t<std::tuple_element_t<
              1, boost::callable_traits::args_t<Callback>>>;
          CallbackReturnType value;
          std::move(callback)(ec, value);
        });
  }
  MOCK_METHOD(std::shared_ptr<ValueType>, IsManagedObjectCurrentAndTracked,
              (const std::string& key_id, const KeyType& keyType,
               const ManagedObjectStoreContext& requestContext),
              (override));
};

class MockSerializedManagedObjectStore : public ManagedObjectStore {
 public:
  MockSerializedManagedObjectStore(
      const ManagedObjectStoreConfig& cfg, boost::asio::io_context& io,
      std::thread::id main_thread_id,
      const std::shared_ptr<boost::asio::io_context>& io_context_worker_threads,
      ecclesia::SubscriptionService* ss = nullptr,
      sdbusplus::asio::connection* systemBus = nullptr)
      : ManagedObjectStore(cfg, io, main_thread_id, io_context_worker_threads,
                           ss, systemBus) {}

  // This method will mock data into managedStore by upserting a new key value
  // pair.
  absl::Status upsertMockObjectIntoManagedStore(
      const KeyType& key, const std::shared_ptr<ValueType>& value) {
    ManagedType key_type = key.getManagedType();
    ManagedType value_type = value->getManagedType();

    if (!KeyAndValueTypeAreCompatible(key_type, value_type)) {
      LOG(INFO) << absl::StrFormat(
          "Key and Value type are not compatible. Key type: %s, Value type: %s",
          ManagedTypeToString(key_type), ManagedTypeToString(value_type));
      return absl::InvalidArgumentError("Key and Value type do not match");
    }

    absl::MutexLock lock(&managed_objects_mutex_);
    managedObjects[key.GetId()] = value;
    return absl::OkStatus();
  }

  // This method will evict a key value pair from managedStore.
  absl::Status evictMockObjectFromManagedStore(const KeyType& key) {
    absl::MutexLock lock(&managed_objects_mutex_);
    if (managedObjects.find(key.GetId()) == managedObjects.end()) {
      return absl::NotFoundError("Key not found in store");
    }
    managedObjects.erase(key.GetId());
    return absl::OkStatus();
  }

  // This method will get a key value pair from managedStore.
  absl::StatusOr<std::shared_ptr<ValueType>> getMockObjectFromManagedStore(
      const KeyType& key) {
    absl::MutexLock lock(&managed_objects_mutex_);
    if (managedObjects.find(key.GetId()) == managedObjects.end()) {
      return absl::NotFoundError("Key not found in store");
    }
    return managedObjects[key.GetId()];
  }

  // This method will print a key value pair from managedStore.
  void printObjectFromManagedStore(const KeyType& key) {
    absl::MutexLock lock(&managed_objects_mutex_);
    auto it = this->managedObjects.find(key.GetId());
    if (it == this->managedObjects.end()) {
      LOG(INFO) << "Key: " << key.GetId() << " not found in store";
      return;
    }
    LOG(INFO) << "Key: " << key.GetId()
              << " Value: " << it->second->serialize();
  }

  MOCK_METHOD(void, setProperty,
              (const std::string& service, const std::string& path,
               const std::string& interface, const std::string& propertyName,
               const std::string& propertyValue, SetPropertyCb&& callback));

  MOCK_METHOD(void, setProperty,
              (const std::string& service, const std::string& path,
               const std::string& interface, const std::string& propertyName,
               dbus::utility::DbusVariantType&& propertyValue,
               SetPropertyCb&& callback));

  using GetAncestorsResponseType = std::array<const char*, 1>;

  using ResolveHostnameCb = absl::AnyInvocable<void(
      const boost::system::error_code&,
      const std::vector<std::tuple<int32_t, int32_t, std::vector<uint8_t>>>&,
      const std::string&, const uint64_t)>;

  using PostCodeEntry = std::tuple<uint64_t, std::vector<uint8_t>>;

  using CreateDumpParamVec =
      std::vector<std::pair<std::string, std::variant<std::string, uint64_t>>>;

  using NumericThresholdParams =
      std::tuple<std::string, uint64_t, std::string, double>;

  using SPDMGetSignedMeasurmentsCb = absl::AnyInvocable<void(
      const boost::system::error_code&, const sdbusplus::message::object_path&,
      const std::string&, const std::string&, const std::string&,
      const std::string&, const std::string&)>;

  using DiscreteThresholdParams =
      std::tuple<std::string, std::string, uint64_t, std::string>;

  using TriggerThresholdParamsExt =
      std::variant<std::monostate, std::vector<NumericThresholdParams>,
                   std::vector<DiscreteThresholdParams>>;

  using TriggerSensorsParams =
      std::vector<std::pair<sdbusplus::message::object_path, std::string>>;

  using TriggerGetParamsVariant =
      std::variant<std::monostate, bool, std::string, TriggerThresholdParamsExt,
                   TriggerSensorsParams, std::vector<std::string>,
                   std::vector<sdbusplus::message::object_path>>;

  using TriggerGetAllCb = absl::AnyInvocable<void(
      const boost::system::error_code&,
      const std::vector<std::pair<std::string, TriggerGetParamsVariant>>&)>;

  // This is one specific type of Dbus Call that can be made
  // Every dbus call with different arguments will need its own mock method
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method));

  // This is one specific type of Dbus Call that can be made
  // This is an introspect command
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const std::string&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method));

  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const std::string&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method,
               const std::string& object,
               const std::vector<std::string>& interfaces));

  // This is one specific type of Dbus Call that can be made
  // This is ListNames command
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       std::vector<std::string>&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method));

  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const std::vector<std::string>&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method,
               const std::string& object,
               const std::vector<std::string>& interfaces));

  // This is one specific type of Dbus Call that can be made
  // This is an GetAncestors command from ObjectMapper
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<
                   void(const boost::system::error_code&,
                        const dbus::utility::MapperGetAncestorsResponse&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method,
               const std::string& obj_name,
               const GetAncestorsResponseType& interfaces));

  // This is one specific type of Dbus Call that can be made
  // This is an RestartUnit command from systemd
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method,
               const std::string& service_name, const std::string& command));

  // This is one specific type of Dbus Call that can be made
  // This overload is used for Get requests that have to be made outside
  // managedStore
  MOCK_METHOD(
      void, PostDbusCallToIoContextThreadSafe,
      (const std::shared_ptr<boost::asio::io_context::strand>&,
       absl::AnyInvocable<void(const boost::system::error_code&,
                               const dbus::utility::DbusVariantType&)>&&,
       const std::string& service, const std::string& objpath,
       const std::string& interf, const std::string& get,
       const std::string& get_interf, const std::string& property));

  // This is one specific type of Dbus Call that can be made
  // This overload is used for Set requests that have to be made outside
  // managedStore
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& set,
               const std::string& set_interf, const std::string& property_name,
               dbus::utility::DbusVariantType&& property));

  // This is one specific type of Dbus Call that can be made
  // This overload is used for Set requests with a special callback
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const sdbusplus::message_t&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& set,
               const std::string& set_interf, const std::string& property_name,
               dbus::utility::DbusVariantType property));

  // This is one specific type of Dbus Call that can be made
  // This overload is used for ResolveHostname in asyncResolve.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               ResolveHostnameCb&&, const std::string& service,
               const std::string& objpath, const std::string& interf,
               const std::string& method, int param1, const std::string& param2,
               int param3, uint64_t param4));

  // This is one specific type of Dbus Call that can be made
  // This overload is used for Create VLAN ethernet.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method,
               const std::string& param1, uint32_t param2));

  // This overload is used for Create IP ethernet.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& create_ip,
               const std::string& protocol, const std::string& address,
               uint8_t prefix_length, const std::string& param4));

  // This is one specific type of Dbus Call that can be made
  // This overload is used for GetPostCodes log_services.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const std::vector<PostCodeEntry>&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& get_postcodes,
               uint16_t param1));

  // getPostPackageRepairStatus in log_service.cpp
  using PostPackageRepairStatusParam =
      std::vector<std::tuple<uint16_t, uint16_t, uint16_t, uint16_t,
                             std::vector<uint16_t>>>;
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const PostPackageRepairStatusParam&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method));
  // getPostPackageRepairConfig
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const std::vector<uint16_t>&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method));

  MOCK_METHOD(
      void, PostDbusCallToIoContextThreadSafe,
      (const std::shared_ptr<boost::asio::io_context::strand>&,
       absl::AnyInvocable<
           void(const boost::system::error_code&,
                const boost::container::flat_map<uint64_t, PostCodeEntry>&&)>&&,
       const std::string& service, const std::string& objpath,
       const std::string& interf, const std::string& get_postcodes,
       uint16_t param1));

  // This is used for delete in log_services.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const sdbusplus::message_t&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method));

  // This is used for GetEntry in log_services.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const sdbusplus::message::unix_fd&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& get_entry));

  // This is used for CreateDump in log_services.hpp
  MOCK_METHOD(
      void, PostDbusCallToIoContextThreadSafe,
      (const std::shared_ptr<boost::asio::io_context::strand>&,
       absl::AnyInvocable<void(const boost::system::error_code&,
                               const sdbusplus::message_t&,
                               const sdbusplus::message::object_path&)>&&,
       const std::string& service, const std::string& objpath,
       const std::string& interf, const std::string& create_dump,
       const CreateDumpParamVec& create_dump_param_vec));

  // GetUserInfo in routing.hpp
  MOCK_METHOD(
      void, PostDbusCallToIoContextThreadSafe,
      (const std::shared_ptr<boost::asio::io_context::strand>&,
       absl::AnyInvocable<void(const boost::system::error_code&,
                               const dbus::utility::DBusPropertiesMap&)>&&,
       const std::string& service, const std::string& objpath,
       const std::string& interf, const std::string& get_user_info,
       const std::string& username));

  // SendHostCommand in google_service_root.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const std::vector<uint8_t>&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& send_host_command,
               const std::vector<unsigned char>& payload));

  // GetLogPage in google_service_nvme.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const sdbusplus::message::unix_fd&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& get_log_page,
               uint8_t lid, uint32_t nsid, uint8_t lsp, uint16_t lsi));

  // NVMEPassThrough in google_service_nvme.hpp
  // Commenting out for now because MOCK_METHOD dosent support this many
  // arguments. We may need it in the future but for now we can comment it out.
  // MOCK_METHOD(
  //     void, PostDbusCallToIoContextThreadSafe,
  //     (const std::shared_ptr<boost::asio::io_context::strand>&,
  //      absl::AnyInvocable<
  //          void(const boost::system::error_code&, const
  //          sdbusplus::message_t&,
  //               const std::tuple<uint32_t, uint32_t, uint32_t>&)>&&,
  //      const std::string& service, const std::string& objpath,
  //      const std::string& interf, const std::string& nvme_passthrough,
  //      uint8_t opcode, uint32_t cdw1, uint32_t cdw2, uint32_t cdw3,
  //      uint32_t cdw10, uint32_t cdw11, uint32_t cdw12, uint32_t cdw13,
  //      uint32_t cdw14, uint32_t cdw15));

  // Identify in google_service_nvme.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const sdbusplus::message::unix_fd&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& identify,
               uint8_t cns, uint32_t nsid, uint16_t cntid));

  // ExecuteRde in redfish_aggregator.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const std::string&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& execute_rde,
               int random, uint8_t id, const std::string& uri,
               const std::string& udev_id, const std::string& payload));

  // Mount in virtual_media.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const sdbusplus::message::unix_fd&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& mount,
               const std::string& image_url, bool rw,
               dbus::utility::DbusVariantType unix_fd));

  // CreateVolume in storage.hpp
  MOCK_METHOD(
      void, PostDbusCallToIoContextThreadSafe,
      (const std::shared_ptr<boost::asio::io_context::strand>&,
       absl::AnyInvocable<void(const boost::system::error_code&,
                               const sdbusplus::message_t&,
                               const sdbusplus::message::object_path&)>&&,
       const std::string& service, const std::string& objpath,
       const std::string& interf, const std::string& create_volume,
       uint64_t size, size_t lba_index, bool metadata_at_end));

  // AttachVolume in storage.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const sdbusplus::message_t&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& attach_volume,
               const sdbusplus::message::object_path& v));

  // SecuritySend in storage.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const sdbusplus::message_t&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& security_send,
               uint8_t proto, uint16_t proto_specific,
               const std::vector<uint8_t>& data));

  // SecurityRecieve in storage.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const sdbusplus::message_t&,
                                       const std::vector<uint8_t>&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& security_recieve,
               uint8_t proto, uint16_t proto_specific,
               uint32_t transfer_length));

  // DriveErase in storage.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const sdbusplus::message_t&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& drive_erase,
               const std::string& action_name));

  // CreateUser in account_service.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       sdbusplus::message_t&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& create_user,
               const std::string& username,
               const std::vector<std::string>& all_groups_list,
               const std::string& role_id, bool enabled));

  // RenameUser in account_service.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       sdbusplus::message_t&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& create_user,
               const std::string& username, const std::string& new_username));

  // AddObject in managers.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& add_object,
               const dbus::utility::DBusPropertiesMap& output));

  // Install in certificate_service.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const std::string&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& install,
               const std::string& file_path));

  // Replace in certificate_service.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& replace,
               const std::string& file_path));

  // SPDMGetSignedMeasurments in component_integrity.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               SPDMGetSignedMeasurmentsCb&&, const std::string& service,
               const std::string& objpath, const std::string& interf,
               const std::string& replace,
               const std::vector<size_t>& opt_measurement_indexes,
               const std::string& opt_nonce, size_t opt_slot_id));

  // boot time checkpoints in log_service.cpp
  MOCK_METHOD(
      void, PostDbusCallToIoContextThreadSafe,
      (const std::shared_ptr<boost::asio::io_context::strand>&,
       absl::AnyInvocable<void(
           const boost::system::error_code&,
           const std::vector<std::tuple<std::string, int64_t, int64_t>>&)>&&,
       const std::string& service, const std::string& objpath,
       const std::string& interf, const std::string& method));
  // boot time durations in log_service.cpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(
                   const boost::system::error_code&,
                   const std::vector<std::tuple<std::string, int64_t>>&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method));

  // PLDMd reload file and sync cache for VMTPPR in bios.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method,
               uint16_t file_handle));

  // Trigger has a special case for GetAll
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               TriggerGetAllCb&&, const std::string& service,
               const std::string& objpath, const std::string& interf,
               const std::string& get_all, const std::string& interface));

  // setPostPackageRepairConfig in log_service.cpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const bool&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method,
               const std::uint16_t& flag, const bool& data));

  // setPostPackageRepairData in log_service.cpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const bool&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method,
               const uint16_t repairEntryNum, const uint16_t repairType,
               const uint16_t socNum, const std::vector<uint16_t>& payload));

  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const uint32_t&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method,
               const uint16_t Index));

  // nvmeMetricFetcher in nvme_metric_utils.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const sdbusplus::message::unix_fd&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method,
               const std::string& arg));

  // nvmeMetricFetcher in nvme_metric_utils.hpp
  MOCK_METHOD(void, PostDbusCallToIoContextThreadSafe,
              (const std::shared_ptr<boost::asio::io_context::strand>&,
               absl::AnyInvocable<void(const boost::system::error_code&,
                                       const sdbusplus::message_t& msg,
                                       const sdbusplus::message::unix_fd&)>&&,
               const std::string& service, const std::string& objpath,
               const std::string& interf, const std::string& method,
               const std::string& arg));

 private:
  inline static bool KeyAndValueTypeAreCompatible(ManagedType key_type,
                                                  ManagedType value_type) {
    // SubtreePath and AssociatedSubtreePath are equivalent
    // Subtree and AssociatedSubtree are equivalent

    // Only KeyType can have Associated variants
    if (key_type == ManagedType::kManagedAssociatedSubtreePaths &&
        value_type == ManagedType::kManagedSubtreePaths) {
      return true;
    }

    if (key_type == ManagedType::kManagedAssociatedSubtree &&
        value_type == ManagedType::kManagedSubtree) {
      return true;
    }

    return key_type == value_type;
  }
};

// This class is to post SetProperty calls to the io context.
// This is to simulate a successful async dbus call on io context
class SimulateSuccessfulAsyncSetPropertyDbusCallAction {
 public:
  template <typename Result, typename ArgumentTuple>
  Result Perform(const ArgumentTuple& args) const {
    // In SetProperty, callback is the 5th parameter (0 indexed)
    boost::asio::post(managedStore::GetManagedObjectStore()->GetIoContext(),
                      [callback{std::move(std::get<5>(args))}]() mutable {
                        std::move(callback)(boost::system::error_code());
                      });
  }

  inline static testing::PolymorphicAction<
      SimulateSuccessfulAsyncSetPropertyDbusCallAction>
  SimulateSuccessfulAsyncSetPropertyDbusCall() {
    return testing::MakePolymorphicAction(
        SimulateSuccessfulAsyncSetPropertyDbusCallAction());
  }
};

// This class is to post SetProperty calls to the io context.
// This is to simulate a failed async dbus call on io context
class SimulateFailedAsyncSetPropertyDbusCallAction {
  const boost::system::error_code ec_;

 public:
  explicit SimulateFailedAsyncSetPropertyDbusCallAction(
      boost::system::error_code ec)
      : ec_(ec) {}

  template <typename Result, typename ArgumentTuple>
  Result Perform(const ArgumentTuple& args) const {
    // In SetProperty, callback is the 5th parameter (0 indexed)
    boost::asio::post(managedStore::GetManagedObjectStore()->GetIoContext(),
                      [callback{std::move(std::get<5>(args))}, this]() mutable {
                        std::move(callback)(this->ec_);
                      });
  }

  inline static testing::PolymorphicAction<
      SimulateFailedAsyncSetPropertyDbusCallAction>
  SimulateFailedAsyncSetPropertyDbusCall(
      std::optional<boost::system::error_code> ec = std::nullopt) {
    return testing::MakePolymorphicAction(
        SimulateFailedAsyncSetPropertyDbusCallAction(
            ec.value_or(boost::system::errc::make_error_code(
                boost::system::errc::not_connected))));
  }
};

class SimulateSuccessfulAsyncPostDbusCallThreadSafeAction {
 public:
  template <typename Result, typename ArgumentTuple>
  Result Perform(const ArgumentTuple& args) const {
    // In postDbusCallToIoContext, callback is the 0th parameter
    boost::asio::post(managedStore::GetManagedObjectStore()->GetIoContext(),
                      [callback{std::move(std::get<1>(args))}]() mutable {
                        std::move(callback)(boost::system::error_code());
                      });
  }

  inline static testing::PolymorphicAction<
      SimulateSuccessfulAsyncPostDbusCallThreadSafeAction>
  SimulateSuccessfulAsyncPostDbusCall() {
    return testing::MakePolymorphicAction(
        SimulateSuccessfulAsyncPostDbusCallThreadSafeAction());
  }
};

template <typename DbusObjectType>
class SimulateSuccessfulAsyncPostDbusCallThreadSafeWithValueAction {
  const std::shared_ptr<DbusObjectType> dbus_object_;

 public:
  explicit SimulateSuccessfulAsyncPostDbusCallThreadSafeWithValueAction(
      const std::shared_ptr<DbusObjectType> obj)
      : dbus_object_(obj) {}
  template <typename Result, typename ArgumentTuple>
  Result Perform(const ArgumentTuple& args) const {
    // In postDbusCallToIoContext, callback is the 0th parameter
    boost::asio::post(managedStore::GetManagedObjectStore()->GetIoContext(),
                      [callback{std::move(std::get<1>(args))}, this]() mutable {
                        std::move(callback)(boost::system::error_code(),
                                            *(this->dbus_object_));
                      });
  }

  inline static testing::PolymorphicAction<
      SimulateSuccessfulAsyncPostDbusCallThreadSafeWithValueAction>
  SimulateSuccessfulAsyncPostDbusCallWithValue(
      const std::shared_ptr<DbusObjectType> dbusObject) {
    return testing::MakePolymorphicAction(
        SimulateSuccessfulAsyncPostDbusCallThreadSafeWithValueAction(
            dbusObject));
  }
};

class SimulateFailedAsyncPostDbusCallThreadSafeAction {
  const boost::system::error_code ec_;

 public:
  explicit SimulateFailedAsyncPostDbusCallThreadSafeAction(
      boost::system::error_code ec)
      : ec_(ec) {}

  template <typename Result, typename ArgumentTuple>
  Result Perform(const ArgumentTuple& args) const {
    // In postDbusCallToIoContext, callback is the 0th parameter
    boost::asio::post(managedStore::GetManagedObjectStore()->GetIoContext(),
                      [callback{std::move(std::get<1>(args))}, this]() mutable {
                        std::move(callback)(this->ec_);
                      });
  }

  inline static testing::PolymorphicAction<
      SimulateFailedAsyncPostDbusCallThreadSafeAction>
  SimulateFailedAsyncPostDbusCall(
      std::optional<boost::system::error_code> ec = std::nullopt) {
    return testing::MakePolymorphicAction(
        SimulateFailedAsyncPostDbusCallThreadSafeAction(
            ec.value_or(boost::system::errc::make_error_code(
                boost::system::errc::not_connected))));
  }
};

class SimulateFailedAsyncPostDbusCallThreadSafeWithEmptyValueAction {
 private:
  const boost::system::error_code ec_;

 public:
  explicit SimulateFailedAsyncPostDbusCallThreadSafeWithEmptyValueAction(
      const boost::system::error_code ec)
      : ec_(ec) {}
  template <typename Result, typename ArgumentTuple>
  Result Perform(const ArgumentTuple& args) const {
    // In postDbusCallToIoContext, callback is the 0th parameter
    boost::asio::post(managedStore::GetManagedObjectStore()->GetIoContext(),
                      [callback{std::move(std::get<1>(args))}, this]() mutable {
                        std::move(callback)(this->ec_, {});
                      });
  }

  inline static testing::PolymorphicAction<
      SimulateFailedAsyncPostDbusCallThreadSafeWithEmptyValueAction>
  SimulateFailedAsyncPostDbusCallWithEmptyValue(
      std::optional<boost::system::error_code> ec = std::nullopt) {
    return testing::MakePolymorphicAction(
        SimulateFailedAsyncPostDbusCallThreadSafeWithEmptyValueAction(
            ec.value_or(boost::system::errc::make_error_code(
                boost::system::errc::not_connected))));
  }
};

class SimulateFailedAsyncPostDbusCallThreadSafeWithMsgAndEmptyValueAction {
 private:
  const boost::system::error_code ec_;
  const sdbusplus::message_t& msg_;

 public:
  explicit SimulateFailedAsyncPostDbusCallThreadSafeWithMsgAndEmptyValueAction(
      const boost::system::error_code ec, const sdbusplus::message_t& msg)
      : ec_(ec), msg_(msg) {}
  template <typename Result, typename ArgumentTuple>
  Result Perform(const ArgumentTuple& args) const {
    // In postDbusCallToIoContext, callback is the 0th parameter
    boost::asio::post(managedStore::GetManagedObjectStore()->GetIoContext(),
                      [callback{std::move(std::get<1>(args))}, this]() mutable {
                        std::move(callback)(this->ec_, this->msg_, {});
                      });
  }

  inline static testing::PolymorphicAction<
      SimulateFailedAsyncPostDbusCallThreadSafeWithMsgAndEmptyValueAction>
  SimulateFailedAsyncPostDbusCallWithMsgAndEmptyValue(
      const sdbusplus::message_t& msg,
      std::optional<boost::system::error_code> ec = std::nullopt) {
    return testing::MakePolymorphicAction(
        SimulateFailedAsyncPostDbusCallThreadSafeWithMsgAndEmptyValueAction(
            ec.value_or(boost::system::errc::make_error_code(
                boost::system::errc::not_connected)),
            msg));
  }
};

}  // namespace managedStore

#pragma GCC diagnostic pop

#endif  // THIRD_PARTY_MILOTIC_INTERNAL_CC_BMCWEB_MOCK_MANAGED_STORE_H_
