/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 */

#ifndef SH4LT_MONITOR_H_
#define SH4LT_MONITOR_H_

#include <filesystem>

#include "../infotree/information-tree.hpp"
#include "../logger/logger.hpp"
#include "./dir-watcher.hpp"
#include "./follower-stat.hpp"

namespace fs = std::filesystem;

namespace sh4lt::monitor {

class Monitor {
 public:
  /**
   * Construct the Monitor object. Default constructor use default sh4lt location.
   **/
  Monitor(logger::Logger::ptr logger);

  /**
   * Construct the Monitor object. Default constructor use default sh4lt location.
   *
   * \param path The path of a directory with sh4lt socket files
   **/
  Monitor(logger::Logger::ptr logger, fs::path path);

  /**
   * Update the monitor internal informations.
   *
   */
  auto update() -> void;

  /**
   * Get statistics.
   *
   * The top level has the following keys:
   *    - created: contains an array of sh4lt ids created between the last call to update and the
   *               previous one.
   *    - ids: contains all sh4lt ids with a sub-object containing "group", "label" and absolute
   *           socket "path". This branch is updated only once, when sh4lt is discovered.
   *    - infos: contains all sh4lt ids with a sub-object containing the statistics from the
   *             FollowerStat::stats method.
   *
   * \return The Information Tree containing statitics
   **/
  auto get_stats() -> const InfoTree*;

  /**
   * Get configuration of the data printer for a given Sh4lt.
   *
   * \return The Information Tree containing configuration
   **/
  auto get_data_printer_configuration(const fs::path& path) -> const InfoTree*;

  /**
   * Set formating options for the values of the data printer.
   *
   * \param path path of the Sh4lt to configure
   * See `::Sh4lt::utils::make_data_printer_fun` for other params documentation.
   *
   */
  bool set_data_printer_configuration(const fs::path& path,
                                      std::string value_format,
                                      std::string separator,
                                      size_t precision,
                                      size_t min_width);
  /**
   * Set number of value to be printed for a given Sh4lt.
   *
   * \param path path of the Sh4lt to configure
   * \param num_val The number of value to be printed. 0 for all values.
   *
   * return true if path was found, false otherwise.
   **/
  bool set_num_value_to_print(const fs::path& path, size_t num_val);

 private:
  logger::Logger::ptr log_;
  DirWatcher dir_watcher_;
  InfoTree::ptr info_;
  std::vector<std::unique_ptr<FollowerStat>> follower_stats_{};

  void update_with_new_sh4lt(const std::vector<fs::path>& paths);
};

}  // namespace sh4lt::monitor
#endif
