#include "absl/cleanup/cleanup.h"
#include "app.hpp"
#include "bmcweb_config.h"

#include "async_resp.hpp"
#include "http_response.hpp"
#include "nlohmann/json.hpp"
#include "systems.hpp"
#include "snapshot_fixture.hpp"
#include "dbus_utility.hpp"

#include <fstream>
#include <ios>
#include <memory>
#include <vector>
#include <string>
#include <sstream>
#include <iomanip>

#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
{
namespace
{

using ::dbus::utility::DbusVariantType;
using ::managedStore::KeyType;
using ::managedStore::ManagedObjectStoreContext;
using ::managedStore::ManagedType;
using ::managedStore::SimulateFailedAsyncPostDbusCallThreadSafeAction;
using ::managedStore::SimulateSuccessfulAsyncPostDbusCallThreadSafeAction;
using ::managedStore::ValueType;
using ::testing::An;
using ::testing::_;

TEST(HandlerSystemTest, VerifyCreateResetActionInfoResponse)
{
    auto shareAsyncResp = std::make_shared<bmcweb::AsyncResp>();

    createResetActionInfoResponse(shareAsyncResp, "test");
    nlohmann::json& json = shareAsyncResp->res.jsonValue;
    EXPECT_EQ(json["@odata.id"], "/redfish/v1/Systems/test/ResetActionInfo");
    EXPECT_EQ(json["@odata.type"], "#ActionInfo.v1_1_2.ActionInfo");
    EXPECT_EQ(json["Name"], "Reset Action Info");
    EXPECT_EQ(json["Id"], "ResetActionInfo");

    nlohmann::json::array_t parameters;
    nlohmann::json::object_t parameter;

    parameter["Name"] = "ResetType";
    parameter["Required"] = true;
    parameter["DataType"] = "String";
    parameter["Delay"] = "Number";
    nlohmann::json::array_t allowableValues;
    allowableValues.emplace_back("On");
    allowableValues.emplace_back("ForceOff");
    allowableValues.emplace_back("ForceOn");
    allowableValues.emplace_back("ForceRestart");
    allowableValues.emplace_back("GracefulRestart");
    allowableValues.emplace_back("GracefulShutdown");
    allowableValues.emplace_back("PowerCycle");
    allowableValues.emplace_back("Nmi");
    allowableValues.emplace_back("ReallyGracefulShutDownTechDebt");
    parameter["AllowableValues"] = std::move(allowableValues);
    parameters.emplace_back(std::move(parameter));

    nlohmann::json::object_t delayParameter;
    delayParameter["Name"] = "Delay";
    delayParameter["Required"] = false;
    delayParameter["DataType"] = "Number";
    parameters.emplace_back(std::move(delayParameter));
    EXPECT_EQ(json["Parameters"], parameters);
}

TEST(GetSystemResetCommandFromInputTest, TestOnAndForceOnReturnCorrectly)
{
    SystemResetCommand systemResetCommandOn = GetSystemResetCommandFromInput("On");
    EXPECT_EQ(systemResetCommandOn.command, "xyz.openbmc_project.State.Host.Transition.On");
    EXPECT_TRUE(systemResetCommandOn.hostCommand);
    EXPECT_TRUE(systemResetCommandOn.validCommand);

    SystemResetCommand systemResetCommandForceOn = GetSystemResetCommandFromInput("ForceOn");
    EXPECT_EQ(systemResetCommandForceOn.command, "xyz.openbmc_project.State.Host.Transition.On");
    EXPECT_TRUE(systemResetCommandForceOn.hostCommand);
    EXPECT_TRUE(systemResetCommandForceOn.validCommand);
}

TEST(GetSystemResetCommandFromInputTest, TestForceOffReturnCorrectly)
{
    SystemResetCommand systemResetCommandOn = GetSystemResetCommandFromInput("ForceOff");
    EXPECT_EQ(systemResetCommandOn.command, "xyz.openbmc_project.State.Chassis.Transition.Off");
    EXPECT_FALSE(systemResetCommandOn.hostCommand);
    EXPECT_TRUE(systemResetCommandOn.validCommand);
}

TEST(GetSystemResetCommandFromInputTest, TestForceRestartReturnCorrectly)
{
    SystemResetCommand systemResetCommandOn = GetSystemResetCommandFromInput("ForceRestart");
    EXPECT_EQ(systemResetCommandOn.command, "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot");
    EXPECT_TRUE(systemResetCommandOn.hostCommand);
    EXPECT_TRUE(systemResetCommandOn.validCommand);
}

TEST(GetSystemResetCommandFromInputTest, TestGracefulShutdownReturnCorrectly)
{
    SystemResetCommand systemResetCommandOn = GetSystemResetCommandFromInput("GracefulShutdown");
    EXPECT_EQ(systemResetCommandOn.command, "xyz.openbmc_project.State.Host.Transition.Off");
    EXPECT_TRUE(systemResetCommandOn.hostCommand);
    EXPECT_TRUE(systemResetCommandOn.validCommand);
}

TEST(GetSystemResetCommandFromInputTest, TestGracefulRestartReturnCorrectly)
{
    SystemResetCommand systemResetCommandOn = GetSystemResetCommandFromInput("GracefulRestart");
    EXPECT_EQ(systemResetCommandOn.command, "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot");
    EXPECT_TRUE(systemResetCommandOn.hostCommand);
    EXPECT_TRUE(systemResetCommandOn.validCommand);
}

TEST(GetSystemResetCommandFromInputTest, TestPowerCycleReturnCorrectly)
{
    SystemResetCommand systemResetCommandOn = GetSystemResetCommandFromInput("PowerCycle");
    EXPECT_EQ(systemResetCommandOn.command, "xyz.openbmc_project.State.Host.Transition.Reboot");
    EXPECT_TRUE(systemResetCommandOn.hostCommand);
    EXPECT_TRUE(systemResetCommandOn.validCommand);
}

TEST(GetSystemResetCommandFromInputTest, TestReallyGracefulShutDownTechDebtReturnCorrectly)
{
    SystemResetCommand systemResetCommandOn = GetSystemResetCommandFromInput("ReallyGracefulShutDownTechDebt");
    EXPECT_EQ(systemResetCommandOn.command, "xyz.openbmc_project.State.Host.Transition.ReallyGracefulShutDown");
    EXPECT_TRUE(systemResetCommandOn.hostCommand);
    EXPECT_TRUE(systemResetCommandOn.validCommand);
}

TEST(GetSystemResetCommandFromInputTest, TestInvalidInput)
{
    SystemResetCommand systemResetCommandOn = GetSystemResetCommandFromInput("SomeInvalidInput");
    EXPECT_FALSE(systemResetCommandOn.validCommand);
}

TEST(GetSystemSuffixHelperTest, TestAllInputs)
{
    // Empty, invalid strings
    EXPECT_EQ("", getSystemSuffix(""));
    EXPECT_EQ("", getSystemSuffix("asdf"));
    EXPECT_EQ("", getSystemSuffix("syste"));
    // Valid Systems/
    EXPECT_EQ("", getSystemSuffix("system"));
    EXPECT_EQ("1", getSystemSuffix("system1"));
    EXPECT_EQ("13", getSystemSuffix("system13"));
    EXPECT_EQ("FUTURE", getSystemSuffix("systemFUTURE"));
}

TEST(HandlerSystemTest, HelpersValuesEnable)
{
    auto shareAsyncResp = std::make_shared<bmcweb::AsyncResp>();
    nlohmann::json& json = shareAsyncResp->res.jsonValue;

    json["MemorySummary"]["Status"]["State"] = "Disabled";
    json["ProcessorSummary"]["Count"] = 1;
    json["ProcessorSummary"]["Status"]["State"] = "Disabled";

    updateDimmProperties(shareAsyncResp, true);
    modifyCpuPresenceState(shareAsyncResp, true);
    modifyCpuFunctionalState(shareAsyncResp, true);

    EXPECT_EQ(json["MemorySummary"]["Status"]["State"], "Enabled");
    EXPECT_EQ(json["ProcessorSummary"]["Count"], 2);
    EXPECT_EQ(json["ProcessorSummary"]["Status"]["State"], "Enabled");
}

TEST_F(SnapshotFixture, PostSystemResetAsNMIOnDBusCallFailed){
    EXPECT_CALL(*managedStore::GetManagedObjectStore(),
                PostDbusCallToIoContextThreadSafe(_, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(),
                "xyz.openbmc_project.Control.Host.NMI", "/xyz/openbmc_project/control/host0/nmi",
                "xyz.openbmc_project.Control.Host.NMI", "NMI"))
        .Times(1)
        .WillOnce(SimulateFailedAsyncPostDbusCallThreadSafeAction::
                    SimulateFailedAsyncPostDbusCall());

    handlePostComputerSystemReset(app_, CreateRequest("{\"ResetType\":\"Nmi\"}"), share_async_resp_, "system");

    RunIoUntilDone();

    EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::internal_server_error);
}

TEST_F(SnapshotFixture, PostSystemResetAsNMIOnDBusCallSuccess){
    EXPECT_CALL(*managedStore::GetManagedObjectStore(),
                PostDbusCallToIoContextThreadSafe(_, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(),
                "xyz.openbmc_project.Control.Host.NMI", "/xyz/openbmc_project/control/host0/nmi",
                "xyz.openbmc_project.Control.Host.NMI", "NMI"))
        .Times(1)
        .WillOnce(SimulateSuccessfulAsyncPostDbusCallThreadSafeAction::
                    SimulateSuccessfulAsyncPostDbusCall());

    handlePostComputerSystemReset(app_, CreateRequest("{\"ResetType\":\"Nmi\"}"), share_async_resp_, "system");

    RunIoUntilDone();

    EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(SnapshotFixture, PostSystemResetSingleSystemHostResetOnFail){
    EXPECT_CALL(*managedStore::GetManagedObjectStore(),
                PostDbusCallToIoContextThreadSafe(_, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(),
                "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
                "org.freedesktop.DBus.Properties", "Set", "xyz.openbmc_project.State.Host", "RequestedHostTransition",
                dbus::utility::DbusVariantType("xyz.openbmc_project.State.Host.Transition.On")))
        .Times(1)
        .WillOnce(SimulateFailedAsyncPostDbusCallThreadSafeAction::
                    SimulateFailedAsyncPostDbusCall());

    handlePostComputerSystemReset(app_, CreateRequest("{\"ResetType\":\"ForceOn\"}"), share_async_resp_, "system");

    RunIoUntilDone();

    EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::internal_server_error);
}

TEST_F(SnapshotFixture, PostSystemResetSingleSystemHostResetOnSuccess){
    EXPECT_CALL(*managedStore::GetManagedObjectStore(),
                PostDbusCallToIoContextThreadSafe(_, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(),
                "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
                "org.freedesktop.DBus.Properties", "Set", "xyz.openbmc_project.State.Host", "RequestedHostTransition",
                dbus::utility::DbusVariantType("xyz.openbmc_project.State.Host.Transition.On")))
        .Times(1)
        .WillOnce(SimulateSuccessfulAsyncPostDbusCallThreadSafeAction::
                    SimulateSuccessfulAsyncPostDbusCall());

    handlePostComputerSystemReset(app_, CreateRequest("{\"ResetType\":\"ForceOn\"}"), share_async_resp_, "system");

    RunIoUntilDone();

    EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(SnapshotFixture, PostSystemResetSingleSystemChassisResetOnFail){
    EXPECT_CALL(*managedStore::GetManagedObjectStore(),
                PostDbusCallToIoContextThreadSafe(_, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(),
                "xyz.openbmc_project.State.Chassis", "/xyz/openbmc_project/state/chassis0",
                "org.freedesktop.DBus.Properties", "Set", "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
                dbus::utility::DbusVariantType("xyz.openbmc_project.State.Chassis.Transition.Off")))
        .Times(1)
        .WillOnce(SimulateFailedAsyncPostDbusCallThreadSafeAction::
                    SimulateFailedAsyncPostDbusCall());

    handlePostComputerSystemReset(app_, CreateRequest("{\"ResetType\":\"ForceOff\"}"), share_async_resp_, "system");

    RunIoUntilDone();

    EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::internal_server_error);
}

TEST_F(SnapshotFixture, PostSystemResetSingleSystemChassisResetOnSuccess){
    EXPECT_CALL(*managedStore::GetManagedObjectStore(),
                PostDbusCallToIoContextThreadSafe(_, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(),
                "xyz.openbmc_project.State.Chassis", "/xyz/openbmc_project/state/chassis0",
                "org.freedesktop.DBus.Properties", "Set", "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
                dbus::utility::DbusVariantType("xyz.openbmc_project.State.Chassis.Transition.Off")))
        .Times(1)
        .WillOnce(SimulateSuccessfulAsyncPostDbusCallThreadSafeAction::
                    SimulateSuccessfulAsyncPostDbusCall());

    handlePostComputerSystemReset(app_, CreateRequest("{\"ResetType\":\"ForceOff\"}"), share_async_resp_, "system");

    RunIoUntilDone();

    EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(SnapshotFixture, CheckComputerSystemHostStateSingleHost)
{
    KeyType key(
        ManagedType::kManagedProperty, "xyz.openbmc_project.State.Host",
        sdbusplus::message::object_path("/xyz/openbmc_project/state/host0"),
        "xyz.openbmc_project.State.Host", "CurrentHostState");
    const std::array<std::tuple<std::string, std::string, std::string>, 6>
        testCases{
            {{"xyz.openbmc_project.State.Host.HostState.Running", "On",
              "Enabled"},
             {"xyz.openbmc_project.State.Host.HostState.Quiesced", "On",
              "Quiesced"},
             {"xyz.openbmc_project.State.Host.HostState.DiagnosticMode", "On",
              "InTest"},
             {"xyz.openbmc_project.State.Host.HostState.TransitioningToRunning",
              "PoweringOn", "Starting"},
             {"xyz.openbmc_project.State.Host.HostState.TransitioningToOff",
              "PoweringOff", "Disabled"},
             {"xyz.openbmc_project.State.Host.HostState.OtherDummy", "Off",
              "Disabled"}}};
    for (auto testCase : testCases)
    {
        const auto [currentHostState, powerState, status] = testCase;
        DbusVariantType targetState = currentHostState;
        std::shared_ptr<ValueType> mockHostStateValue =
            managedStore::MockManagedStoreTest::CreateValueType(
                std::move(targetState));
        ASSERT_TRUE(
            managedStore::GetManagedObjectStore()
                ->upsertMockObjectIntoManagedStore(key, mockHostStateValue)
                .ok());
        handleComputerSystem(share_async_resp_, "", "system", false);

        RunIoUntilDone();

        nlohmann::json& json = share_async_resp_->res.jsonValue;
        EXPECT_TRUE(json.contains("PowerState"));
        EXPECT_TRUE(json.contains("Status"));
        EXPECT_EQ(json["PowerState"], powerState);
        EXPECT_TRUE(json["Status"].contains("State"));
        EXPECT_EQ(json["Status"]["State"], status);
    }
}

TEST_F(SnapshotFixture, GetSystemHostPowerAssociatedSubTreeFailed)
{
    // Looking for
    // kManagedAssociatedSubtree|/xyz/openbmc_project/state|0|xyz.openbmc_project.State.Host|/host_power
    KeyType key(ManagedType::kManagedAssociatedSubtree, "/host_power",
                "/xyz/openbmc_project/state", 0,
                {"xyz.openbmc_project.State.Host"});

    absl::StatusOr<std::shared_ptr<ValueType>>
        associatedSubtreeObjectsStatusOr =
            managedStore::GetManagedObjectStore()
                ->getMockObjectFromManagedStore(key);
    ASSERT_TRUE(associatedSubtreeObjectsStatusOr.ok());

    // TODO(b/416746677): Uncomment after the bug is fixed
    // ASSERT_EQ(associatedSubtreeObjectsStatusOr.value()->managedType,
    //           ManagedType::kManagedSubtreePaths);

    std::optional<dbus::utility::MapperGetSubTreeResponse>
        originalAssociatedSubtree =
            associatedSubtreeObjectsStatusOr.value()->managedSubtree;

    ASSERT_TRUE(originalAssociatedSubtree.has_value());

    ASSERT_TRUE(
        managedStore::GetManagedObjectStore()
            ->upsertMockObjectIntoManagedStore(
                key, managedStore::MockManagedStoreTest::CreateErrorValueType(
                         originalAssociatedSubtree.value(),
                         boost::system::errc::make_error_code(
                             boost::system::errc::io_error)))
            .ok());

    absl::Cleanup mockManagedStoreResetter = [key,
                                              originalAssociatedSubtree]() {
        ASSERT_TRUE(
            managedStore::GetManagedObjectStore()
                ->upsertMockObjectIntoManagedStore(
                    key, managedStore::MockManagedStoreTest::CreateValueType(
                             originalAssociatedSubtree.value()))
                .ok());
    };

    handleComputerSystem(share_async_resp_, "", "system", false);

    RunIoUntilDone();

    EXPECT_EQ(share_async_resp_->res.result(),
              boost::beast::http::status::internal_server_error);
}

std::shared_ptr<ValueType> CreateMockAssociatedSubtree()
{
    dbus::utility::MapperGetSubTreeResponse mockAssociatedSubtree = {
        std::make_pair(
            "/xyz/openbmc_project/state/host1",
            dbus::utility::MapperServiceMap{
                {std::make_pair(
                    "xyz.openbmc_project.Chassis.Buttons1",
                    std::vector<std::string>{
                        "org.freedesktop.DBus.Introspectable",
                        "org.freedesktop.DBus.Peer",
                        "org.freedesktop.DBus.Properties",
                        "xyz.openbmc_project.State.Host",
                                }),
                 std::make_pair(
                     "xyz.openbmc_project.Control.Host.RestartCause1",
                     std::vector<std::string>{
                         "org.freedesktop.DBus.Introspectable",
                         "org.freedesktop.DBus.Peer",
                         "org.freedesktop.DBus.Properties",
                         "xyz.openbmc_project.State.Host",
                     })}}),
        std::make_pair(
            "/xyz/openbmc_project/state/host2",
            dbus::utility::MapperServiceMap{
                {std::make_pair(
                    "xyz.openbmc_project.Chassis.Buttons1",
                    std::vector<std::string>{
                        "org.freedesktop.DBus.Introspectable",
                        "org.freedesktop.DBus.Peer",
                        "org.freedesktop.DBus.Properties",
                        "xyz.openbmc_project.State.Host",
                    }),
                 std::make_pair(
                     "xyz.openbmc_project.Control.Host.RestartCause1",
                     std::vector<std::string>{
                         "org.freedesktop.DBus.Introspectable",
                         "org.freedesktop.DBus.Peer",
                         "org.freedesktop.DBus.Properties",
                         "xyz.openbmc_project.State.Host",
                     })}}),
    };
    return managedStore::MockManagedStoreTest::CreateValueType(
        std::move(mockAssociatedSubtree));
}

TEST_F(SnapshotFixture,
       GetSystemHostPowerAssociatedSubTreeHasMoreThanOneObjects)
{
    crow::Logger::setLogLevel(crow::LogLevel::Error);
    // Looking for
    // kManagedAssociatedSubtree|/xyz/openbmc_project/state|0|xyz.openbmc_project.State.Host|/host_power
    KeyType key(ManagedType::kManagedAssociatedSubtree, "/host_power",
                "/xyz/openbmc_project/state", 0,
                {"xyz.openbmc_project.State.Host"});

    absl::StatusOr<std::shared_ptr<ValueType>>
        associatedSubtreeObjectsStatusOr =
            managedStore::GetManagedObjectStore()
                ->getMockObjectFromManagedStore(key);
    ASSERT_TRUE(associatedSubtreeObjectsStatusOr.ok());

    // TODO(b/416746677): Uncomment after the bug is fixed
    // ASSERT_EQ(associatedSubtreeObjectsStatusOr.value()->managedType,
    //           ManagedType::kManagedSubtreePaths);

    std::optional<dbus::utility::MapperGetSubTreeResponse>
        originalAssociatedSubtree =
            associatedSubtreeObjectsStatusOr.value()->managedSubtree;

    ASSERT_TRUE(originalAssociatedSubtree.has_value());

    ASSERT_TRUE(managedStore::GetManagedObjectStore()
                    ->upsertMockObjectIntoManagedStore(
                        key, CreateMockAssociatedSubtree())
                    .ok());

    absl::Cleanup mockManagedStoreResetter = [key,
                                              originalAssociatedSubtree]() {
        ASSERT_TRUE(
            managedStore::GetManagedObjectStore()
                ->upsertMockObjectIntoManagedStore(
                    key, managedStore::MockManagedStoreTest::CreateValueType(
                             originalAssociatedSubtree.value()))
                .ok());
    };

    handleComputerSystem(share_async_resp_, "", "system", false);

    RunIoUntilDone();

    EXPECT_EQ(share_async_resp_->res.result(),
              boost::beast::http::status::internal_server_error);
}

TEST_F(SnapshotFixture, PostSystemResetSingleSystemChassisResetOnSuccessDelay){
    handlePostComputerSystemReset(app_, CreateRequest("{\"ResetType\":\"ForceOff\", \"Delay\":1} "), share_async_resp_, "system");

    RunIoUntilDone();

    EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
    EXPECT_EQ(share_async_resp_->res.jsonValue["ResetString"],
         "systemd-run --on-active=1 --timer-property=AccuracySec=100ms -- "
         "curl -d {\"ResetType\":\"ForceOff\"} -H Content-Type: application/json "
         "-X POST localhost:80/redfish/v1/Systems/system/Actions/ComputerSystem.Reset");
}

TEST_F(SnapshotFixture, PostSystemResetSingleSystemChassisResetOnFailTimeDelay){
    handlePostComputerSystemReset(app_, CreateRequest("{\"ResetType\":\"ForceOff\", \"Delay\":901} "), share_async_resp_, "system");

    RunIoUntilDone();

    EXPECT_EQ(share_async_resp_->res.result(),boost::beast::http::status::bad_request);
}

TEST_F(SnapshotFixture, PostSystemResetSingleSystemChassisResetOnFailTypeDelay){
    handlePostComputerSystemReset(app_, CreateRequest("{\"ResetType\":\"PleaseReset\", \"Delay\":1} "), share_async_resp_, "system");

    RunIoUntilDone();

    EXPECT_EQ(share_async_resp_->res.result(),boost::beast::http::status::bad_request);
}

TEST_F(SnapshotFixture, HandleGetSystemBootGuestOSInfo)
{
    handleGetSystemBootGuestOSInfo(app_, CreateRequest(""), share_async_resp_,
                                   "system2");
    RunIoUntilDone();

    nlohmann::json& json = share_async_resp_->res.jsonValue;
    EXPECT_EQ(json["@odata.id"],
              "/redfish/v1/System/system2/Oem/Google/BootGuestOSActionInfo");
}

TEST_F(SnapshotFixture, handleGetBareMetalInstanceBase)
{
    handleGetBareMetalInstance(app_, CreateRequest(""), share_async_resp_,
                               "system1");
    RunIoUntilDone();

    nlohmann::json& json = share_async_resp_->res.jsonValue;
    EXPECT_EQ(json["@odata.id"],
              "/redfish/v1/Systems/system1/Oem/Google/BareMetalInstance");
    EXPECT_EQ(json["@odata.type"],
              "#GoogleBareMetalInstance.v1_0_0.GoogleBareMetalInstance");
}

TEST_F(SnapshotFixture, HandleGetBootNumber)
{
    const std::string bootCountPath =
        "/xyz/openbmc_project/inventory/system";
    KeyType key(ManagedType::kManagedProperty,
        "xyz.openbmc_project.Smbios.MDR_V2",
        sdbusplus::message::object_path("/xyz/openbmc_project/inventory/system/chassis/motherboard/bios"),
        "xyz.openbmc_project.State.Host", "BootCount");

    uint32_t num = 1000;
    std::shared_ptr<ValueType> bootCountValue =
                managedStore::MockManagedStoreTest::CreateValueType(
                    std::move(num)
                );
    ASSERT_TRUE(
        managedStore::GetManagedObjectStore()
            ->upsertMockObjectIntoManagedStore(
                key, bootCountValue)
            .ok());

    handleGetBootNumber(app_, CreateRequest(""), share_async_resp_,
                            "system");
    RunIoUntilDone();

    nlohmann::json& json = share_async_resp_->res.jsonValue;
    EXPECT_EQ(json["@odata.id"],
              "/redfish/v1/Systems/system/Oem/Google/BootNumber");
    EXPECT_EQ(json["@odata.type"],
              "#GoogleBootNumber.v1_0_0.GoogleBootNumber");
    EXPECT_TRUE(json.contains("BootNumber"));
    EXPECT_EQ(json["BootNumber"], 1000);
}

TEST(SystemsTest, SetAndGetBootOrder)
{
    const std::string biosSettingFile = "/tmp/oem_bios_setting.test";
    // Ensure file is removed before and after test
    std::remove(biosSettingFile.c_str());
    auto cleanup = absl::MakeCleanup([&]() {
        std::remove(biosSettingFile.c_str());
    });

    auto asyncResp = std::make_shared<bmcweb::AsyncResp>();

    // Test setting the boot order
    std::vector<std::string> bootOrderToWrite = {"Boot0001", "Boot0000", "Boot0028"};
    setBootOrder(asyncResp, bootOrderToWrite, biosSettingFile);

    // Verify the file content
    std::ifstream fileIn(biosSettingFile, std::ios::binary);
    ASSERT_TRUE(fileIn.is_open());

    std::vector<uint16_t> bootIndices;
    uint16_t index;
    while (fileIn.read(reinterpret_cast<char*>(&index), sizeof(index)))
    {
        bootIndices.push_back(index);
    }
    fileIn.close();

    ASSERT_EQ(bootIndices.size(), 3);
    EXPECT_EQ(bootIndices[0], 1);
    EXPECT_EQ(bootIndices[1], 0);
    EXPECT_EQ(bootIndices[2], 0x28);

    // Test getting the boot order
    asyncResp->res.clear();
    getBootOrder(asyncResp, biosSettingFile);

    EXPECT_EQ(asyncResp->res.jsonValue["Boot"]["BootOrder"], bootOrderToWrite);
}

TEST(SystemsTest, SetAndGetBootOrderHex)
{
    const std::string biosSettingFile = "/tmp/oem_bios_setting.test";
    // Ensure file is removed before and after test
    std::remove(biosSettingFile.c_str());
    auto cleanup = absl::MakeCleanup([&]() {
        std::remove(biosSettingFile.c_str());
    });

    auto asyncResp = std::make_shared<bmcweb::AsyncResp>();

    // Test setting the boot order
    std::vector<std::string> bootOrderToWrite = {"Boot0001", "Boot0000",
                                                 "BootFFFE"};
    setBootOrder(asyncResp, bootOrderToWrite, biosSettingFile);

    // Verify the file content
    std::ifstream fileIn(biosSettingFile, std::ios::binary);
    ASSERT_TRUE(fileIn.is_open());

    std::vector<uint16_t> bootIndices;
    uint16_t index;
    while (fileIn.read(reinterpret_cast<char*>(&index), sizeof(index)))
    {
        bootIndices.push_back(index);
    }
    fileIn.close();

    ASSERT_EQ(bootIndices.size(), 3);
    EXPECT_EQ(bootIndices[0], 1);
    EXPECT_EQ(bootIndices[1], 0);
    EXPECT_EQ(bootIndices[2], 0xFFFE);

    // Test getting the boot order
    asyncResp->res.clear();
    getBootOrder(asyncResp, biosSettingFile);

    EXPECT_EQ(asyncResp->res.jsonValue["Boot"]["BootOrder"], bootOrderToWrite);
}

TEST(SystemsTest, SetBootOrderInvalidFormat)
{
    const std::string biosSettingFile = "/tmp/oem_bios_setting.test";
    std::remove(biosSettingFile.c_str());
    auto cleanup = absl::MakeCleanup([&]() {
        std::remove(biosSettingFile.c_str());
    });

    auto asyncResp = std::make_shared<bmcweb::AsyncResp>();

    std::vector<std::string> bootOrderToWrite = {"InvalidBoot0001"};
    setBootOrder(asyncResp, bootOrderToWrite, biosSettingFile);

    // Expect an error message
    EXPECT_EQ(asyncResp->res.result(), boost::beast::http::status::bad_request);

    // File should not have been created or should be empty
    std::ifstream fileIn(biosSettingFile, std::ios::binary | std::ios::ate);
    EXPECT_TRUE(!fileIn.is_open() || fileIn.tellg() == 0);
}

TEST(SystemsTest, SetBootOrderIndexOutOfRange)
{
    const std::string biosSettingFile = "/tmp/oem_bios_setting.test";
    std::remove(biosSettingFile.c_str());
    auto cleanup = absl::MakeCleanup([&]() {
        std::remove(biosSettingFile.c_str());
    });

    auto asyncResp = std::make_shared<bmcweb::AsyncResp>();

    std::vector<std::string> bootOrderToWrite = {"Boot99999"};
    setBootOrder(asyncResp, bootOrderToWrite, biosSettingFile);

    // Expect an error message
    EXPECT_EQ(asyncResp->res.result(), boost::beast::http::status::bad_request);

    // File should not have been created or should be empty
    std::ifstream fileIn(biosSettingFile, std::ios::binary | std::ios::ate);
    EXPECT_TRUE(!fileIn.is_open() || fileIn.tellg() == 0);
}

TEST(SystemsTest, SetBootOrderMixedCaseHex)
{
    const std::string biosSettingFile = "/tmp/oem_bios_setting.test";
    // Ensure file is removed before and after test
    std::remove(biosSettingFile.c_str());
    auto cleanup = absl::MakeCleanup([&]() {
        std::remove(biosSettingFile.c_str());
    });

    auto asyncResp = std::make_shared<bmcweb::AsyncResp>();

    // Test setting the boot order with mixed-case hex values
    std::vector<std::string> bootOrderToWrite = {"Boot000f", "Boot0E40"};
    setBootOrder(asyncResp, bootOrderToWrite, biosSettingFile);

    // Verify the file content
    std::ifstream fileIn(biosSettingFile, std::ios::binary);
    ASSERT_TRUE(fileIn.is_open());

    std::vector<uint16_t> bootIndices;
    uint16_t index;
    while (fileIn.read(reinterpret_cast<char*>(&index), sizeof(index)))
    {
        bootIndices.push_back(index);
    }
    fileIn.close();

    ASSERT_EQ(bootIndices.size(), 2);
    EXPECT_EQ(bootIndices[0], 0x000f);
    EXPECT_EQ(bootIndices[1], 0x0e40);

    // Test getting the boot order
    asyncResp->res.clear();
    getBootOrder(asyncResp, biosSettingFile);

    // getBootOrder normalizes to uppercase hex
    std::vector<std::string> expectedBootOrder = {"Boot000F", "Boot0E40"};
    EXPECT_EQ(asyncResp->res.jsonValue["Boot"]["BootOrder"], expectedBootOrder);
}


} // namespace
} // namespace redfish

