#include "app.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "fan.hpp"
#include "http_request.hpp"
#include "http_response.hpp"
#include "snapshot_fixture.hpp"

#include <nlohmann/json.hpp>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

namespace redfish
{
namespace
{

using ::dbus::utility::DBusInteracesMap;
using ::dbus::utility::DBusPropertiesMap;
using ::dbus::utility::DbusVariantType;
using ::dbus::utility::ManagedObjectType;
using ::dbus::utility::MapperGetSubTreeResponse;
using ::dbus::utility::MapperServiceMap;
using ::managedStore::KeyType;
using ::managedStore::ManagedType;
using ::managedStore::ValueType;

std::shared_ptr<ValueType> CreateMockAssociatedSubtreeResponse()
{
    MapperGetSubTreeResponse mockAssociatedSubtreeResponse{{std::make_pair(
        "/xyz/openbmc_project/inventory/system/board/Bigchassis2_1",
        MapperServiceMap{{std::make_pair(
            "xyz.openbmc_project.EntityManager",
            std::vector<std::string>{
                "xyz.openbmc_project.Inventory.Decorator.LocationCode"})}})}};
    return managedStore::MockManagedStoreTest::CreateValueType(
        std::move(mockAssociatedSubtreeResponse));
}

absl::Status AssociateSensors(std::string_view sensorName)
{
    return managedStore::GetManagedObjectStore()
        ->upsertMockObjectIntoManagedStore(
            KeyType(ManagedType::kManagedAssociatedSubtree,
                    std::format("/xyz/openbmc_project/sensors/{}/chassis",
                                sensorName),
                    "/xyz/openbmc_project/inventory", 0,
                    {"xyz.openbmc_project.Inventory.Item.Board",
                     "xyz.openbmc_project.Inventory.Item.Chassis"}),
            CreateMockAssociatedSubtreeResponse());
}

TEST_F(SnapshotFixture, GetFanReturnsTheCorrectResponse)
{
    ASSERT_TRUE(AssociateSensors("fan_pwm/fan4_pwm").ok());
    handleFanGet(app_, CreateRequest(), share_async_resp_, "Bigchassis2_1",
                 "fan0");

    RunIoUntilDone();

    nlohmann::json& json = share_async_resp_->res.jsonValue;
    EXPECT_EQ(json["@odata.id"],
              "/redfish/v1/Chassis/Bigchassis2_1/ThermalSubsystem/Fans/fan0");
    EXPECT_EQ(json["Location"]["PartLocation"]["ServiceLabel"], "fan0");
    EXPECT_EQ(json["Location"]["PartLocation"]["LocationType"], "Embedded");
    EXPECT_EQ(json["Location"]["PartLocationContext"], "BIGchassis2");
    EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(SnapshotFixture, HandleFanGetPopulatesSecondarySpeedPercent)
{
    // Sets up the EM config
    ASSERT_TRUE(
        managedStore::GetManagedObjectStore()
            ->upsertMockObjectIntoManagedStore(
                KeyType(
                    ManagedType::kManagedPropertyMap,
                    "xyz.openbmc_project.EntityManager",
                    sdbusplus::message::object_path(
                        "/xyz/openbmc_project/inventory/system/board/Bigchassis2_1/fan0"),
                    "xyz.openbmc_project.Configuration.Fan"),
                managedStore::MockManagedStoreTest::CreateValueType(
                    DBusPropertiesMap({
                        std::make_pair("property",
                                       DbusVariantType("test_value")),
                        std::make_pair("HotPluggable", DbusVariantType(false)),
                        std::make_pair("LocationType",
                                       DbusVariantType("Embedded")),
                        std::make_pair("Name", DbusVariantType("fan0")),
                        std::make_pair("PWMSensor",
                                       DbusVariantType("fan4_pwm")),
                        std::make_pair("SecondaryPWMSensor",
                                       DbusVariantType("fan5_pwm")),
                        std::make_pair("ServiceLabel", DbusVariantType("fan0")),
                        std::make_pair("TachSensor",
                                       DbusVariantType("fan4_tach")),
                        std::make_pair("SecondaryTachSensor",
                                       DbusVariantType("fan5_tach")),
                        std::make_pair("Type", DbusVariantType("Fan")),
                    })))
            .ok());

    // Sets up the chassis associations
    ASSERT_TRUE(AssociateSensors("fan_pwm/fan4_pwm").ok());
    ASSERT_TRUE(AssociateSensors("fan_pwm/fan5_pwm").ok());
    ASSERT_TRUE(AssociateSensors("fan_tach/fan4_tach").ok());
    ASSERT_TRUE(AssociateSensors("fan_tach/fan5_tach").ok());

    handleFanGet(app_, CreateRequest(), share_async_resp_, "Bigchassis2_1",
                 "fan0");

    RunIoUntilDone();

    nlohmann::json& json = share_async_resp_->res.jsonValue;
    EXPECT_EQ(json["@odata.id"],
              "/redfish/v1/Chassis/Bigchassis2_1/ThermalSubsystem/Fans/fan0");
    EXPECT_THAT(json["SpeedPercent"]["Reading"].template get<double>(),
                ::testing::DoubleEq(40.784313725490193));
    EXPECT_THAT(json["SpeedPercent"]["SpeedRPM"].template get<double>(),
                ::testing::DoubleEq(9219));
    EXPECT_THAT(json["SecondarySpeedPercent"]["Reading"].template get<double>(),
                ::testing::DoubleEq(40.784313725490193));
    EXPECT_THAT(
        json["SecondarySpeedPercent"]["SpeedRPM"].template get<double>(),
        ::testing::DoubleEq(9241));
    EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

} // namespace
} // namespace redfish
