/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014, Regents of the University of California.
 *
 * This file is part of NDNS (Named Data Networking Domain Name Service).
 * See AUTHORS.md for complete list of NDNS authors and contributors.
 *
 * NDNS 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.
 *
 * NDNS 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
 * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * Copyright (c) 2014  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
 *
 * 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/>.
 **/

#include "config-file.hpp"
#include "logger.hpp"

#include <boost/property_tree/info_parser.hpp>
#include <fstream>


namespace ndn {
namespace ndns {

NDNS_LOG_INIT("ConfigFile")

void
ConfigFile::throwErrorOnUnknownSection(const std::string& filename,
                                       const std::string& sectionName,
                                       const ConfigSection& section,
                                       bool isDryRun)
{
  std::string msg = "Error processing configuration file ";
  msg += filename;
  msg += ": no module subscribed for section \"" + sectionName + "\"";

  throw ConfigFile::Error(msg);
}

void
ConfigFile::ignoreUnknownSection(const std::string& filename,
                                 const std::string& sectionName,
                                 const ConfigSection& section,
                                 bool isDryRun)
{
  // do nothing
}

ConfigFile::ConfigFile(UnknownConfigSectionHandler unknownSectionCallback)
  : m_unknownSectionCallback(unknownSectionCallback)
{
}

void
ConfigFile::addSectionHandler(const std::string& sectionName,
                              ConfigSectionHandler subscriber)
{
  m_subscriptions[sectionName] = subscriber;
}

void
ConfigFile::parse(const std::string& filename, bool isDryRun)
{
  BOOST_ASSERT(isDryRun == false);
  std::ifstream inputFile;
  inputFile.open(filename.c_str());
  if (!inputFile.good() || !inputFile.is_open())
    {
      std::string msg = "Failed to read configuration file: ";
      msg += filename;
      throw Error(msg);
    }
  parse(inputFile, isDryRun, filename);
  inputFile.close();
}

void
ConfigFile::parse(const std::string& input, bool isDryRun, const std::string& filename)
{
  std::istringstream inputStream(input);
  parse(inputStream, isDryRun, filename);
}


void
ConfigFile::parse(std::istream& input, bool isDryRun, const std::string& filename)
{
  try
    {
      boost::property_tree::read_info(input, m_global);
    }
  catch (const boost::property_tree::info_parser_error& error)
    {
      std::stringstream msg;
      msg << "Failed to parse configuration file";
      msg << " " << filename;
      msg << " " << error.message() << " line " << error.line();
      throw Error(msg.str());
    }

  process(isDryRun, filename);
}

void
ConfigFile::process(bool isDryRun, const std::string& filename)
{
  BOOST_ASSERT(isDryRun == false);
  BOOST_ASSERT(!filename.empty());
  // NFD_LOG_DEBUG("processing..." << ((isDryRun)?("dry run"):("")));

  if (m_global.begin() == m_global.end())
    {
      std::string msg = "Error processing configuration file: ";
      msg += filename;
      msg += " no data";
      throw Error(msg);
    }

  for (ConfigSection::const_iterator i = m_global.begin(); i != m_global.end(); ++i)
    {
      const std::string& sectionName = i->first;
      const ConfigSection& section = i->second;

      SubscriptionTable::iterator subscriberIt = m_subscriptions.find(sectionName);
      if (subscriberIt != m_subscriptions.end())
        {
          ConfigSectionHandler subscriber = subscriberIt->second;
          subscriber(section, isDryRun, filename);
        }
      else
        {
          m_unknownSectionCallback(filename, sectionName, section, isDryRun);
        }
    }
}

} // namespace ndns
} // namespace ndn
