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

#ifndef NDNS_DAEMON_RRSET_FACTORY_HPP
#define NDNS_DAEMON_RRSET_FACTORY_HPP

#include "rrset.hpp"
#include "logger.hpp"
#include "daemon/db-mgr.hpp"
#include "ndns-enum.hpp"

#include <ndn-cxx/link.hpp>
#include <ndn-cxx/security/key-chain.hpp>

#include <boost/filesystem/path.hpp>

namespace ndn {
namespace ndns {

class RrsetFactory
{
public:
  /** @brief Represents an error might be thrown during runtime
   */
  class Error : public std::runtime_error
  {
  public:
    using std::runtime_error::runtime_error;
  };

public:
  RrsetFactory(const boost::filesystem::path& dbFile,
               const Name& zoneName,
               KeyChain& keyChain,
               const Name& inputDskCertName);

  void
  checkZoneKey();

  Rrset
  generateNsRrset(const Name& label,
                  uint64_t version,
                  time::seconds ttl,
                  const ndn::DelegationList& delegations);

  Rrset
  generateTxtRrset(const Name& label,
                   uint64_t version,
                   time::seconds ttl,
                   const std::vector<std::string>& contents);

  Rrset
  generateAuthRrset(const Name& label,
                    uint64_t version,
                    time::seconds ttl);

  Rrset
  generateCertRrset(const Name& label,
                    uint64_t version,
                    time::seconds ttl,
                    const ndn::security::Certificate& cert);

  /**
   * @brief DoE records are just txt records of all entries of a zone
   * which means the any range showed in this record does not exist
   */
  Rrset
  generateDoeRrset(const Name& label,
                   uint64_t version,
                   time::seconds ttl,
                   const Name& lowerLabel,
                   const Name& upperLabel);

  static std::vector<std::string>
  wireDecodeTxt(const Block& wire);

NDNS_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  // only used for database-test-data unit test
  void
  onlyCheckZone();

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

  bool
  matchCertificate(const Name& certName, const Name& identity);

  template<encoding::Tag TAG>
  inline size_t
  wireEncode(EncodingImpl<TAG>& block, const std::vector<Block>& rrs) const;

  const Block
  wireEncode(const std::vector<Block>& rrs) const;

  void
  sign(Data& data);

  void
  setContentType(Data& data, NdnsContentType contentType,
                 const time::seconds& ttl);

private:
  KeyChain& m_keyChain;
  std::string m_dbFile;
  Zone m_zone;
  Name m_dskCertName;
  Name m_dskName;
  bool m_checked;
};

} // namespace ndns
} // namespace ndn

#endif // NDNS_DAEMON_RRSET_FACTORY_HPP
