/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013-2020 Regents of the University of California.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * ndn-cxx library 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 Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 */

#ifndef NDN_CXX_DATA_HPP
#define NDN_CXX_DATA_HPP

#include "ndn-cxx/detail/packet-base.hpp"
#include "ndn-cxx/encoding/block.hpp"
#include "ndn-cxx/meta-info.hpp"
#include "ndn-cxx/name.hpp"
#include "ndn-cxx/security/security-common.hpp"
#include "ndn-cxx/signature-info.hpp"

namespace ndn {

/** @brief Represents a %Data packet.
 *  @sa https://named-data.net/doc/NDN-packet-spec/0.3/data.html
 */
class Data : public PacketBase, public std::enable_shared_from_this<Data>
{
public:
  class Error : public tlv::Error
  {
  public:
    using tlv::Error::Error;
  };

  /** @brief Construct an unsigned Data packet with given @p name and empty Content.
   *  @warning In certain contexts that use `Data::shared_from_this()`, Data must be created using
   *           `std::make_shared`. Otherwise, `shared_from_this()` may trigger undefined behavior.
   *           One example where this is necessary is storing Data into a subclass of InMemoryStorage.
   */
  explicit
  Data(const Name& name = Name());

  /** @brief Construct a Data packet by decoding from @p wire.
   *  @param wire TLV block of type tlv::Data; may be signed or unsigned.
   *  @warning In certain contexts that use `Data::shared_from_this()`, Data must be created using
   *           `std::make_shared`. Otherwise, `shared_from_this()` may trigger undefined behavior.
   *           One example where this is necessary is storing Data into a subclass of InMemoryStorage.
   */
  explicit
  Data(const Block& wire);

  /** @brief Prepend wire encoding to @p encoder
   *  @param encoder EncodingEstimator or EncodingBuffer instance.
   *  @param wantUnsignedPortionOnly If true, prepend only Name, MetaInfo, Content, and
   *         SignatureInfo to @p encoder, but omit SignatureValue and the outermost TLV
   *         Type and Length of the Data element. This is intended to be used with
   *         wireEncode(EncodingBuffer&, const Block&) const.
   *  @throw Error %Signature is not present and @p wantUnsignedPortionOnly is false.
   */
  template<encoding::Tag TAG>
  size_t
  wireEncode(EncodingImpl<TAG>& encoder, bool wantUnsignedPortionOnly = false) const;

  /** @brief Finalize Data packet encoding with the specified SignatureValue
   *  @param encoder EncodingBuffer containing Name, MetaInfo, Content, and SignatureInfo, but
   *                 without SignatureValue and the outermost Type-Length of the Data element.
   *  @param signatureValue SignatureValue element.
   *
   *  This method is intended to be used in concert with `wireEncode(encoder, true)`, e.g.:
   *  @code
   *     Data data;
   *     ...
   *     EncodingBuffer encoder;
   *     data.wireEncode(encoder, true);
   *     ...
   *     Block signatureValue = <sign_over_unsigned_portion>(encoder.buf(), encoder.size());
   *     data.wireEncode(encoder, signatureValue)
   *  @endcode
   */
  const Block&
  wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const;

  /** @brief Encode into a Block.
   *  @pre Data must be signed.
   */
  const Block&
  wireEncode() const;

  /** @brief Decode from @p wire.
   */
  void
  wireDecode(const Block& wire);

  /** @brief Check if this instance has cached wire encoding.
   */
  bool
  hasWire() const noexcept
  {
    return m_wire.hasWire();
  }

  /** @brief Get full name including implicit digest
   *  @pre hasWire() == true; i.e. wireEncode() must have been called
   *  @throw Error Data has no wire encoding
   */
  const Name&
  getFullName() const;

public: // Data fields
  /** @brief Get name
   */
  const Name&
  getName() const noexcept
  {
    return m_name;
  }

  /** @brief Set name
   *  @return a reference to this Data, to allow chaining
   */
  Data&
  setName(const Name& name);

  /** @brief Get MetaInfo
   */
  const MetaInfo&
  getMetaInfo() const noexcept
  {
    return m_metaInfo;
  }

  /** @brief Set MetaInfo
   *  @return a reference to this Data, to allow chaining
   */
  Data&
  setMetaInfo(const MetaInfo& metaInfo);

  /**
   * @brief Return whether this Data has a Content element
   */
  bool
  hasContent() const noexcept
  {
    return m_content.isValid();
  }

  /**
   * @brief Get the Content element
   *
   * If the element is not present (hasContent() == false), an invalid Block will be returned.
   *
   * The value of the returned Content Block (if valid) can be accessed through
   * Block::value() / Block::value_size() or Block::value_begin() / Block::value_end().
   *
   * @sa hasContent()
   * @sa Block::blockFromValue(), Block::parse()
   */
  const Block&
  getContent() const noexcept
  {
    return m_content;
  }

  /**
   * @brief Set Content from a Block
   * @param block TLV block to be used as Content; must be valid
   * @return a reference to this Data, to allow chaining
   *
   * If the block's TLV-TYPE is tlv::Content, it will be used directly as this Data's
   * Content element. Otherwise, the block will be nested into a Content element.
   */
  Data&
  setContent(const Block& block);

  /**
   * @brief Set Content by copying from a raw buffer
   * @param value buffer with the TLV-VALUE of the content; may be nullptr if @p length is zero
   * @param length size of the buffer
   * @return a reference to this Data, to allow chaining
   */
  Data&
  setContent(const uint8_t* value, size_t length);

  /**
   * @brief Set Content from a shared buffer
   * @param value buffer with the TLV-VALUE of the content; must not be nullptr
   * @return a reference to this Data, to allow chaining
   */
  Data&
  setContent(ConstBufferPtr value);

  /**
   * @brief Remove the Content element
   * @return a reference to this Data, to allow chaining
   * @post hasContent() == false
   */
  Data&
  unsetContent();

  /** @brief Get SignatureInfo
   */
  const SignatureInfo&
  getSignatureInfo() const noexcept
  {
    return m_signatureInfo;
  }

  /** @brief Set SignatureInfo
   *
   *  This is a low-level function that should not normally be called directly by applications.
   *  Instead, provide a SignatureInfo to the SigningInfo object passed to KeyChain::sign().
   *
   *  @return a reference to this Data, to allow chaining
   *  @warning SignatureInfo is overwritten when the packet is signed via KeyChain::sign().
   *  @sa SigningInfo
   */
  Data&
  setSignatureInfo(const SignatureInfo& info);

  /** @brief Get SignatureValue
   */
  const Block&
  getSignatureValue() const noexcept
  {
    return m_signatureValue;
  }

  /** @brief Set SignatureValue
   *  @param value buffer containing the TLV-VALUE of the SignatureValue; must not be nullptr
   *
   *  This is a low-level function that should not normally be called directly by applications.
   *  Instead, use KeyChain::sign() to sign the packet.
   *
   *  @return a reference to this Data, to allow chaining
   *  @warning SignatureValue is overwritten when the packet is signed via KeyChain::sign().
   */
  Data&
  setSignatureValue(ConstBufferPtr value);

  /** @brief Extract ranges of Data covered by the signature
   *  @throw Error Data cannot be encoded or is missing ranges necessary for signing
   *  @warning The returned pointers will be invalidated if wireDecode() or wireEncode() are called.
   */
  InputBuffers
  extractSignedRanges() const;

public: // MetaInfo fields
  uint32_t
  getContentType() const
  {
    return m_metaInfo.getType();
  }

  Data&
  setContentType(uint32_t type);

  time::milliseconds
  getFreshnessPeriod() const
  {
    return m_metaInfo.getFreshnessPeriod();
  }

  Data&
  setFreshnessPeriod(time::milliseconds freshnessPeriod);

  const optional<name::Component>&
  getFinalBlock() const
  {
    return m_metaInfo.getFinalBlock();
  }

  Data&
  setFinalBlock(optional<name::Component> finalBlockId);

public: // SignatureInfo fields
  /** @brief Get SignatureType
   *  @return tlv::SignatureTypeValue, or -1 to indicate the signature is invalid
   */
  int32_t
  getSignatureType() const noexcept
  {
    return m_signatureInfo.getSignatureType();
  }

  /** @brief Get KeyLocator
   */
  optional<KeyLocator>
  getKeyLocator() const noexcept
  {
    return m_signatureInfo.hasKeyLocator() ? make_optional(m_signatureInfo.getKeyLocator()) : nullopt;
  }

protected:
  /** @brief Clear wire encoding and cached FullName
   *  @note This does not clear the SignatureValue.
   */
  void
  resetWire();

private:
  Name m_name;
  MetaInfo m_metaInfo;
  Block m_content;
  SignatureInfo m_signatureInfo;
  Block m_signatureValue;

  mutable Block m_wire;
  mutable Name m_fullName; // cached FullName computed from m_wire
};

#ifndef DOXYGEN
extern template size_t
Data::wireEncode<encoding::EncoderTag>(EncodingBuffer&, bool) const;

extern template size_t
Data::wireEncode<encoding::EstimatorTag>(EncodingEstimator&, bool) const;
#endif

std::ostream&
operator<<(std::ostream& os, const Data& data);

bool
operator==(const Data& lhs, const Data& rhs);

inline bool
operator!=(const Data& lhs, const Data& rhs)
{
  return !(lhs == rhs);
}

} // namespace ndn

#endif // NDN_CXX_DATA_HPP
