#include <CLI/App.hpp>
#include <CLI/Config.hpp>
#include <CLI/Formatter.hpp>
#include <boost/asio/steady_timer.hpp>
#include <chrono>
#include <functional>
#include <iostream>
#include <memory>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>

boost::asio::io_context io;
std::vector<std::shared_ptr<sdbusplus::asio::dbus_interface>> sensorInterfaces;

int update_interval_seconds = 1;

size_t reads = 0;

void on_loop(boost::asio::steady_timer *timer,
             const boost::system::error_code &error) {

  if (error) {
    return;
  }
  std::chrono::steady_clock::time_point start =
      std::chrono::steady_clock::now();

  static double value = -100.0;

  for (auto &sensor : sensorInterfaces) {
    if (!sensor->set_property("Value", value)) {
      std::cout << "Can't set property for sensor\n";
    }
    value += 10.0;
    if (value >= 100.0) {
      value = -100.0;
    }
  }
  if (!sensorInterfaces.empty()) {
    std::cout << sensorInterfaces.size() << " updates took "
              << std::chrono::duration_cast<std::chrono::duration<float>>(
                     std::chrono::steady_clock::now() - start)
                     .count()
              << " seconds\n";
  }

  if (reads > 0) {
    std::cout << "Read " << reads << " sensor updates\n";
    reads = 0;
  }

  timer->expires_from_now(std::chrono::seconds(update_interval_seconds));
  timer->async_wait(std::bind_front(on_loop, timer));
};

int main(int argc, const char **argv) {
  CLI::App app{"dbus performance test application"};

  size_t number_of_sensors = 0;
  app.add_option("-n", number_of_sensors, "Number of sensors to create");

  bool watch_sensor_updates = false;
  app.add_flag("-w", watch_sensor_updates,
               "Watch for all sensor values from dbus");
  CLI11_PARSE(app, argc, argv);

  if (number_of_sensors == 0 && watch_sensor_updates == false) {
    std::cout << "Nothing to do\n";
    app.exit(CLI::CallForHelp());
    return -1;
  }

  std::shared_ptr<sdbusplus::asio::connection> connection =
      std::make_shared<sdbusplus::asio::connection>(io);
  sdbusplus::asio::object_server objectServer(connection);

  std::string name = "foobar";
  sensorInterfaces.reserve(number_of_sensors);
  for (size_t sensorIndex = 0; sensorIndex < number_of_sensors; sensorIndex++) {
    sdbusplus::message::object_path path(
        "/xyz/openbmc_project/sensors/temperature/");
    path /= name + std::to_string(sensorIndex);
    std::shared_ptr<sdbusplus::asio::dbus_interface> sensorInterface =
        objectServer.add_interface(path.str,
                                   "xyz.openbmc_project.Sensor.Value");
    sensorInterface->register_property<std::string>(
        "Unit", "xyz.openbmc_project.Sensor.Unit.DegreesC");
    sensorInterface->register_property<double>("MaxValue", 100);
    sensorInterface->register_property<double>("MinValue", -100);
    sensorInterface->register_property<double>("Value", 42);

    sensorInterface->initialize();
    sensorInterfaces.emplace_back(sensorInterface);
  }

  std::cout << "Done initializing\n";

  boost::asio::steady_timer timer(io);
  timer.expires_from_now(std::chrono::seconds(update_interval_seconds));
  timer.async_wait(std::bind_front(on_loop, &timer));
  std::optional<sdbusplus::bus::match::match> match;
  if (watch_sensor_updates) {
    std::string expr = "type='signal',member='PropertiesChanged',path_"
                       "namespace='/xyz/openbmc_project/sensors'";

    match.emplace(
        static_cast<sdbusplus::bus::bus &>(*connection), expr,
        [](sdbusplus::message::message &message) {
          std::string objectName;
          std::vector<std::pair<std::string, std::variant<double>>> result;
          try {
            message.read(objectName, result);
          } catch (const sdbusplus::exception_t &) {
            std::cerr << "Error reading match data\n";
            return;
          }
          for (auto &property : result) {
            if (property.first == "Value") {
              reads++;
            }
          }
        });
  }

  io.run();

  return 0;
}