#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_UTILS_FAN_UTILS_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_UTILS_FAN_UTILS_H_

#include <array>
#include <memory>
#include <string>
#include <string_view>
#include <unordered_map>
#include <utility>
#include <variant>

#include "logging.hpp"
#include "utility.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/message/native_types.hpp"

#ifdef UNIT_TEST_BUILD
#include "test/g3/mock_managed_store.hpp"  // NOLINT
#endif

namespace redfish {

namespace fan_utils {

constexpr std::array<std::string_view, 1> fanInterfaces = {
    "xyz.openbmc_project.Configuration.Fan"};

inline void fillFanProperties(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& objectPath,
    const dbus::utility::DBusPropertiesMap& properties,
    const std::shared_ptr<std::unordered_map<std::string, std::string>>&
        fanSensorToInventoryPath) {
  for (const auto& [propKey, propVariant] : properties) {
    if (propKey == "TachSensor") {
      const std::string* tachSensor = std::get_if<std::string>(&propVariant);
      if (tachSensor == nullptr) {
        messages::internalError(asyncResp->res);
        return;
      }
      (*fanSensorToInventoryPath)[*tachSensor] = objectPath;
    } else if (propKey == "PWMSensor") {
      const std::string* pwmSensor = std::get_if<std::string>(&propVariant);
      if (pwmSensor == nullptr) {
        messages::internalError(asyncResp->res);
        return;
      }
      (*fanSensorToInventoryPath)[*pwmSensor] = objectPath;
    }
  }
}

template <typename Callback>
inline void getFanInventory(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::shared_ptr<std::unordered_map<std::string, std::string>>&
        fanSensorToInventoryPath,
    Callback callback) {
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTree(
      "/xyz/openbmc_project/inventory", 0, fanInterfaces, requestContext,
      [asyncResp, fanSensorToInventoryPath, requestContext, callback{callback}](
          const boost::system::error_code ec,
          const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error";
          messages::internalError(asyncResp->res);
          return;
        }

        if (subtree.empty()) {
          callback();
          return;
        }

        auto fanConfigurationsQueried = std::make_shared<int>(subtree.size());
        for (const auto& [objectPath, serviceMap] : subtree) {
          for (const auto& [service, interfaces] : serviceMap) {
            for (const auto& interface : interfaces) {
              if (interface != fanInterfaces[0]) {
                continue;
              }
              managedStore::GetManagedObjectStore()->getAllProperties(
                  service, objectPath, interface, requestContext,
                  [asyncResp, fanSensorToInventoryPath, objectPath, callback,
                   fanConfigurationsQueried](
                      const boost::system::error_code& ec,
                      const dbus::utility::DBusPropertiesMap& properties) {
                    if (ec) {
                      BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
                      messages::internalError(asyncResp->res);
                      return;
                    }

                    fillFanProperties(asyncResp, objectPath, properties,
                                      fanSensorToInventoryPath);

                    if (*fanConfigurationsQueried <= 0) {
                      BMCWEB_LOG_ERROR << "Unaccounted fan configuration";
                      messages::internalError(asyncResp->res);
                      return;
                    }

                    if (*fanConfigurationsQueried == 1) {
                      callback();
                    }
                    --(*fanConfigurationsQueried);
                  });
            }
          }
        }
      });
}

inline void AddThermalSubsystemLink(
    const sdbusplus::message::object_path& fanInventoryPath,
    nlohmann::json& sensorJson) {
  nlohmann::json::object_t obj;
  obj["@odata.id"] = crow::utility::urlFromPieces(
      "redfish", "v1", "Chassis", fanInventoryPath.parent_path().filename(),
      "ThermalSubsystem", "Fans", fanInventoryPath.filename());
  sensorJson["RelatedItem"] = nlohmann::json::array_t{std::move(obj)};
}

inline void AddRelatedItemForFanSensor(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& sensorName) {
  auto fanSensorToInventoryPath =
      std::make_shared<std::unordered_map<std::string, std::string>>();
  getFanInventory(
      asyncResp, fanSensorToInventoryPath,
      [asyncResp, sensorName, fanSensorToInventoryPath]() {
        auto findFanObjectPath = fanSensorToInventoryPath->find(sensorName);
        if (findFanObjectPath != fanSensorToInventoryPath->end()) {
          sdbusplus::message::object_path fanInventoryPath(
              findFanObjectPath->second);
          AddThermalSubsystemLink(fanInventoryPath, asyncResp->res.jsonValue);
        }
      });
}

}  // namespace fan_utils
}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_UTILS_FAN_UTILS_H_
