#include "managed_store_http.hpp"

#include <malloc.h>

#include <charconv>
#include <cstddef>
#include <cstdio>
#include <cstring>
#include <memory>
#include <string>
#include <string_view>

#include "absl/strings/match.h"
#include "app.hpp"
#include "http_request.hpp"
#include "logging.hpp"
#include "async_resp.hpp"
#include "query.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_clock.hpp"
#include "managed_store_types.hpp"

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

namespace managedStore {

void ManagedObjectStoreHttp::requestRoutesManagedStoreDebug(
    const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  // playing with the header:
  auto maxAgeSec = 0;
  const auto maxAgeSecStr = req.getHeaderValue(bmcweb::BMCWEB_HINT_MAX_AGE_SEC);
  if (!maxAgeSecStr.empty()) {
    std::from_chars(maxAgeSecStr.data(),
                    maxAgeSecStr.data() + maxAgeSecStr.size(), maxAgeSec);
  }

  BMCWEB_LOG_STATEFUL_DEBUG
      << "=> /debug/managed_store: target: " << req.target()
      << " method: " << req.method() << " body: " << req.body()
      << " maxAgeSecStr: " << maxAgeSecStr << " maxAgeSec: " << maxAgeSec;

  // ManagedObjectStore instance:
  auto* store = managedStore::GetManagedObjectStore();
  if (store == nullptr) {
    asyncResp->res.jsonValue["err"] = "managed object store is null";
    BMCWEB_LOG_STATEFUL_ERROR << "=> ERROR: "
                              << asyncResp->res.jsonValue.dump();
    return;
  }

  // config:
  asyncResp->res.jsonValue["config"] = store->getConfig().toJson();

  // objects:
  asyncResp->res.jsonValue["managed_objects_metrics"] =
      store->GetManagedObjectsMetrics(managedStore::clockNow());

  // serialized size:
  asyncResp->res.jsonValue["snapshot_size_in_bytes"] =
      store->GetSnapshotSizeInBytes();

  // Export pq entries:
  store->GetPriorityQueueSize([asyncResp](size_t size) {
    asyncResp->res.jsonValue["managed_objects_pq_size"] = size;
  });
  store->GetPriorityQueueMetrics([asyncResp](const nlohmann::json& metrics) {
    asyncResp->res.jsonValue["managed_objects_pq_entries"] = metrics;
  });

  // ManagedStore counters from managedStoreTracker
  const ManagedStoreTracker& storeTracker = store->getStoreTracker();
  asyncResp->res.jsonValue["tracker"] = storeTracker.toJson();

  // always keep this one as the last item:
  asyncResp->res.jsonValue["ok"] = true;
}

void ManagedObjectStoreHttp::requestRoutesManagedStorePostFlush(
    const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  BMCWEB_LOG_STATEFUL_DEBUG
      << "=> /debug/managed_store: target: " << req.target()
      << " method: " << req.method() << " body: " << req.body();

  // ManagedObjectStore instance:
  auto* store = managedStore::GetManagedObjectStore();
  if (store == nullptr) {
    asyncResp->res.jsonValue["err"] = "managed object store is null";
    BMCWEB_LOG_STATEFUL_ERROR << "=> ERROR: "
                              << asyncResp->res.jsonValue.dump();
    return;
  }

  asyncResp->res.jsonValue["config"] = store->getConfig().toJson();
  store->clearAllObjects();
  asyncResp->res.jsonValue["managed_objects_metrics"] =
      store->GetManagedObjectsMetrics(managedStore::clockNow());
  store->GetPriorityQueueSize([asyncResp](size_t size) {
    asyncResp->res.jsonValue["managed_objects_pq_size"] = size;
  });

  // always keep this one as the last item:
  asyncResp->res.jsonValue["ok"] = true;
}

void ManagedObjectStoreHttp::requestRoutesSubscriptionsDebug(
    const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  BMCWEB_LOG_STATEFUL_DEBUG
      << "=> /debug/subscriptions: target: " << req.target()
      << " method: " << req.method() << " body: " << req.body();

  // ManagedObjectStore instance:
  auto* store = managedStore::GetManagedObjectStore();
  if (store == nullptr) {
    asyncResp->res.jsonValue["err"] = "managed object store is null";
    BMCWEB_LOG_STATEFUL_ERROR << "=> ERROR: "
                              << asyncResp->res.jsonValue.dump();
    return;
  }

  asyncResp->res.jsonValue["SubscriptionStore"] =
      store->GetSubscriptionsToJSON();
  asyncResp->res.jsonValue["DBusMonitors"] = store->GetDBusMonitorsToJSON();
}

void ManagedObjectStoreHttp::requestRoutesEventStoreDebug(
    const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  BMCWEB_LOG_STATEFUL_DEBUG << "=> /debug/event_store: target: " << req.target()
                            << " method: " << req.method()
                            << " body: " << req.body();

  // ManagedObjectStore instance:
  auto* store = managedStore::GetManagedObjectStore();
  if (store == nullptr) {
    asyncResp->res.jsonValue["err"] = "managed object store is null";
    BMCWEB_LOG_STATEFUL_ERROR << "=> ERROR: "
                              << asyncResp->res.jsonValue.dump();
    return;
  }

  std::string_view target = req.target();
  auto startIndex = target.find('?');
  if (startIndex != std::string::npos) {
    // The query has query params
    auto subIdIndex = target.find("subscription_id=", startIndex);
    if (subIdIndex == std::string::npos || subIdIndex != startIndex + 1) {
      asyncResp->res.jsonValue["Error"] =
          "Invalid query param. Only subscription_id param is supported.";
      return;
    }
    auto len = strlen("subscription_id=");
    std::string_view subscription_id = target.substr(subIdIndex + len);
    if (subscription_id.empty() || absl::StrContains(subscription_id, '?')) {
      asyncResp->res.jsonValue["Error"] =
          "Invalid query params. Only subscription_id param is supported.";
      return;
    }
    BMCWEB_LOG_STATEFUL_DEBUG << "subscription_id = " << subscription_id;
    size_t id = 0;
    if (1 == sscanf(subscription_id.data(), "%zu", &id))  // NOLINT
    {
      asyncResp->res.jsonValue = store->GetEventsBySubscriptionIdToJSON(id);
      return;
    }
    asyncResp->res.jsonValue["Error"] = "Invalid subscription_id.";
    return;
  }
  asyncResp->res.jsonValue = store->GetEventsToJSON();
}

void ManagedObjectStoreHttp::requestRoutesEventStoreFlush(
    const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  BMCWEB_LOG_STATEFUL_DEBUG << "=> /debug/event_store: target: " << req.target()
                            << " method: " << req.method()
                            << " body: " << req.body();

  // ManagedObjectStore instance:
  auto* store = managedStore::GetManagedObjectStore();
  if (store == nullptr) {
    asyncResp->res.jsonValue["err"] = "managed object store is null";
    BMCWEB_LOG_STATEFUL_ERROR << "=> ERROR: "
                              << asyncResp->res.jsonValue.dump();
    return;
  }

  store->ClearEventStore();
  asyncResp->res.jsonValue = store->GetEventsToJSON();
}

void ManagedObjectStoreHttp::requestGetGoogleManagedObjectStoreMetrics(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }

  asyncResp->res.jsonValue =
      managedStore::GetManagedObjectStore()->GetManagedObjectsMetrics(
          managedStore::clockNow());
}

void ManagedObjectStoreHttp::requestGetGoogleTimetrace(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  (void)app;
  BMCWEB_LOG_STATEFUL_DEBUG
      << "=> GoogleTimetrace:" << " method: " << req.method()
      << " target: " << req.target() << " body: " << req.body();

  // ManagedObjectStore instance:
  auto* store = managedStore::GetManagedObjectStore();
  if (store == nullptr) {
    asyncResp->res.jsonValue["err"] = "managed object store is null";
    BMCWEB_LOG_STATEFUL_ERROR << "=> ERROR: "
                              << asyncResp->res.jsonValue.dump();
    return;
  }

  nlohmann::json google;
  google["@odata.id"] =
      "/redfish/v1/Managers/bmc/ManagerDiagnosticData/Oem/Google/"
      "GoogleTimetrace";
  google["@odata.type"] = "#GoogleTimetrace.v1_0_0.GoogleTimetrace";

  google["Actions"]["#GoogleTimetrace.Clear"] = {
      {"target",
       "/redfish/v1/Managers/bmc/ManagerDiagnosticData/Oem/Google/"
       "GoogleTimetrace/Actions/GoogleTimetrace.Clear"}};

  // timeTrace
  const auto& timeTrace = store->getTimeTrace();
  google["time_trace_size"] = timeTrace.size();
  google["timetrace"] = timeTrace;

  // always keep this one as the last item:
  // final object:
  asyncResp->res.jsonValue = google;
}

void ManagedObjectStoreHttp::handleGoogleTimetraceClearPost(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  (void)app;
  BMCWEB_LOG_STATEFUL_DEBUG
      << "=> GoogleTimetraceClear:" << " method: " << req.method()
      << " target: " << req.target() << " body: " << req.body();

  // ManagedObjectStore instance:
  auto* store = managedStore::GetManagedObjectStore();
  if (store == nullptr) {
    asyncResp->res.jsonValue["err"] = "managed object store is null";
    BMCWEB_LOG_STATEFUL_ERROR << "=> ERROR: "
                              << asyncResp->res.jsonValue.dump();
    return;
  }

  store->clearTimeTrace();
}

void ManagedObjectStoreHttp::handleGoogleTakeSnapShot(
    [[maybe_unused]] App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  BMCWEB_LOG_STATEFUL_DEBUG
      << "=> GoogleTakeSnapShot:" << " method: " << req.method()
      << " target: " << req.target() << " body: " << req.body();

  auto* store = managedStore::GetManagedObjectStore();
  if (store == nullptr) {
    asyncResp->res.jsonValue["err"] = "managed object store is null";
    BMCWEB_LOG_STATEFUL_ERROR << "=> ERROR: "
                              << asyncResp->res.jsonValue.dump();
    return;
  }
  if (store->serialize()) {
    asyncResp->res.jsonValue["ok"] = true;
  } else {
    asyncResp->res.jsonValue["err"] = "Error making snapshot";
    BMCWEB_LOG_STATEFUL_ERROR << "=> ERROR: "
                              << asyncResp->res.jsonValue.dump();
  }
}

void ManagedObjectStoreHttp::handleGoogleLoadSnapShot(
    [[maybe_unused]] App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  BMCWEB_LOG_STATEFUL_DEBUG
      << "=> GoogleLoadSnapShot:" << " method: " << req.method()
      << " target: " << req.target() << " body: " << req.body();

  auto* store = managedStore::GetManagedObjectStore();
  if (store == nullptr) {
    asyncResp->res.jsonValue["err"] = "managed object store is null";
    BMCWEB_LOG_STATEFUL_ERROR << "=> ERROR: "
                              << asyncResp->res.jsonValue.dump();
    return;
  }
  if (store->deserialize()) {
    asyncResp->res.jsonValue["ok"] = true;
  } else {
    asyncResp->res.jsonValue["err"] = "Error loading snapshot";
    BMCWEB_LOG_STATEFUL_ERROR << "=> ERROR: "
                              << asyncResp->res.jsonValue.dump();
  }
}

void requestRoutesManagedStore(App& app) {
  // a few exports for debugging:
  BMCWEB_ROUTE(app, "/debug/malloc_stats")
      .methods(boost::beast::http::verb::get)(
          []([[maybe_unused]] const crow::Request& req,
             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
            asyncResp->res.jsonValue["ok"] = true;
            malloc_stats();
          });

  // a few exports for debugging:
  BMCWEB_ROUTE(app, "/debug/managed_store")
      // .privileges(redfish::privileges::postManager)
      .methods(boost::beast::http::verb::get)(
          [](const crow::Request& req,
             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
            ManagedObjectStoreHttp::requestRoutesManagedStoreDebug(req,
                                                                   asyncResp);
          });

  // flush the managed objects:
  BMCWEB_ROUTE(app, "/debug/managed_store/clear")
      .methods(boost::beast::http::verb::post)(
          [](const crow::Request& req,
             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
            ManagedObjectStoreHttp::requestRoutesManagedStorePostFlush(
                req, asyncResp);
          });

  // debug subscriptions
  BMCWEB_ROUTE(app, "/debug/subscriptions")
      .methods(boost::beast::http::verb::get)(
          [](const crow::Request& req,
             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
            ManagedObjectStoreHttp::requestRoutesSubscriptionsDebug(req,
                                                                    asyncResp);
          });

  // debug events
  BMCWEB_ROUTE(app, "/debug/event_store")
      .methods(boost::beast::http::verb::get)(
          [](const crow::Request& req,
             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
            ManagedObjectStoreHttp::requestRoutesEventStoreDebug(req,
                                                                 asyncResp);
          });

  // flush the event store
  BMCWEB_ROUTE(app, "/debug/event_store/clear")
      .methods(boost::beast::http::verb::post)(
          [](const crow::Request& req,
             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
            ManagedObjectStoreHttp::requestRoutesEventStoreFlush(req,
                                                                 asyncResp);
          });

  // GoogleManagedObjectStoreMetrics:
  BMCWEB_ROUTE(app,
               "/redfish/v1/Managers/bmc/ManagerDiagnosticData/Oem/Google/"
               "GoogleManagedObjectStoreMetrics")
      .methods(boost::beast::http::verb::get)(
          [&app](const crow::Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
            ManagedObjectStoreHttp::requestGetGoogleManagedObjectStoreMetrics(
                app, req, asyncResp);
          });

  // requests time trace
  BMCWEB_ROUTE(app,
               "/redfish/v1/Managers/bmc/ManagerDiagnosticData/Oem/Google/"
               "GoogleTimetrace")
      .methods(boost::beast::http::verb::get)(
          [&app](const crow::Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
            ManagedObjectStoreHttp::requestGetGoogleTimetrace(app, req,
                                                              asyncResp);
          });

  // Clear timetrace:
  BMCWEB_ROUTE(app,
               "/redfish/v1/Managers/bmc/ManagerDiagnosticData/Oem/Google/"
               "GoogleTimetrace/Actions/GoogleTimetrace.Clear")
      .methods(boost::beast::http::verb::post)(
          [&app](const crow::Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
            ManagedObjectStoreHttp::handleGoogleTimetraceClearPost(app, req,
                                                                   asyncResp);
          });

  // take snapshot
  BMCWEB_ROUTE(app,
               "/redfish/v1/Managers/bmc/ManagerDiagnosticData/Oem/Google/"
               "GoogleSnapShot/Actions/GoogleTakeSnapShot")
      .methods(boost::beast::http::verb::post)(
          [&app](const crow::Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
            ManagedObjectStoreHttp::handleGoogleTakeSnapShot(app, req,
                                                             asyncResp);
          });

  // load snapshot
  BMCWEB_ROUTE(app,
               "/redfish/v1/Managers/bmc/ManagerDiagnosticData/Oem/Google/"
               "GoogleSnapShot/Actions/GoogleLoadSnapShot")
      .methods(boost::beast::http::verb::post)(
          [&app](const crow::Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
            ManagedObjectStoreHttp::handleGoogleLoadSnapShot(app, req,
                                                             asyncResp);
          });
}

}  // namespace managedStore
