#include "fan.hpp"

#include <memory>
#include <string>
#include <string_view>
#include <system_error>  // NOLINT
#include <utility>
#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "dbus_utility.hpp"
#include "test/redfish-core/lib/snapshot_fixture.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "test/g3/mock_managed_store_test.hpp"
#include "sdbusplus/message/native_types.hpp"

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 dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
             managedStore::GetManagedObjectStore())
      ->upsertMockObjectIntoManagedStore(
          KeyType(ManagedType::kManagedAssociatedSubtree,
                  absl::StrCat("/xyz/openbmc_project/sensors/", sensorName,
                               "/chassis"),
                  "/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(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          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
