#ifndef THIRD_PARTY_GBMCWEB_INCLUDE_PERSISTENT_DATA_H_
#define THIRD_PARTY_GBMCWEB_INCLUDE_PERSISTENT_DATA_H_
#include <chrono>  // NOLINT
#include <cstdint>
#include <filesystem>  // NOLINT
#include <fstream>
#include <memory>
#include <optional>
#include <string>
#include <utility>

#ifdef GOOGLE3_GBMCWEB_BUILD
#include "absl/base/no_destructor.h"
#endif

#include "boost/beast/http/fields.hpp"  // NOLINT
#include "boost/uuid/uuid.hpp"  // NOLINT
#include "boost/uuid/uuid_generators.hpp"  // NOLINT
#include "boost/uuid/uuid_io.hpp"  // NOLINT
#include "logging.hpp"
#include "event_service_store.hpp"
#include "request_stats.hpp"
#include "sessions.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"

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

namespace persistent_data {

class ConfigFile {
  uint64_t json_revision_ = 1;

 public:
  // todo(ed) should read this from a fixed location somewhere, not CWD
  static constexpr const char* kFileName = "bmcweb_persistent_data.json";

  ConfigFile() { readData(); }

  ~ConfigFile() {
    // Make sure we aren't writing stale sessions
    persistent_data::SessionStore::getInstance().applySessionTimeouts();
    if (persistent_data::SessionStore::getInstance().needsWrite()) {
      writeData();
    }
  }

  ConfigFile(const ConfigFile&) = delete;
  ConfigFile(ConfigFile&&) = delete;
  ConfigFile& operator=(const ConfigFile&) = delete;
  ConfigFile& operator=(ConfigFile&&) = delete;

  // TODO(ed) this should really use protobuf, or some other serialization
  // library, but adding another dependency is somewhat outside the scope of
  // this application for the moment
  void readData() {
    std::ifstream persistent_file(kFileName);
    uint64_t file_revision = 0;
    if (persistent_file.is_open()) {
      // call with exceptions disabled
      auto data = nlohmann::json::parse(persistent_file, nullptr, false);
      if (data.is_discarded()) {
        BMCWEB_LOG_ERROR << "Error parsing persistent data in json file.";
      } else {
        for (const auto& item : data.items()) {
          if (item.key() == "revision") {
            file_revision = 0;

            const uint64_t* uint_ptr = item.value().get_ptr<const uint64_t*>();
            if (uint_ptr == nullptr) {
              BMCWEB_LOG_ERROR << "Failed to read revision flag";
            } else {
              file_revision = *uint_ptr;
            }
          } else if (item.key() == "system_uuid") {
            const std::string* j_system_uuid =
                item.value().get_ptr<const std::string*>();
            if (j_system_uuid != nullptr) {
              systemUuid = *j_system_uuid;
            }
          } else if (item.key() == "auth_config") {
            SessionStore::getInstance().getAuthMethodsConfig().fromJson(
                item.value());
          } else if (item.key() == "sessions") {
            for (const auto& elem : item.value()) {
              std::shared_ptr<UserSession> new_session =
                  UserSession::fromJson(elem);

              if (new_session == nullptr) {
                BMCWEB_LOG_ERROR << "Problem reading session "
                                    "from persistent store";
                continue;
              }

              BMCWEB_LOG_DEBUG << "Restored session: " << new_session->csrfToken
                               << " " << new_session->uniqueId << " "
                               << new_session->sessionToken;
              SessionStore::getInstance().authTokens.emplace(
                  new_session->sessionToken, new_session);
            }
          } else if (item.key() == "timeout") {
            const int64_t* j_timeout = item.value().get_ptr<int64_t*>();
            if (j_timeout == nullptr) {
              BMCWEB_LOG_DEBUG << "Problem reading session timeout value";
              continue;
            }
            std::chrono::seconds session_timeout_in_seconds(*j_timeout);
            BMCWEB_LOG_DEBUG << "Restored Session Timeout: "
                             << session_timeout_in_seconds.count();
            SessionStore::getInstance().updateSessionTimeout(
                session_timeout_in_seconds);
          } else if (item.key() == "eventservice_config") {
            EventServiceStore::getInstance().getEventServiceConfig().fromJson(
                item.value());
          } else if (item.key() == "subscriptions") {
            for (const auto& elem : item.value()) {
              std::shared_ptr<UserSubscription> new_subscription =
                  UserSubscription::fromJson(elem);

              if (new_subscription == nullptr) {
                BMCWEB_LOG_ERROR << "Problem reading subscription "
                                    "from persistent store";
                continue;
              }

              BMCWEB_LOG_DEBUG
                  << "Restored subscription: " << new_subscription->id << " "
                  << new_subscription->customText;
              EventServiceStore::getInstance().subscriptionsConfigMap.emplace(
                  new_subscription->id, new_subscription);
            }
          } else if (item.key() == "stateful") {
            BMCWEB_LOG_STATEFUL_ALWAYS << "=> ConfigFile: stateful: "
                                       << item.value().dump();
            this->isStatefulEnabled =
                item.value().get<nlohmann::json::boolean_t>();
          } else if (item.key() == "request_stats") {
            BMCWEB_LOG_STATEFUL_ALWAYS << "=> ConfigFile: request_stats: "
                                       << item.value().dump();
            this->isRequestStatsEnabled =
                item.value().get<nlohmann::json::boolean_t>();
          } else if (item.key() == "stateful_logs") {
            BMCWEB_LOG_STATEFUL_ALWAYS << "=> ConfigFile: stateful_logs: "
                                       << item.value().dump();
            this->isStatefulLogsEnabled =
                item.value().get<nlohmann::json::boolean_t>();
          } else {
            // Do nothing in the case of extra fields.  We may have
            // cases where fields are added in the future, and we
            // want to at least attempt to gracefully support
            // downgrades in that case, even if we don't officially
            // support it
          }
        }
      }
    }
    bool need_write = false;

    if (systemUuid.empty()) {
      systemUuid = boost::uuids::to_string(boost::uuids::random_generator()());
      need_write = true;
    }
    if (file_revision < json_revision_) {
      need_write = true;
    }
    // write revision changes or system uuid changes immediately
    if (need_write) {
      writeData();
    }
  }

  void writeData() {
    std::ofstream persistent_file(kFileName);

    // set the permission of the file to 640
    std::filesystem::perms permission = std::filesystem::perms::owner_read |
                                        std::filesystem::perms::owner_write |
                                        std::filesystem::perms::group_read;
    std::filesystem::permissions(kFileName, permission);
    const auto& c = SessionStore::getInstance().getAuthMethodsConfig();
    const auto& event_service_config =
        EventServiceStore::getInstance().getEventServiceConfig();
    nlohmann::json::object_t data;

    nlohmann::json& auth_config = data["auth_config"];
    auth_config["XToken"] = c.xtoken;
    auth_config["Cookie"] = c.cookie;
    auth_config["SessionToken"] = c.sessionToken;
    auth_config["BasicAuth"] = c.basic;
    auth_config["TLS"] = c.tls;

    nlohmann::json& eventservice_config = data["eventservice_config"];
    eventservice_config["ServiceEnabled"] = event_service_config.enabled;
    eventservice_config["DeliveryRetryAttempts"] =
        event_service_config.retryAttempts;
    eventservice_config["DeliveryRetryIntervalSeconds"] =
        event_service_config.retryTimeoutInterval;

    // export the managed_store_config:
    if (managedStore::GetManagedObjectStore() != nullptr) {
      data["managed_store_config"] =
          managedStore::GetManagedObjectStore()->getConfig().toJson();
      data["stateful"] =
          managedStore::GetManagedObjectStore()->getConfig().isEnabled;
      BMCWEB_LOG_STATEFUL_ALWAYS << "=> managed_store_config: "
                                 << data["managed_store_config"].dump();
    }

    {
      data["request_stats_config"] =
          managedStore::RequestStatsStore::instance().getConfig().toJson();
      data["request_stats"] = managedStore::RequestStatsStore::isEnabled();
      BMCWEB_LOG_STATEFUL_ALWAYS << "=> request_stats_config: "
                                 << data["request_stats_config"].dump();
    }

    data["system_uuid"] = systemUuid;
    data["revision"] = json_revision_;
    data["timeout"] = SessionStore::getInstance().getTimeoutInSeconds();

    nlohmann::json& sessions = data["sessions"];
    sessions = nlohmann::json::array();
    for (const auto& p : SessionStore::getInstance().authTokens) {
      if (p.second->persistence !=
          persistent_data::PersistenceType::SINGLE_REQUEST) {
        nlohmann::json::object_t session;
        session["unique_id"] = p.second->uniqueId;
        session["session_token"] = p.second->sessionToken;
        session["username"] = p.second->username;
        session["csrf_token"] = p.second->csrfToken;
        session["client_ip"] = p.second->clientIp;
        if (p.second->clientId) {
          session["client_id"] = *p.second->clientId;
        }
        sessions.push_back(std::move(session));
      }
    }
    nlohmann::json& subscriptions = data["subscriptions"];
    subscriptions = nlohmann::json::array();
    for (const auto& it :
         EventServiceStore::getInstance().subscriptionsConfigMap) {
      std::shared_ptr<UserSubscription> sub_value = it.second;
      if (sub_value->subscriptionType == "SSE") {
        BMCWEB_LOG_DEBUG << "The subscription type is SSE, so skipping.";
        continue;
      }
      nlohmann::json::object_t headers;
      for (const boost::beast::http::fields::value_type& header :
           sub_value->httpHeaders) {
        // Note, these are technically copies because nlohmann doesn't
        // support key lookup by std::string_view.  At least the
        // following code can use move
        // https://github.com/nlohmann/json/issues/1529
        std::string name(header.name_string());
        headers[std::move(name)] = header.value();
      }

      nlohmann::json::object_t subscription;

      subscription["Id"] = sub_value->id;
      subscription["Context"] = sub_value->customText;
      subscription["DeliveryRetryPolicy"] = sub_value->retryPolicy;
      subscription["Destination"] = sub_value->destinationUrl;
      subscription["EventFormatType"] = sub_value->eventFormatType;
      subscription["HttpHeaders"] = std::move(headers);
      subscription["MessageIds"] = sub_value->registryMsgIds;
      subscription["Protocol"] = sub_value->protocol;
      subscription["RegistryPrefixes"] = sub_value->registryPrefixes;
      subscription["ResourceTypes"] = sub_value->resourceTypes;
      subscription["SubscriptionType"] = sub_value->subscriptionType;
      subscription["MetricReportDefinitions"] =
          sub_value->metricReportDefinitions;

      subscriptions.push_back(std::move(subscription));
    }
    persistent_file << data;
  }

  std::string systemUuid;  // NOLINT
  // 'stateful' enable/disable
  std::optional<bool> isStatefulEnabled;  // NOLINT
  // 'request stats' enable/disable
  std::optional<bool> isRequestStatsEnabled;  // NOLINT
  // 'stateful_logs' enable/disable
  std::optional<bool> isStatefulLogsEnabled;  // NOLINT
};

inline ConfigFile& getConfig() {
#ifdef GOOGLE3_GBMCWEB_BUILD
  static absl::NoDestructor<ConfigFile> f;
  return *f;
#else
  static ConfigFile f; // NOLINT
  return f;
#endif
}

}  // namespace persistent_data

#endif  // THIRD_PARTY_GBMCWEB_INCLUDE_PERSISTENT_DATA_H_
