/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013-2024 Regents of the University of California.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * ndn-cxx library 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 Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 */

#include "ndn-cxx/security/validation-policy-config.hpp"
#include "ndn-cxx/security/validator.hpp"
#include "ndn-cxx/util/io.hpp"

#include <boost/algorithm/string/predicate.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/property_tree/info_parser.hpp>

#include <filesystem>
#include <fstream>

namespace ndn::security::validator_config {

void
ValidationPolicyConfig::load(const std::string& filename)
{
  std::ifstream inputFile(filename);
  if (!inputFile) {
    NDN_THROW(Error("Failed to read configuration file: " + filename));
  }
  load(inputFile, filename);
}

void
ValidationPolicyConfig::load(const std::string& input, const std::string& filename)
{
  std::istringstream inputStream(input);
  load(inputStream, filename);
}

void
ValidationPolicyConfig::load(std::istream& input, const std::string& filename)
{
  ConfigSection tree;
  try {
    boost::property_tree::read_info(input, tree);
  }
  catch (const boost::property_tree::info_parser_error& e) {
    NDN_THROW(Error("Failed to parse configuration file " + filename +
                    " line " + to_string(e.line()) + ": " + e.message()));
  }
  load(tree, filename);
}

void
ValidationPolicyConfig::load(const ConfigSection& configSection, const std::string& filename)
{
  BOOST_ASSERT(!filename.empty());

  if (m_validator == nullptr) {
    NDN_THROW(Error("Validator instance not assigned on the policy"));
  }
  if (m_isConfigured) {
    m_shouldBypass = false;
    m_dataRules.clear();
    m_interestRules.clear();
    m_validator->resetAnchors();
    m_validator->resetVerifiedCertificates();
  }
  m_isConfigured = true;

  for (const auto& subSection : configSection) {
    const std::string& sectionName = subSection.first;
    const ConfigSection& section = subSection.second;

    if (boost::iequals(sectionName, "rule")) {
      auto rule = Rule::create(section, filename);
      if (rule->getPktType() == tlv::Data) {
        m_dataRules.push_back(std::move(rule));
      }
      else if (rule->getPktType() == tlv::Interest) {
        m_interestRules.push_back(std::move(rule));
      }
    }
    else if (boost::iequals(sectionName, "trust-anchor")) {
      processConfigTrustAnchor(section, filename);
    }
    else {
      NDN_THROW(Error("Error processing configuration file " + filename +
                      ": unrecognized section " + sectionName));
    }
  }
}

void
ValidationPolicyConfig::processConfigTrustAnchor(const ConfigSection& configSection,
                                                 const std::string& filename)
{
  auto propertyIt = configSection.begin();

  // Get trust-anchor.type
  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type")) {
    NDN_THROW(Error("Expecting <trust-anchor.type>"));
  }

  auto baseDir = std::filesystem::absolute(filename).parent_path().lexically_normal();
  std::string type = propertyIt->second.data();
  propertyIt++;

  if (boost::iequals(type, "file")) {
    // Get trust-anchor.file
    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "file-name")) {
      NDN_THROW(Error("Expecting <trust-anchor.file-name>"));
    }

    std::string file = propertyIt->second.data();
    propertyIt++;

    time::nanoseconds refresh = getRefreshPeriod(propertyIt, configSection.end());
    if (propertyIt != configSection.end())
      NDN_THROW(Error("Expecting end of <trust-anchor>"));

    m_validator->loadAnchor(file, baseDir / file, refresh, false);
  }
  else if (boost::iequals(type, "base64")) {
    // Get trust-anchor.base64-string
    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "base64-string"))
      NDN_THROW(Error("Expecting <trust-anchor.base64-string>"));

    std::stringstream ss(propertyIt->second.data());
    propertyIt++;

    if (propertyIt != configSection.end())
      NDN_THROW(Error("Expecting end of <trust-anchor>"));

    auto idCert = io::load<Certificate>(ss);
    if (idCert != nullptr) {
      m_validator->loadAnchor("", std::move(*idCert));
    }
    else {
      NDN_THROW(Error("Cannot decode certificate from base64-string"));
    }
  }
  else if (boost::iequals(type, "dir")) {
    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "dir"))
      NDN_THROW(Error("Expecting <trust-anchor.dir>"));

    std::string dirString(propertyIt->second.data());
    propertyIt++;

    time::nanoseconds refresh = getRefreshPeriod(propertyIt, configSection.end());
    if (propertyIt != configSection.end())
      NDN_THROW(Error("Expecting end of <trust-anchor>"));

    m_validator->loadAnchor(dirString, baseDir / dirString, refresh, true);
  }
  else if (boost::iequals(type, "any")) {
    m_shouldBypass = true;
  }
  else {
    NDN_THROW(Error("Unrecognized <trust-anchor.type>: " + type));
  }
}

time::nanoseconds
ValidationPolicyConfig::getRefreshPeriod(ConfigSection::const_iterator& it,
                                         const ConfigSection::const_iterator& end)
{
  auto refresh = time::nanoseconds::max();
  if (it == end) {
    return refresh;
  }

  if (!boost::iequals(it->first, "refresh")) {
    NDN_THROW(Error("Expecting <trust-anchor.refresh>"));
  }

  std::string inputString = it->second.data();
  ++it;
  char unit = inputString[inputString.size() - 1];
  std::string refreshString = inputString.substr(0, inputString.size() - 1);

  int32_t refreshPeriod = -1;
  try {
    refreshPeriod = boost::lexical_cast<int32_t>(refreshString);
  }
  catch (const boost::bad_lexical_cast&) {
    // pass
  }
  if (refreshPeriod < 0) {
    NDN_THROW(Error("Bad refresh value: " + refreshString));
  }

  if (refreshPeriod == 0) {
    return getDefaultRefreshPeriod();
  }

  switch (unit) {
    case 'h':
      return time::hours(refreshPeriod);
    case 'm':
      return time::minutes(refreshPeriod);
    case 's':
      return time::seconds(refreshPeriod);
    default:
      NDN_THROW(Error("Bad refresh time unit: "s + unit));
  }
}

time::nanoseconds
ValidationPolicyConfig::getDefaultRefreshPeriod()
{
  return 1_h;
}

void
ValidationPolicyConfig::checkPolicy(const Data& data, const shared_ptr<ValidationState>& state,
                                    const ValidationContinuation& continueValidation)
{
  BOOST_ASSERT_MSG(!hasInnerPolicy(), "ValidationPolicyConfig must be a terminal inner policy");

  if (m_shouldBypass) {
    return continueValidation(nullptr, state);
  }

  Name klName = getKeyLocatorName(data.getSignatureInfo(), *state);
  if (!state->getOutcome()) { // already failed
    return;
  }

  auto sigType = tlv::SignatureTypeValue(data.getSignatureType());

  for (const auto& rule : m_dataRules) {
    if (rule->match(tlv::Data, data.getName(), state)) {
      if (rule->check(tlv::Data, sigType, data.getName(), klName, state)) {
        return continueValidation(make_shared<CertificateRequest>(klName), state);
      }
      // rule->check calls state->fail(...) if the check fails
      return;
    }
  }

  return state->fail({ValidationError::POLICY_ERROR,
                      "No rule matched for data `" + data.getName().toUri() + "`"});
}

void
ValidationPolicyConfig::checkPolicy(const Interest& interest, const shared_ptr<ValidationState>& state,
                                    const ValidationContinuation& continueValidation)
{
  BOOST_ASSERT_MSG(!hasInnerPolicy(), "ValidationPolicyConfig must be a terminal inner policy");

  if (m_shouldBypass) {
    return continueValidation(nullptr, state);
  }

  auto sigInfo = getSignatureInfo(interest, *state);
  if (!state->getOutcome()) { // already failed
    return;
  }

  Name klName = getKeyLocatorName(sigInfo, *state);
  if (!state->getOutcome()) { // already failed
    return;
  }

  auto sigType = tlv::SignatureTypeValue(sigInfo.getSignatureType());

  for (const auto& rule : m_interestRules) {
    if (rule->match(tlv::Interest, interest.getName(), state)) {
      if (rule->check(tlv::Interest, sigType, interest.getName(), klName, state)) {
        return continueValidation(make_shared<CertificateRequest>(klName), state);
      }
      // rule->check calls state->fail(...) if the check fails
      return;
    }
  }

  return state->fail({ValidationError::POLICY_ERROR,
                      "No rule matched for interest `" + interest.getName().toUri() + "`"});
}

} // namespace ndn::security::validator_config
