#include "bmcweb_config.h"

#include "app.hpp"
#include "async_resp.hpp"
#include "http_response.hpp"
#include "nlohmann/json.hpp"
#include "test/g3/mock_managed_store.hpp"
#include "test/g3/mock_managed_store_test.hpp"

#include <memory>
#include <vector>

#include <gmock/gmock.h> // IWYU pragma: keep
#include <gtest/gtest.h> // IWYU pragma: keep

// IWYU pragma: no_include <gtest/gtest-message.h>
// IWYU pragma: no_include <gtest/gtest-test-part.h>
// IWYU pragma: no_include "gtest/gtest_pred_impl.h"
// IWYU pragma: no_include <gmock/gmock-matchers.h>
// IWYU pragma: no_include <gtest/gtest-matchers.h>

namespace redfish
{

class SnapshotFixture : public ::managedStore::MockManagedStoreTest
{
  protected:
    SnapshotFixture() : app_(false)
    {
        share_async_resp_ = std::make_shared<bmcweb::AsyncResp>();
    };

    static void SetUpTestSuite()
    {
        // Have to manually call this as defining this current function prevents
        // its parent's Setup from being called
        ::managedStore::MockManagedStoreTest::SetUpTestSuite();
        EXPECT_TRUE(managedStore::GetManagedObjectStore()->deserialize(
            snapshotFilepath));
    }
    // Use this to create a crow request for use in handlers
    static crow::Request CreateRequest(const std::string& reqIn = "")
    {
        // Dont need this error code ever
        std::error_code ec;
        return {reqIn, ec};
    }
    std::shared_ptr<bmcweb::AsyncResp> share_async_resp_;
    App app_;
};

class SnapshotFixture_Platform22 : public ::managedStore::MockManagedStoreTest
{
  protected:
    SnapshotFixture_Platform22() : app_(false)
    {
        share_async_resp_ = std::make_shared<bmcweb::AsyncResp>();
    };

    static void SetUpTestSuite()
    {
        // Have to manually call this as defining this current function prevents
        // its parent's Setup from being called
        ::managedStore::MockManagedStoreTest::SetUpTestSuite();
        EXPECT_TRUE(managedStore::GetManagedObjectStore()->deserialize(
            snapshotFilepath_platform22));
    }
    // Use this to create a crow request for use in handlers
    static crow::Request CreateRequest(const std::string& reqIn = "")
    {
        // Dont need this error code ever
        std::error_code ec;
        return {reqIn, ec};
    }
    std::shared_ptr<bmcweb::AsyncResp> share_async_resp_;
    App app_;
};

class SnapshotFixture_Platform23 : public ::managedStore::MockManagedStoreTest
{
  protected:
    SnapshotFixture_Platform23() : app_(false)
    {
        share_async_resp_ = std::make_shared<bmcweb::AsyncResp>();
    };

    static void SetUpTestSuite()
    {
        // Have to manually call this as defining this current function prevents
        // its parent's Setup from being called
        ::managedStore::MockManagedStoreTest::SetUpTestSuite();
        EXPECT_TRUE(managedStore::GetManagedObjectStore()->deserialize(
            snapshotFilepath_platform23));
    }
    // Use this to create a crow request for use in handlers
    static crow::Request CreateRequest(const std::string& reqIn = "")
    {
        // Dont need this error code ever
        std::error_code ec;
        return {reqIn, ec};
    }
    std::shared_ptr<bmcweb::AsyncResp> share_async_resp_;
    App app_;
};

class SnapshotFixture_Platform11_Config4 :
    public ::managedStore::MockManagedStoreTest
{
  protected:
    SnapshotFixture_Platform11_Config4() : app_(false)
    {
        share_async_resp_ = std::make_shared<bmcweb::AsyncResp>();
    };

    static void SetUpTestSuite()
    {
        // Have to manually call this as defining this current function prevents
        // its parent's Setup from being called
        ::managedStore::MockManagedStoreTest::SetUpTestSuite();
        EXPECT_TRUE(managedStore::GetManagedObjectStore()->deserialize(
            snapshotFilepath_platform11_config4));
    }
    // Use this to create a crow request for use in handlers
    static crow::Request CreateRequest(const std::string& reqIn = "")
    {
        // Dont need this error code ever
        std::error_code ec;
        return {reqIn, ec};
    }
    std::shared_ptr<bmcweb::AsyncResp> share_async_resp_;
    App app_;
};

class SnapshotFixture_Platform5_Config7 :
    public ::managedStore::MockManagedStoreTest
{
  protected:
    SnapshotFixture_Platform5_Config7() : app_(false)
    {
        share_async_resp_ = std::make_shared<bmcweb::AsyncResp>();
    };

    static void SetUpTestSuite()
    {
        // Have to manually call this as defining this current function prevents
        // its parent's Setup from being called
        ::managedStore::MockManagedStoreTest::SetUpTestSuite();
        EXPECT_TRUE(managedStore::GetManagedObjectStore()->deserialize(
            snapshotFilepath_platform5_config7));
    }
    // Use this to create a crow request for use in handlers
    static crow::Request CreateRequest(const std::string& reqIn = "")
    {
        // Dont need this error code ever
        std::error_code ec;
        return {reqIn, ec};
    }
    std::shared_ptr<bmcweb::AsyncResp> share_async_resp_;
    App app_;
};

class SnapshotFixture_Platform5_Config0 : public ::managedStore::MockManagedStoreTest
{
 protected:
   SnapshotFixture_Platform5_Config0() : app_(false) {
       share_async_resp_ = std::make_shared<bmcweb::AsyncResp>();
   };

   static void SetUpTestSuite()
   {
    // Have to manually call this as defining this current function prevents its parent's Setup from being called
       ::managedStore::MockManagedStoreTest::SetUpTestSuite();
       EXPECT_TRUE(managedStore::GetManagedObjectStore()->deserialize(snapshotFilepath_platform5_config0));
   }
   // Use this to create a crow request for use in handlers
   static crow::Request CreateRequest(const std::string& reqIn = ""){
      // Dont need this error code ever
      std::error_code ec;
      return {reqIn, ec};
   }
   std::shared_ptr<bmcweb::AsyncResp> share_async_resp_;
   App app_;
};
} // namespace redfish
