/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2018, 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/>.
 */

#include "rrset-factory.hpp"
#include "mgmt/management-tool.hpp"
#include "util/cert-helper.hpp"

#include <ndn-cxx/security/signing-helpers.hpp>

#include <boost/algorithm/string/join.hpp>

namespace ndn {
namespace ndns {

RrsetFactory::RrsetFactory(const boost::filesystem::path& dbFile,
                           const Name& zoneName,
                           KeyChain& keyChain,
                           const Name& inputDskCertName)
  : m_keyChain(keyChain)
  , m_dbFile(dbFile.string())
  , m_zone(zoneName)
  , m_dskCertName(inputDskCertName)
  , m_checked(false)
{
  Name identityName = Name(zoneName).append(label::NDNS_ITERATIVE_QUERY);
  if (m_dskCertName == DEFAULT_CERT) {
    m_dskName = CertHelper::getDefaultKeyNameOfIdentity(m_keyChain, identityName);
    m_dskCertName = CertHelper::getDefaultCertificateNameOfIdentity(m_keyChain, identityName);
  }
}

void
RrsetFactory::checkZoneKey()
{
  onlyCheckZone();
  Name zoneIdentityName = Name(m_zone.getName()).append(label::NDNS_ITERATIVE_QUERY);
  if (m_dskCertName != DEFAULT_CERT &&
      !matchCertificate(m_dskCertName, zoneIdentityName)) {
    BOOST_THROW_EXCEPTION(Error("Cannot verify certificate"));
  }
}

void
RrsetFactory::onlyCheckZone()
{
  if (m_checked) {
    return ;
  }
  m_checked = true;

  DbMgr dbMgr(m_dbFile);
  const Name& zoneName = m_zone.getName();
  if (!dbMgr.find(m_zone)) {
    BOOST_THROW_EXCEPTION(Error(zoneName.toUri() + " is not presented in the NDNS db"));
  }
}


std::pair<Rrset, Name>
RrsetFactory::generateBaseRrset(const Name& label,
                                const name::Component& type,
                                uint64_t version,
                                const time::seconds& ttl)
{
  Rrset rrset(&m_zone);

  rrset.setLabel(label);
  rrset.setType(type);
  rrset.setTtl(ttl);

  Name name;
  name.append(m_zone.getName())
      .append(label::NDNS_ITERATIVE_QUERY)
      .append(label)
      .append(type);

  if (version != VERSION_USE_UNIX_TIMESTAMP) {
    name.append(name::Component::fromVersion(version));
  }
  else {
    name.appendVersion();
  }

  rrset.setVersion(name.get(-1));

  return std::make_pair(rrset, name);
}

bool
RrsetFactory::matchCertificate(const Name& certName, const Name& identity)
{
  try {
    CertHelper::getCertificate(m_keyChain, identity, certName);
    return true;
  } catch (const ndn::security::Pib::Error&) {
    return false;
  }
}

Rrset
RrsetFactory::generateNsRrset(const Name& label,
                              uint64_t version,
                              time::seconds ttl,
                              const ndn::DelegationList& delegations)
{
  if (!m_checked) {
    BOOST_THROW_EXCEPTION(Error("You have to call checkZoneKey before call generate functions"));
  }

  if (ttl == DEFAULT_RR_TTL)
    ttl = m_zone.getTtl();

  std::pair<Rrset, Name> rrsetAndName = generateBaseRrset(label, label::NS_RR_TYPE, version, ttl);
  const Name& name = rrsetAndName.second;
  Rrset& rrset = rrsetAndName.first;

  Link link(name);
  link.setDelegationList(delegations);

  setContentType(link, NDNS_LINK, ttl);
  sign(link);
  rrset.setData(link.wireEncode());

  return rrset;
}

Rrset
RrsetFactory::generateTxtRrset(const Name& label,
                               uint64_t version,
                               time::seconds ttl,
                               const std::vector<std::string>& strings)
{
  if (!m_checked) {
    BOOST_THROW_EXCEPTION(Error("You have to call checkZoneKey before call generate functions"));
  }

  if (ttl == DEFAULT_RR_TTL)
    ttl = m_zone.getTtl();

  Name name;
  Rrset rrset;
  std::tie(rrset, name) = generateBaseRrset(label, label::TXT_RR_TYPE, version, ttl);

  std::vector<Block> rrs;
  for (const auto& item : strings) {
    rrs.push_back(makeBinaryBlock(ndns::tlv::RrData,
                                  item.c_str(),
                                  item.size()));
  }

  Data data(name);
  data.setContent(wireEncode(rrs));

  setContentType(data, NDNS_RESP, ttl);
  sign(data);
  rrset.setData(data.wireEncode());

  return rrset;
}

Rrset
RrsetFactory::generateCertRrset(const Name& label,
                                uint64_t version,
                                time::seconds ttl,
                                const ndn::security::v2::Certificate& cert)
{
  if (!m_checked) {
    BOOST_THROW_EXCEPTION(Error("You have to call checkZoneKey before call generate functions"));
  }

  if (ttl == DEFAULT_RR_TTL)
    ttl = m_zone.getTtl();

  Name name;
  Rrset rrset;
  std::tie(rrset, name) = generateBaseRrset(label, label::APPCERT_RR_TYPE, version, ttl);

  Data data(name);
  data.setContent(cert.wireEncode());

  setContentType(data, NDNS_KEY, ttl);
  sign(data);
  rrset.setData(data.wireEncode());

  return rrset;
}

Rrset
RrsetFactory::generateAuthRrset(const Name& label,
                                uint64_t version,
                                time::seconds ttl)
{
  if (!m_checked) {
    BOOST_THROW_EXCEPTION(Error("You have to call checkZoneKey before call generate functions"));
  }

  if (ttl == DEFAULT_RR_TTL)
    ttl = m_zone.getTtl();

  Name name;
  Rrset rrset;
  std::tie(rrset, name) = generateBaseRrset(label, label::NS_RR_TYPE, version, ttl);

  Data data(name);

  setContentType(data, NDNS_AUTH, ttl);
  sign(data);
  rrset.setData(data.wireEncode());

  return rrset;
}

Rrset
RrsetFactory::generateDoeRrset(const Name& label,
                               uint64_t version,
                               time::seconds ttl,
                               const Name& lowerLabel,
                               const Name& upperLabel)
{
  if (!m_checked) {
    BOOST_THROW_EXCEPTION(Error("You have to call checkZoneKey before call generate functions"));
  }

  if (ttl == DEFAULT_RR_TTL)
    ttl = m_zone.getTtl();

  Name name;
  Rrset rrset;
  std::tie(rrset, name) = generateBaseRrset(label, label::DOE_RR_TYPE, version, ttl);

  std::vector<Block> range;
  range.push_back(lowerLabel.wireEncode());
  range.push_back(upperLabel.wireEncode());

  Data data(name);
  data.setContent(wireEncode(range));

  setContentType(data, NDNS_DOE, ttl);
  sign(data);
  rrset.setData(data.wireEncode());

  return rrset;
}


void
RrsetFactory::sign(Data& data)
{
  m_keyChain.sign(data, signingByCertificate(m_dskCertName));
}

void
RrsetFactory::setContentType(Data& data, NdnsContentType contentType,
                             const time::seconds& ttl)
{
  data.setContentType(contentType);
  data.setFreshnessPeriod(ttl);
}

template<encoding::Tag TAG>
inline size_t
RrsetFactory::wireEncode(EncodingImpl<TAG>& block, const std::vector<Block>& rrs) const
{
  // Content :: = CONTENT-TYPE TLV-LENGTH
  //              Block*

  size_t totalLength = 0;
  for (auto iter = rrs.rbegin(); iter != rrs.rend(); ++iter) {
    totalLength += block.prependBlock(*iter);
  }

  totalLength += block.prependVarNumber(totalLength);
  totalLength += block.prependVarNumber(::ndn::tlv::Content);

  return totalLength;
}

const Block
RrsetFactory::wireEncode(const std::vector<Block>& rrs) const
{
  EncodingEstimator estimator;
  size_t estimatedSize = wireEncode(estimator, rrs);
  EncodingBuffer buffer(estimatedSize, 0);
  wireEncode(buffer, rrs);
  return buffer.block();
}

std::vector<std::string>
RrsetFactory::wireDecodeTxt(const Block& wire)
{
  std::vector<std::string> txts;
  wire.parse();

  for (const auto& e : wire.elements()) {
    txts.push_back(std::string(reinterpret_cast<const char*>(e.value()),
                               e.value_size()));
  }

  return txts;
}


} // namespace ndns
} // namespace ndn
