/* -*- 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_RESPONSE_HPP
#define NDNS_CLIENTS_RESPONSE_HPP

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

#include <ndn-cxx/data.hpp>
#include <ndn-cxx/meta-info.hpp>

namespace ndn {
namespace ndns {

/**
 * @brief Default life time of resource record
 */
const time::seconds DEFAULT_RR_FRESHNESS_PERIOD = 3600_s;


/**
 * @brief NDNS Response abstraction. Response is used on client side,
 * while Rrset is used on server side, and Data packet is used during transmission in network.
 */
class Response
{
public:
  class Error : public ndn::tlv::Error
  {
  public:
    using ndn::tlv::Error::Error;
  };

  Response();

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

  /**
   * @brief fill the attributes from Data packet.
   *
   * @param zone NDNS zone name
   * @param data Data.getName() must the same zone as its prefix,
   *             otherwise it's undefined behavior
   * @return false if Data.getName() does not follow the structure of NDNS Response without
   *         changing any attributes, otherwise return true and fill the attributes
   */
  bool
  fromData(const Name& zone, const Data& data);

  shared_ptr<Data>
  toData();

  Response&
  addRr(const Block& rr);

  /**
   * @brief add Block which contains string information and its tlv type is ndns::tlv::RrData
   *
   * @return Response that is service level information, the encoding level abstraction,
   *         i.e., Block is not very convenient.
   */
  Response&
  addRr(const std::string& rr);

  bool
  removeRr(const Block& rr);

  bool
  operator==(const Response& other) const;

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

  /**
   * @brief encode the app-level data
   */
  Block
  wireEncode() const;

  /**
   * @brief decode the app-level data
   */
  void
  wireDecode(const Block& wire);

  /**
   * @brief encode app-level data
   */
  template<encoding::Tag T>
  size_t
  wireEncode(EncodingImpl<T>& encoder) const;

  static std::pair<Name, Name>
  wireDecodeDoe(const Block& wire);

public: // getter and setter
  const Name&
  getZone() const
  {
    return m_zone;
  }

  void
  setZone(const Name& zone)
  {
    m_zone = zone;
  }

  const name::Component&
  getQueryType() const
  {
    return m_queryType;
  }

  void
  setQueryType(const name::Component& queryType)
  {
    m_queryType = queryType;
  }

  const Name&
  getRrLabel() const
  {
    return m_rrLabel;
  }

  void
  setRrLabel(const Name& rrLabel)
  {
    m_rrLabel = rrLabel;
  }

  void
  setRrType(const name::Component& rrType)
  {
    m_rrType = rrType;
  }

  const name::Component&
  getRrType() const
  {
    return m_rrType;
  }

  void
  setVersion(const name::Component& version)
  {
    m_version = version;
  }

  const name::Component&
  getVersion() const
  {
    return m_version;
  }

  void
  setContentType(NdnsContentType contentType)
  {
    m_contentType = contentType;
  }

  NdnsContentType
  getContentType() const
  {
    return m_contentType;
  }

  const Block&
  getAppContent() const
  {
    return m_appContent;
  }

  void
  setAppContent(const Block& block);

  const std::vector<Block>&
  getRrs() const
  {
    return m_rrs;
  }

  void
  setRrs(const std::vector<Block>& rrs)
  {
    m_rrs = rrs;
  }

  time::seconds
  getFreshnessPeriod() const
  {
    return m_freshnessPeriod;
  }

  void
  setFreshnessPeriod(time::seconds freshnessPeriod)
  {
    m_freshnessPeriod = freshnessPeriod;
  }

private:
  Name m_zone;
  name::Component m_queryType;
  Name m_rrLabel;
  name::Component m_rrType;
  name::Component m_version;

  NdnsContentType m_contentType;
  time::seconds m_freshnessPeriod;

  /**
   * @brief App content. Be valid only for NDNS-NULL Response
   */
  Block m_appContent;

  /**
   * @brief Content of Resource Record. Be valid only when this is not a NDNS-NULL Response
   */
  std::vector<Block> m_rrs;
};

std::ostream&
operator<<(std::ostream& os, const Response& response);

} // namespace ndns
} // namespace ndn

#endif // NDNS_CLIENTS_RESPONSE_HPP
