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

#include "ndns-label.hpp"
#include "ndns-enum.hpp"

#include <ndn-cxx/name.hpp>
#include <ndn-cxx/link.hpp>

namespace ndn {
namespace ndns {

/**
 * @brief NDNS Query abstraction
 *
 * Query is an Interest whose name follows the format:
 *
 *      <zone> [<NDNS>|<NDNS-R>] <rrLabel> <rrType>
 */
class Query : boost::noncopyable
{
public:
  Query();

  Query(const Name& zone, const name::Component& queryType);

  /**
   * @brief construct an Interest according to the query abstraction
   */
  Interest
  toInterest() const;

  /**
   * @brief extract the query information (rrLabel, rrType) from a Interest
   *
   * @param zone     NDNS zone
   * @param interest The Interest to parse; the Interest must have correct zone,
   *                 otherwise it's undefined behavior
   */
  bool
  fromInterest(const Name& zone, const Interest& interest);

  void
  setForwardingHintFromLink(const Link& link);

  bool
  operator==(const Query& other) const
  {
    return (getZone() == other.getZone() &&
      getQueryType() == other.getQueryType() && getRrLabel() == other.getRrLabel() &&
      getRrType() == other.getRrType());
  }

  bool
  operator!=(const Query& other) const
  {
    return !(*this == other);
  }

public:

  /**
   * @brief get name of authoritative zone
   */
  const Name&
  getZone() const
  {
    return m_zone;
  }

  /**
   * @brief set name of authoritative zone
   */
  void
  setZone(const Name& zone)
  {
    m_zone = zone;
  }

  /**
   * @brief get lifetime of the Interest
   */
  const time::milliseconds&
  getInterestLifetime() const
  {
    return m_interestLifetime;
  }

  /**
   * @brief set lifetime of the Interest
   */
  void
  setInterestLifetime(const time::milliseconds& interestLifetime)
  {
    m_interestLifetime = interestLifetime;
  }


  /**
   * @brief get query type
   */
  const name::Component&
  getQueryType() const
  {
    return m_queryType;
  }

  /**
   * @brief get query type
   */
  void
  setQueryType(const name::Component& queryType)
  {
    m_queryType = queryType;
  }

  /**
   * @brief get label of resource record
   */
  const Name&
  getRrLabel() const
  {
    return m_rrLabel;
  }

  /**
   * @brief set label of resource record
   */
  void
  setRrLabel(const Name& rrLabel)
  {
    m_rrLabel = rrLabel;
  }

  /**
   * @brief get type resource record
   */
  const name::Component&
  getRrType() const
  {
    return m_rrType;
  }

  /**
   * @brief set type resource record
   */
  void
  setRrType(const name::Component& rrType)
  {
    m_rrType = rrType;
  }

  /**
   * @brief set ForwardingHint
   */
  void
  setForwardingHint(std::vector<Name> forwardingHint)
  {
    m_forwardingHint = std::move(forwardingHint);
  }

  /**
   * @brief get ForwardingHint
   */
  span<const Name>
  getForwardingHint() const
  {
    return m_forwardingHint;
  }

private:
  Name m_zone;
  name::Component m_queryType;
  Name m_rrLabel;
  name::Component m_rrType;
  time::milliseconds m_interestLifetime;
  std::vector<Name> m_forwardingHint;
};

std::ostream&
operator<<(std::ostream& os, const Query& query);

} // namespace ndns
} // namespace ndn

#endif // NDNS_CLIENTS_QUERY_HPP
