/* -*- 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_caPrefix.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_caPrefix = Name(configSection.get("ca-prefix", ""));
  if (item.m_caPrefix.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", ""));
  item.m_maxSuffixLength = configSection.get<size_t>(CONFIG_MAX_SUFFIX_LENGTH, 1);
  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_caPrefix == caName; });
}

}  // namespace ndncert
}  // namespace ndn
