/* -*- 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 "tlv.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", ""));
  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
