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

#include "zone.hpp"
#include "rrset.hpp"
#include "db-mgr.hpp"
#include "ndns-label.hpp"
#include "ndns-tlv.hpp"
#include "validator/validator.hpp"

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

#include <sstream>
#include <stdexcept>

namespace ndn {
namespace ndns {

/**
 * @brief provides authoritative name server.
 *
 * The authoritative name server handles NDNS query and update.
 */
class NameServer : boost::noncopyable
{
  DEFINE_ERROR(Error, std::runtime_error);

public:
  explicit
  NameServer(const Name& zoneName, const Name& certName, Face& face, DbMgr& dbMgr,
             KeyChain& keyChain, security::Validator& validator);

NDNS_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  void
  onInterest(const Name& prefix, const Interest& interest);

  /**
   * @brief handle NDNS query message
   */
  void
  handleQuery(const Name& prefix, const Interest& interest, const label::MatchResult& re);

  /**
   * @brief handle NDNS update message
   */
  void
  handleUpdate(const Name& prefix, const Interest& interest, const label::MatchResult& re);

  void
  onRegisterFailed(const ndn::Name& prefix, const std::string& reason);

  void
  doUpdate(const shared_ptr<const Interest>& interest, const shared_ptr<const Data>& data);

public:
  const Name&
  getNdnsPrefix()
  {
    return m_ndnsPrefix;
  }

  const Zone&
  getZone() const
  {
    return m_zone;
  }

  const time::milliseconds&
  getContentFreshness() const
  {
    return m_contentFreshness;
  }

  /**
   * @brief set the Data fresh period
   */
  void
  setContentFreshness(const time::milliseconds& contentFreshness)
  {
    BOOST_ASSERT(contentFreshness > time::milliseconds::zero());
    m_contentFreshness = contentFreshness;
  }

private:
  Zone m_zone;
  DbMgr& m_dbMgr;

  Name m_ndnsPrefix;
  Name m_certName;

  time::milliseconds m_contentFreshness;

  Face& m_face;
  KeyChain& m_keyChain;
  security::Validator& m_validator;
};

} // namespace ndns
} // namespace ndn

#endif // NDNS_DAEMON_NAME_SERVER_HPP
