#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_MANAGER_DIAGNOSTIC_DATA_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_MANAGER_DIAGNOSTIC_DATA_H_

#include <algorithm>
#include <array>
#include <cctype>
#include <chrono>  // NOLINT
#include <cstdint>
#include <fstream>
#include <functional>
#include <memory>
#include <optional>
#include <ratio>  // NOLINT
#include <string>
#include <string_view>
#include <unordered_set>
#include <utility>
#include <vector>

#include "boost/algorithm/string/predicate.hpp"  // NOLINT
#include "app.hpp"
#include "http_request.hpp"
#include "logging.hpp"
#include "routing.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "str_utility.hpp"
#include "error_messages.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "dbus_utils.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/unpack_properties.hpp"

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

namespace redfish {

using SensorVariantType = dbus::utility::DbusVariantType;

const std::unordered_set<std::string> daemonDoublePropertiesSet{
    "KernelTimeSeconds", "UserTimeSeconds", "UptimeSeconds"};

const std::unordered_set<std::string> daemonU32TPropertiesSet{
    "ResidentSetSizeBytes", "NFileDescriptors", "RestartCount"};

constexpr std::array bootupTimeProperties = {
    "FirmwareTimestampMonotonic",  "LoaderTimestampMonotonic",
    "KernelTimestampMonotonic",    "InitRDTimestampMonotonic",
    "UserspaceTimestampMonotonic", "FinishTimestampMonotonic"};

constexpr std::array bootupTimeMetricName = {
    "FirmwareTimeSeconds", "LoaderTimeSeconds", "KernelTimeSeconds",
    "InitrdTimeSeconds", "UserSpaceTimeSeconds"};

constexpr const char healthMon[] = "xyz.openbmc_project.HealthMon";

inline std::optional<std::pair<std::string, std::string>>
checkAndGetSoleGetSubTreeResponse(
    const dbus::utility::MapperGetSubTreeResponse& subtree) {
  if (subtree.empty()) {
    BMCWEB_LOG_DEBUG << "Can't find bmc D-Bus object!";
    return std::nullopt;
  }

  // TODO: Consider Multi-BMC cases
  // Assume only 1 bmc D-Bus object
  // Throw an error if there is more than 1
  if (subtree.size() > 1) {
    BMCWEB_LOG_DEBUG << "Found more than 1 bmc D-Bus object!";
    return std::nullopt;
  }

  if (subtree[0].first.empty() || subtree[0].second.size() != 1) {
    BMCWEB_LOG_DEBUG << "Error getting bmc D-Bus object!";
    return std::nullopt;
  }

  return std::make_pair(subtree[0].first, subtree[0].second[0].first);
}

// Returns the sole non-Object Mapper service
inline std::optional<std::string> checkAndGetSoleNonMapperGetObjectResponse(
    const dbus::utility::MapperGetObject& objects) {
  if (objects.empty()) {
    return std::nullopt;
  }

  for (const std::pair<std::string, std::vector<std::string>>&
           serviceAndIfaces : objects) {
    if (serviceAndIfaces.first != "xyz.openbmc_project.ObjectMapper") {
      return serviceAndIfaces.first;
    }
  }
  return std::nullopt;
}

inline void populateProcessorStatistics(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  managedStore::ManagedObjectStoreContext context(asyncResp);
  const std::array<std::pair<std::string, std::string>, 2>
      processorStatisticMapping{
          {{"/xyz/openbmc_project/metric/bmc/cpu/kernel", "KernelPercent"},
           {"/xyz/openbmc_project/metric/bmc/cpu/user", "UserPercent"}}};

  for (const auto& mapping : processorStatisticMapping) {
    dbus_utils::getProperty<double>(
        healthMon, mapping.first, "xyz.openbmc_project.Metric.Value", "Value",
        context,
        [asyncResp, property(mapping.second)](
            const boost::system::error_code ec2, double value) {
          if (ec2) {
            BMCWEB_LOG_ERROR << "DBus response error on getProperty " << ec2;
            return;
          }
          asyncResp->res.jsonValue["ProcessorStatistics"][property] = value;
        });
  }
}

inline void populateMemoryStatistics(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  managedStore::ManagedObjectStoreContext context(asyncResp);
  dbus_utils::getProperty<double>(
      healthMon, "/xyz/openbmc_project/metric/bmc/memory/available",
      "xyz.openbmc_project.Metric.Value", "Value", context,
      [asyncResp](const boost::system::error_code ec2, double value) {
        if (ec2) {
          BMCWEB_LOG_ERROR << "DBus response error on getProperty " << ec2;
          return;
        }
        asyncResp->res.jsonValue["MemoryStatistics"]["AvailableBytes"] =
            static_cast<int64_t>(value);
      });
}

inline void populateRWFSStatistics(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  managedStore::ManagedObjectStoreContext context(asyncResp);
  dbus_utils::getProperty<double>(
      healthMon, "/xyz/openbmc_project/metric/bmc/storage/rw",
      "xyz.openbmc_project.Metric.Value", "Value", context,
      [asyncResp](const boost::system::error_code ec, double value) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DBus response error on getProperty " << ec;
          return;
        }
        asyncResp->res.jsonValue["Oem"]["Google"]["RWStorageSpaceUsageBytes"] =
            static_cast<int64_t>(value);
      });
}

inline void populateTMPFSStatistics(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  managedStore::ManagedObjectStoreContext context(asyncResp);
  dbus_utils::getProperty<double>(
      healthMon, "/xyz/openbmc_project/metric/bmc/storage/tmp",
      "xyz.openbmc_project.Metric.Value", "Value", context,
      [asyncResp](const boost::system::error_code ec, double value) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DBus response error on getProperty " << ec;
          return;
        }
        asyncResp->res.jsonValue["Oem"]["Google"]["TMPStorageSpaceUsageBytes"] =
            static_cast<int64_t>(value);
      });
}

/**
 * @brief Find the endpoints for an Association definition.
 *
 * @param[i,o] asyncResp - Async response object
 *
 * @return void
 */
inline void findBmcInventory(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  populateProcessorStatistics(asyncResp);
  populateMemoryStatistics(asyncResp);
  populateRWFSStatistics(asyncResp);
  populateTMPFSStatistics(asyncResp);
}

inline void getBootInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  const std::array<std::string, 2> bootInfoProperties = {
      {"BootCount", "CrashCount"}};

  for (const std::string& propertyName : bootInfoProperties) {
    managedStore::ManagedObjectStoreContext context(asyncResp);
    dbus_utils::getProperty<uint32_t>(
        "xyz.openbmc_project.Metric", "/xyz/openbmc_project/metric/bmc0",
        "xyz.openbmc_project.Metric.BMC", propertyName, context,
        [asyncResp, propertyName](const boost::system::error_code ec,
                                  uint32_t property) {
          if (ec) {
            BMCWEB_LOG_ERROR << "DBus error getting boot count";
            return;
          }

          asyncResp->res.jsonValue["BootInfo"][propertyName] = property;
        });
  }

  // On-demand read of BootId
  // See https://www.kernel.org/doc/html/latest/admin-guide/sysctl/kernel.html#random
  std::ifstream bootIdFile("/proc/sys/kernel/random/boot_id");
  if (bootIdFile.is_open()) {
    std::string line;
    if (std::getline(bootIdFile, line)) {
      // Remove potential trailing newline or spaces
      line.erase(
          std::remove_if(line.begin(), line.end(),
                         [](unsigned char c) { return std::isspace(c); }),
          line.end());
      asyncResp->res.jsonValue["BootInfo"]["BootId"] = line;
    }
  } else {
    BMCWEB_LOG_ERROR << "Failed to open /proc/sys/kernel/random/boot_id";
  }
}

inline void calculateBootTimeResp(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
        properties) {
  static_assert(bootupTimeProperties.size() == bootupTimeMetricName.size() + 1);
  const uint32_t kernelIdx =
      std::find(bootupTimeProperties.begin(), bootupTimeProperties.end(),
                "KernelTimestampMonotonic") -
      bootupTimeProperties.begin();
  uint64_t lastTime = 0;
  uint32_t metricIdx = 0;

  for (const auto& s : bootupTimeMetricName) {
    aResp->res.jsonValue["BootTimeStatistics"][s] = 0.0;
  }
  // each metric should be calculated as next monotime - curr monotime
  // some timestamps maybe 0 if the hardware doesn't support it. In this
  // case we simply set that metrics to 0, and accumulate the diff until
  // an available time is seen
  // e.g. kernelmono initrdmono usermono finishmono is 0, 4, 0, 10
  // The metric values kerneltime initrdtime usertime should be 4, 0, 6
  try {
    for (uint32_t i = 0; i < bootupTimeProperties.size(); ++i) {
      const uint64_t* currTime = nullptr;
      const bool success = sdbusplus::unpackPropertiesNoThrow(
          dbus_utils::UnpackErrorPrinter(), properties,
          static_cast<std::string>(bootupTimeProperties[i]), currTime);
      if (!success || currTime == nullptr) {
        messages::internalError(aResp->res);
        return;
      }

      if (i == 0) {
        lastTime = *currTime;
        continue;
      }
      uint64_t timeDiff = 0;
      // KernelTime is 0 and timestamps before kernelTime are negative,
      // timestamps after kernel are positive.
      if (*currTime == 0 && i != kernelIdx) {
        continue;
      }

      if (i <= kernelIdx) {
        if (lastTime != 0) {
          timeDiff = lastTime - *currTime;
        }
      } else {
        timeDiff = *currTime - lastTime;
      }

      lastTime = *currTime;

      aResp->res
          .jsonValue["BootTimeStatistics"][bootupTimeMetricName[metricIdx]] =
          static_cast<double>(timeDiff) / 1000000.0;
      metricIdx = i;
    }
  } catch (...) {
    messages::internalError(aResp->res);
  }
}

inline void getBootTimeInfo(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  managedStore::ManagedObjectStoreContext context(asyncResp);
  managedStore::GetManagedObjectStore()->getAllProperties(
      "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
      "org.freedesktop.systemd1.Manager", context,
      [asyncResp](const boost::system::error_code ec2,
                  const dbus::utility::DBusPropertiesMap& properties) {
        if (ec2) {
          BMCWEB_LOG_ERROR << "DBUS error getting boot time";
          return;
        }
        calculateBootTimeResp(asyncResp, properties);
      });
}

inline void populateDaemonEntry(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& objectPath, const std::string& filterServiceName) {
  managedStore::ManagedObjectStoreContext context(asyncResp);
  managedStore::GetManagedObjectStore()->getAllProperties(
      "xyz.openbmc_project.Metric", objectPath,
      "xyz.openbmc_project.Metric.Daemon", context,
      [asyncResp, filterServiceName](
          const boost::system::error_code ec,
          const dbus::utility::DBusPropertiesMap& propertyMap) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DBus error getting daemon property";
          return;
        }

        nlohmann::json daemon;

        for (const auto& propertyPair : propertyMap) {
          if (propertyPair.first == "CommandLine") {
            std::string commandLine =
                std::get<std::string>(propertyPair.second);
            if (!filterServiceName.empty() &&
                commandLine.find(filterServiceName) == std::string::npos) {
              BMCWEB_LOG_DEBUG
                  << "Filter param exsits,skipping service:" << commandLine
                  << ". Fitler service name is " << filterServiceName;
              return;
            }
            daemon[propertyPair.first] = commandLine;
            continue;
          }

          if (daemonDoublePropertiesSet.contains(propertyPair.first)) {
            daemon[propertyPair.first] = std::get<double>(propertyPair.second);
            continue;
          }

          if (daemonU32TPropertiesSet.contains(propertyPair.first)) {
            daemon[propertyPair.first] =
                std::get<uint32_t>(propertyPair.second);
            continue;
          }
        }

        asyncResp->res.jsonValue["TopProcesses"].emplace_back(daemon);
      });
}

inline void getDaemonInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          const query_param::Query& delegatedQuery) {
  asyncResp->res.jsonValue["TopProcesses"] = nlohmann::json::array();

  std::string filterServiceName;
  if (!delegatedQuery.filter.empty()) {
    std::vector<std::string> filterParams;
    bmcweb::split(filterParams, delegatedQuery.filter, ' ');

    if (filterParams.size() != 3 ||
        filterParams[0] != "TopProcesses.CommandLine" ||
        filterParams[1] != "eq") {
      redfish::messages::queryParameterValueFormatError(
          asyncResp->res, "$filter", delegatedQuery.filter);
      asyncResp->res.result(boost::beast::http::status::not_implemented);
      return;
    }
    filterServiceName = filterParams[2];
  }

  managedStore::ManagedObjectStoreContext context(asyncResp);
  dbus_utils::getProperty<std::vector<std::string>>(
      "xyz.openbmc_project.ObjectMapper",
      "/xyz/openbmc_project/metric/bmc0/daemon",
      "xyz.openbmc_project.Association", "endpoints", context,
      [asyncResp, filterServiceName](
          const boost::system::error_code ec,
          const std::vector<std::string>& endpoints) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DBus error getting daemon association endpoints";
          return;
        }

        for (const auto& endpoint : endpoints) {
          populateDaemonEntry(asyncResp, endpoint, filterServiceName);
        }
      });
}

inline void getLatencyInfo(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  managedStore::ManagedObjectStoreContext context(asyncResp);
  dbus_utils::getProperty<double>(
      "xyz.openbmc_project.Metric", "/xyz/openbmc_project/metric/bmc0",
      "xyz.openbmc_project.Metric.BMC", "Latency", context,
      [asyncResp](const boost::system::error_code ec, const double property) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DBus error getting daemon association endpoints";
          return;
        }

        asyncResp->res.jsonValue["Oem"]["Google"]["Latency"] = property;
      });
}

inline void afterGetManagerStartTime(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const boost::system::error_code& ec, uint64_t bmcwebResetTime) {
  if (ec) {
    // Not all servers will be running in systemd, so ignore the error.
    return;
  }
  using std::chrono::steady_clock;

  std::chrono::duration<steady_clock::rep, std::micro> usReset{bmcwebResetTime};
  steady_clock::time_point resetTime{usReset};

  steady_clock::time_point now = steady_clock::now();

  steady_clock::duration runTime = now - resetTime;

  if (runTime < steady_clock::duration::zero()) {
    BMCWEB_LOG_CRITICAL << "Uptime was negative????";
    messages::internalError(aResp->res);
    return;
  }

  // Floor to the closest millisecond
  using Milli = std::chrono::duration<steady_clock::rep, std::milli>;
  Milli milli = std::chrono::floor<Milli>(runTime);

  using SecondsFloat = std::chrono::duration<double>;
  SecondsFloat sec = std::chrono::duration_cast<SecondsFloat>(milli);

  aResp->res.jsonValue["ServiceRootUptimeSeconds"] = sec.count();
}

inline void managerGetServiceRootUptime(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  managedStore::ManagedObjectStoreContext context(aResp);
  dbus_utils::getProperty<uint64_t>(
      "org.freedesktop.systemd1",
      "/org/freedesktop/systemd1/unit/bmcweb_2eservice",
      "org.freedesktop.systemd1.Unit", "ActiveEnterTimestampMonotonic", context,
      std::bind_front(afterGetManagerStartTime, aResp));
}
/**
 * handleManagerDiagnosticData supports ManagerDiagnosticData.
 * It retrieves BMC health information from various DBus resources and returns
 * the information through the response.
 */
inline void handleManagerDiagnosticDataGet(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  query_param::QueryCapabilities capabilities = {
      .canDelegateFilter = true,
  };
  query_param::Query delegatedQuery;
  if (!redfish::setUpRedfishRouteWithDelegation(app, req, asyncResp,
                                                delegatedQuery, capabilities)) {
    return;
  }
  asyncResp->res.jsonValue["@odata.type"] =
      "#ManagerDiagnosticData.v1_2_0.ManagerDiagnosticData";
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Managers/bmc/ManagerDiagnosticData";
  asyncResp->res.jsonValue["Id"] = "ManagerDiagnosticData";
  asyncResp->res.jsonValue["Name"] = "Manager Diagnostic Data";

#ifdef BMCWEB_ENABLE_STATEFUL_BMCWEB
  asyncResp->res.jsonValue["Oem"]["Google"]["GoogleManagedObjectStoreMetrics"]
                          ["@odata.id"] =
      "/redfish/v1/Managers/bmc/ManagerDiagnosticData/Oem/Google/"
      "GoogleManagedObjectStoreMetrics";
#endif

  managerGetServiceRootUptime(asyncResp);

  // Start the first step of the 4-step process to populate
  // the BMC diagnostic data
  findBmcInventory(asyncResp);
  getBootInfo(asyncResp);
  getBootTimeInfo(asyncResp);
  getDaemonInfo(asyncResp, delegatedQuery);
  getLatencyInfo(asyncResp);
}

inline void requestRoutesManagerDiagnosticData(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/ManagerDiagnosticData")
      .privileges(redfish::privileges::getManagerDiagnosticData)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleManagerDiagnosticDataGet, std::ref(app)));
}

}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_MANAGER_DIAGNOSTIC_DATA_H_
