/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2024,  Regents of the University of California,
 *                           Arizona Board of Regents,
 *                           Colorado State University,
 *                           University Pierre & Marie Curie, Sorbonne University,
 *                           Washington University in St. Louis,
 *                           Beijing Institute of Technology,
 *                           The University of Memphis.
 *
 * This file is part of NFD (Named Data Networking Forwarding Daemon).
 * See AUTHORS.md for complete list of NFD authors and contributors.
 *
 * NFD is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * NFD 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef NFD_DAEMON_COMMON_CONFIG_FILE_HPP
#define NFD_DAEMON_COMMON_CONFIG_FILE_HPP

#include "core/common.hpp"

#include <boost/property_tree/ptree.hpp>

#include <functional>
#include <map>

namespace nfd {

/**
 * \brief A configuration file section.
 */
using ConfigSection = boost::property_tree::ptree;

/**
 * \brief An optional configuration file section.
 */
using OptionalConfigSection = boost::optional<const ConfigSection&>;

/**
 * \brief Callback to process a configuration file section.
 */
using ConfigSectionHandler = std::function<void(const ConfigSection& section, bool isDryRun,
                                                const std::string& filename)>;

/**
 * \brief Callback to process a configuration file section without a #ConfigSectionHandler.
 */
using UnknownConfigSectionHandler = std::function<void(const std::string& filename,
                                                       const std::string& sectionName,
                                                       const ConfigSection& section,
                                                       bool isDryRun)>;

/**
 * \brief Configuration file parsing utility.
 */
class ConfigFile : noncopyable
{
public:
  class Error : public std::runtime_error
  {
  public:
    using std::runtime_error::runtime_error;
  };

  explicit
  ConfigFile(UnknownConfigSectionHandler unknownSectionCallback = throwErrorOnUnknownSection);

public: // unknown section handlers
  static void
  throwErrorOnUnknownSection(const std::string& filename,
                             const std::string& sectionName,
                             const ConfigSection& section,
                             bool isDryRun);

  static void
  ignoreUnknownSection(const std::string& filename,
                       const std::string& sectionName,
                       const ConfigSection& section,
                       bool isDryRun);

public: // parse helpers
  /** \brief Parse a config option that can be either "yes" or "no".
   *  \retval true "yes"
   *  \retval false "no"
   *  \throw Error the value is neither "yes" nor "no"
   */
  static bool
  parseYesNo(const ConfigSection& node, const std::string& key, const std::string& sectionName);

  static bool
  parseYesNo(const ConfigSection::value_type& option, const std::string& sectionName)
  {
    return parseYesNo(option.second, option.first, sectionName);
  }

  /**
   * \brief Parse a numeric (integral or floating point) config option.
   * \tparam T an arithmetic type
   *
   * \return the numeric value of the parsed option
   * \throw Error the value cannot be converted to the specified type
   */
  template<typename T>
  static T
  parseNumber(const ConfigSection& node, const std::string& key, const std::string& sectionName)
  {
    static_assert(std::is_arithmetic_v<T>);

    auto value = node.get_value_optional<T>();
    // Unsigned logic is workaround for https://redmine.named-data.net/issues/4489
    if (value &&
        (std::is_signed_v<T> || node.get_value<std::string>().find("-") == std::string::npos)) {
      return *value;
    }
    NDN_THROW(Error("Invalid value '" + node.get_value<std::string>() +
                    "' for option '" + key + "' in section '" + sectionName + "'"));
  }

  template<typename T>
  static T
  parseNumber(const ConfigSection::value_type& option, const std::string& sectionName)
  {
    return parseNumber<T>(option.second, option.first, sectionName);
  }

  /**
   * \brief Check that a value is within the inclusive range [min, max].
   * \throw Error the value is out of the acceptable range
   */
  template<typename T>
  static void
  checkRange(T value, T min, T max, const std::string& key, const std::string& sectionName)
  {
    static_assert(std::is_integral_v<T>);

    if (value < min || value > max) {
      NDN_THROW(Error("Invalid value '" + std::to_string(value) + "' for option '" + key +
                      "' in section '" + sectionName + "': out of acceptable range [" +
                      std::to_string(min) + ", " + std::to_string(max) + "]"));
    }
  }

public: // setup and parsing
  /// \brief Setup notification of configuration file sections.
  void
  addSectionHandler(const std::string& sectionName,
                    ConfigSectionHandler subscriber);

  /**
   * \param filename file to parse
   * \param isDryRun true if performing a dry run of configuration, false otherwise
   * \throws ConfigFile::Error if file not found
   * \throws ConfigFile::Error if parse error
   */
  void
  parse(const std::string& filename, bool isDryRun);

  /**
   * \param input configuration (as a string) to parse
   * \param isDryRun true if performing a dry run of configuration, false otherwise
   * \param filename logical filename of the config file, can appear in error messages
   * \throws ConfigFile::Error if file not found
   * \throws ConfigFile::Error if parse error
   */
  void
  parse(const std::string& input, bool isDryRun, const std::string& filename);

  /**
   * \param input stream to parse
   * \param isDryRun true if performing a dry run of configuration, false otherwise
   * \param filename logical filename of the config file, can appear in error messages
   * \throws ConfigFile::Error if parse error
   */
  void
  parse(std::istream& input, bool isDryRun, const std::string& filename);

  /**
   * \param config ConfigSection that needs to be processed
   * \param isDryRun true if performing a dry run of configuration, false otherwise
   * \param filename logical filename of the config file, can appear in error messages
   * \throws ConfigFile::Error if parse error
   */
  void
  parse(const ConfigSection& config, bool isDryRun, const std::string& filename);

private:
  void
  process(bool isDryRun, const std::string& filename) const;

private:
  UnknownConfigSectionHandler m_unknownSectionCallback;
  std::map<std::string, ConfigSectionHandler> m_subscriptions;
  ConfigSection m_global;
};

} // namespace nfd

#endif // NFD_DAEMON_COMMON_CONFIG_FILE_HPP
