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

#include "common.hpp"
#include "name.hpp"
#include "encoding/block.hpp"

#include "signature.hpp"
#include "meta-info.hpp"
#include "key-locator.hpp"
#include "management/nfd-local-control-header.hpp"
#include "tag-host.hpp"

namespace ndn {

/** @brief represents a Data packet
 */
class Data : public TagHost, public enable_shared_from_this<Data>
{
public:
  class Error : public tlv::Error
  {
  public:
    explicit
    Error(const std::string& what)
      : tlv::Error(what)
    {
    }
  };

  /**
   * @brief Create an empty Data object
   *
   * Note that in certain contexts that use Data::shared_from_this(), Data must be
   * created using `make_shared`:
   *
   *     shared_ptr<Data> data = make_shared<Data>();
   *
   * Otherwise, Data::shared_from_this() will throw an exception.
   */
  Data();

  /**
   * @brief Create a new Data object with the given name
   *
   * @param name A reference to the name
   *
   * Note that in certain contexts that use Data::shared_from_this(), Data must be
   * created using `make_shared`:
   *
   *     shared_ptr<Data> data = make_shared<Data>(name);
   *
   * Otherwise, Data::shared_from_this() will throw an exception.
   */
  Data(const Name& name);

  /**
   * @brief Create a new Data object from wire encoding
   *
   * Note that in certain contexts that use Data::shared_from_this(), Data must be
   * created using `make_shared`:
   *
   *     shared_ptr<Data> data = make_shared<Data>(wire);
   *
   * Otherwise, Data::shared_from_this() will throw an exception.
   */
  explicit
  Data(const Block& wire);

  /**
   * @brief Fast encoding or block size estimation
   *
   * @param block                   EncodingEstimator or EncodingBuffer instance
   * @param wantUnsignedPortionOnly Request only unsigned portion to be encoded in block.
   *                                If true, only Name, MetaInfo, Content, and SignatureInfo
   *                                blocks will be encoded into the block. Note that there
   *                                will be no outer TLV header of the Data packet.
   */
  template<bool T>
  size_t
  wireEncode(EncodingImpl<T>& block, bool wantUnsignedPortionOnly = false) const;

  /**
   * @brief Encode to a wire format
   */
  const Block&
  wireEncode() const;

  /**
   * @brief Finalize Data packet encoding with the specified SignatureValue
   *
   * @param encoder        EncodingBuffer instance, containing Name, MetaInfo, Content, and
   *                       SignatureInfo (without outer TLV header of the Data packet).
   * @param signatureValue SignatureValue block to be added to Data packet to finalize
   *                       the wire encoding
   *
   * This method is intended to be used in concert with Data::wireEncode(EncodingBuffer&, true)
   * method to optimize Data packet wire format creation:
   *
   *     Data data;
   *     ...
   *     EncodingBuffer encoder;
   *     data.wireEncode(encoder, true);
   *     ...
   *     Block signatureValue = <sign_over_unsigned_portion>(encoder.buf(), encoder.size());
   *     data.wireEncode(encoder, signatureValue)
   */
  const Block&
  wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const;

  /**
   * @brief Decode from the wire format
   */
  void
  wireDecode(const Block& wire);

  /**
   * @brief Check if Data is already has wire encoding
   */
  bool
  hasWire() const;

  ////////////////////////////////////////////////////////////////////

  /**
   * @brief Get name of the Data packet
   */
  const Name&
  getName() const;

  /**
   * @brief Set name to a copy of the given Name
   *
   * @return This Data so that you can chain calls to update values
   */
  Data&
  setName(const Name& name);

  //

  /**
   * @brief Get full name of Data packet, including the implicit digest
   *
   * @throws Error if Data packet doesn't have a full name yet (wire encoding has not been
   *         yet created)
   */
  const Name&
  getFullName() const;

  /**
   * @brief Get MetaInfo block from Data packet
   */
  const MetaInfo&
  getMetaInfo() const;

  /**
   * @brief Set metaInfo to a copy of the given MetaInfo
   *
   * @return This Data so that you can chain calls to update values.
   */
  Data&
  setMetaInfo(const MetaInfo& metaInfo);

  //

  ///////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////
  // MetaInfo proxy methods

  uint32_t
  getContentType() const;

  Data&
  setContentType(uint32_t type);

  //

  const time::milliseconds&
  getFreshnessPeriod() const;

  Data&
  setFreshnessPeriod(const time::milliseconds& freshnessPeriod);

  //

  const name::Component&
  getFinalBlockId() const;

  Data&
  setFinalBlockId(const name::Component& finalBlockId);

  //
  ///////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////

  /**
   * @brief Get content Block
   *
   * To access content value, one can use value()/value_size() or
   * value_begin()/value_end() methods of the Block class
   */
  const Block&
  getContent() const;

  /**
   * @brief Set the content from the buffer (buffer will be copied)
   *
   * @param buffer Pointer to first byte of the buffer
   * @param bufferSize Size of the buffer
   *
   * @return This Data so that you can chain calls to update values.
   */
  Data&
  setContent(const uint8_t* buffer, size_t bufferSize);

  /**
   * @brief Set the content from the block
   *
   * Depending on type of the supplied block, there are two cases:
   *
   * - if block.type() == tlv::Content, then block will be used directly as Data packet's
   *   content (no extra copying)
   *
   * - if block.type() != tlv::Content, then this method will create a new Block with type
   *   tlv::Content and put block as a nested element in the content Block.
   *
   * @param block The Block containing the content to assign
   *
   * @return This Data so that you can chain calls to update values.
   */
  Data&
  setContent(const Block& block);

  /**
   * @brief Set the content from the pointer to immutable buffer
   *
   * This method will create a Block with tlv::Content and set contentValue as a payload
   * for this block.  Note that this method is very different from setContent(const
   * Block&), since it does not require that payload should be a valid TLV element.
   *
   * @param contentValue The pointer to immutable buffer containing the content to assign
   *
   * @return This Data so that you can chain calls to update values.
   */
  Data&
  setContent(const ConstBufferPtr& contentValue);

  //

  const Signature&
  getSignature() const;

  /**
   * @brief Set the signature to a copy of the given signature.
   * @param signature The signature object which is cloned.
   */
  Data&
  setSignature(const Signature& signature);

  Data&
  setSignatureValue(const Block& value);

  ///////////////////////////////////////////////////////////////

  nfd::LocalControlHeader&
  getLocalControlHeader();

  const nfd::LocalControlHeader&
  getLocalControlHeader() const;

  uint64_t
  getIncomingFaceId() const;

  Data&
  setIncomingFaceId(uint64_t incomingFaceId);

public: // EqualityComparable concept
  bool
  operator==(const Data& other) const;

  bool
  operator!=(const Data& other) const;

private:
  /**
   * @brief Clear the wire encoding.
   */
  void
  onChanged();

private:
  Name m_name;
  MetaInfo m_metaInfo;
  mutable Block m_content;
  Signature m_signature;

  mutable Block m_wire;
  mutable Name m_fullName;

  nfd::LocalControlHeader m_localControlHeader;
  friend class nfd::LocalControlHeader;
};

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

inline bool
Data::hasWire() const
{
  return m_wire.hasWire();
}

inline const Name&
Data::getName() const
{
  return m_name;
}

inline const MetaInfo&
Data::getMetaInfo() const
{
  return m_metaInfo;
}

inline uint32_t
Data::getContentType() const
{
  return m_metaInfo.getType();
}

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

inline const name::Component&
Data::getFinalBlockId() const
{
  return m_metaInfo.getFinalBlockId();
}

inline const Signature&
Data::getSignature() const
{
  return m_signature;
}

inline nfd::LocalControlHeader&
Data::getLocalControlHeader()
{
  return m_localControlHeader;
}

inline const nfd::LocalControlHeader&
Data::getLocalControlHeader() const
{
  return m_localControlHeader;
}

inline uint64_t
Data::getIncomingFaceId() const
{
  return getLocalControlHeader().getIncomingFaceId();
}


} // namespace ndn

#endif
