/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2017-2019, Regents of the University of California.
 *
 * This file is part of ndncert, a certificate management system based on NDN.
 *
 * ndncert 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.
 *
 * ndncert 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 copies of the GNU General Public License along with
 * ndncert, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndncert authors and contributors.
 */

#include "client-config.hpp"
#include <ndn-cxx/util/io.hpp>
#include <fstream>

namespace ndn {
namespace ndncert {

void
ClientConfig::load(const std::string& fileName)
{
  JsonSection config;
  try {
    boost::property_tree::read_json(fileName, config);
  }
  catch (const std::exception& error) {
    BOOST_THROW_EXCEPTION(Error("Failed to parse configuration file " + fileName + ", " + error.what()));
  }

  if (config.begin() == config.end()) {
    BOOST_THROW_EXCEPTION(Error("Error processing configuration file: " + fileName + ", no data"));
  }

  load(config);
}

void
ClientConfig::load(const JsonSection& configSection)
{
  m_caItems.clear();
  auto caList = configSection.get_child("ca-list");
  auto it = caList.begin();
  for (; it != caList.end(); it++) {
    m_caItems.push_back(extractCaItem(it->second));
  }
  m_localNdncertAnchor = configSection.get("local-ndncert-anchor", "");
}

void
ClientConfig::save(const std::string& fileName)
{
  JsonSection configJson;
  JsonSection caList;
  std::stringstream ss;
  for (const auto& item : m_caItems) {
    JsonSection caItem;
    caItem.put("ca-prefix", item.m_caName.toUri());
    caItem.put("ca-info", item.m_caInfo);
    caItem.put("probe", item.m_probe);
    ss.str(std::string());
    io::save(item.m_anchor, ss);
    caItem.put("certificate", ss.str());
    caList.push_back(std::make_pair("", caItem));
  }
  configJson.add_child("ca-list", caList);
  ss.str(std::string());
  boost::property_tree::write_json(ss, configJson);

  std::ofstream configFile;
  configFile.open(fileName, std::ios::trunc);
  configFile << ss.str();
  configFile.close();
}

ClientCaItem
ClientConfig::extractCaItem(const JsonSection& configSection)
{
  ClientCaItem item;
  item.m_caName = Name(configSection.get("ca-prefix", ""));
  if (item.m_caName.empty()) {
    BOOST_THROW_EXCEPTION(Error("Cannot read ca-prefix from the config file"));
  }
  item.m_caInfo = configSection.get("ca-info", "");
  item.m_probe = configSection.get("probe", "");
  std::istringstream ss(configSection.get("certificate", ""));
  auto anchor = io::load<security::v2::Certificate>(ss);
  if (anchor == nullptr) {
    BOOST_THROW_EXCEPTION(Error("Cannot load the certificate from config file"));
  }
  item.m_anchor = *anchor;
  return item;
}

void
ClientConfig::removeCaItem(const Name& caName)
{
  m_caItems.remove_if([&] (const ClientCaItem& item) {return item.m_caName == caName;});
}

} // namespace ndncert
} // namespace ndn
