#include <cstdint>

#include <bmcweb_plugins/async_resp.hpp>
#include <bmcweb_plugins/dbus_utils.hpp>
#include <bmcweb_plugins/http_request.hpp>
#include <bmcweb_plugins/interface.hpp>
#include <bmcweb_plugins/macros.hpp>
#include <bmcweb_plugins/privilege_registry.hpp>
#include <bmcweb_plugins/query.hpp>

#include <iostream>
#include <memory>

namespace {

void echoServer(const crow::Request&,
                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                const std::string& param) {
  asyncResp->res.jsonValue["Echo"] = param;
}

void redfishGetReplacedManagedStore(
    const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRouteOnGlobalApp(req, asyncResp)) {
    return;
  }
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  redfish::dbus_utils::getProperty<std::vector<std::string>>(
      "xyz.openbmc_project.ObjectMapper", "associationPath",
      "xyz.openbmc_project.Association", "endpoints", requestContext,
      [asyncResp](const boost::system::error_code ec,
                  const std::vector<std::string>& resp) {
        if (ec) {
          return;  // no downstream_chassis = no failures
        }
        nlohmann::json& chassis =
            asyncResp->res.jsonValue["Links"]["chassisPropertyName"];
        chassis = nlohmann::json::array();
        const std::string chassisCollectionPath = "/redfish/v1/Chassis";
        for (const std::string& chassisPath : resp) {
          BMCWEB_LOG_INFO << chassisPath << "chassis path";
          sdbusplus::message::object_path path(chassisPath);
          std::string leaf = path.filename();
          if (leaf.empty()) {
            continue;
          }
          std::string newPath = chassisCollectionPath;
          newPath += "/";
          newPath += leaf;
          chassis.push_back({{"@odata.id", std::move(newPath)}});
        }
      });
}

void redfishGetReplaced(const crow::Request& req,
                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRouteOnGlobalApp(req, asyncResp)) {
    return;
  }
  managedStore::GetManagedObjectStore()->postDbusCallToIoContext(
      [asyncResp](const boost::system::error_code ec,
                  const std::variant<std::string>&) {
        if (ec) {
          asyncResp->res.jsonValue["dbus_call_result"] = "failed";
          return;
        }
      },
      "non-exist-service", "/no/exist/object",
      "org.freedesktop.DBus.Properties", "Get",
      "xyz.openbmc_project.Non.Exist.Interface", "Property");
  asyncResp->res.jsonValue["v1"] = "hacked";
}
void redfishGetAppended(const crow::Request&,
                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (asyncResp->res.jsonValue["dbus_call_result"] != "failed") {
    asyncResp->res.jsonValue["plugin_is_working"] = "false";
    return;
  }
  asyncResp->res.jsonValue["plugin_is_working"] = "true";
}

void modifyChassisName(const crow::Request&,
                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                       const std::string& chassisId) {
  if (chassisId == "InterestedChassis") {
    asyncResp->res.jsonValue["whatever_property"] = "whatever";
  }
}

void RegisterPlugins() {
  REDFISH_HANDLER_ADD("/echo_server/<str>/", boost::beast::http::verb::get,
                      redfish::privileges::getChassis, echoServer);
  REDFISH_HANDLER_ADD("/echo_server2/<str>/", boost::beast::http::verb::get,
                      redfish::privileges::getChassis, echoServer);
  REDFISH_HANDLER_ADD("/managed_store/", boost::beast::http::verb::get,
                      redfish::privileges::getChassis,
                      redfishGetReplacedManagedStore);
  REDFISH_HANDLER_REMOVE("/echo_server2/<str>/", boost::beast::http::verb::get);
  REDFISH_HANDLER_REPLACE("/redfish/", boost::beast::http::verb::get,
                          redfishGetReplaced);
  REDFISH_HANDLER_APPEND("/redfish/", boost::beast::http::verb::get,
                         redfishGetAppended);
  REDFISH_HANDLER_APPEND("/redfish/v1/Chassis/<str>/",
                         boost::beast::http::verb::get, modifyChassisName);
}

}  // namespace

namespace redfish_plugin {

void loadPlatformPlugins() { RegisterPlugins(); }
}  // namespace redfish_plugin
