/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2013 Regents of the University of California.
 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
 * See COPYING for copyright and distribution information.
 */

#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"

namespace ndn {
  
class Data {
public:
  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
  
  /**
   * @brief Create an empty Data object
   */
  inline
  Data();
  
  /**
   * @brief Create a new Data object with the given name
   * @param name A reference to the name which is copied.
   */
  inline
  Data(const Name& name);
  
  /**
   * @brief The virtual destructor.
   */
  inline virtual
  ~Data();
  
  /**
   * @brief Encode this Data for a wire format.
   * @return The encoded byte array.
   */
  const Block& 
  wireEncode() const;
  
  /**
   * @brief Decode the input using a particular wire format and update this Data. 
   * @param input The input byte array to be decoded.
   */
  void
  wireDecode(const Block &wire);

  inline const Name& 
  getName() const;
  
  /**
   * @brief Set name to a copy of the given Name.
   *
   * @param name The Name which is copied.
   * @return This Data so that you can chain calls to update values.
   */
  inline void
  setName(const Name& name);

  inline const MetaInfo& 
  getMetaInfo() const;
  
  /**
   * @brief Set metaInfo to a copy of the given MetaInfo.
   * @param metaInfo The MetaInfo which is copied.
   * @return This Data so that you can chain calls to update values.
   */
  inline void
  setMetaInfo(const MetaInfo& metaInfo);

  ///////////////////////////////////////////////////////////////
  // MetaInfo proxy methods
  inline uint32_t 
  getContentType() const;
  
  inline void 
  setContentType(uint32_t type);
  
  inline Milliseconds 
  getFreshnessPeriod() const;
  
  inline void 
  setFreshnessPeriod(Milliseconds freshnessPeriod);
  
  /**
   * @brief Get content Block
   *
   * To access content value, one can use value()/value_size() or
   * value_begin()/value_end() methods of the Block class
   */
  inline const Block& 
  getContent() const;

  /**
   * @brief Set the content to a copy of the data in the vector.
   * @param content A vector whose contents are copied.
   * @return This Data so that you can chain calls to update values.
   */
  inline void
  setContent(const uint8_t* content, size_t contentLength);

  inline void
  setContent(const Block& content);

  inline void
  setContent(const ConstBufferPtr &contentValue);
  
  inline const Signature&
  getSignature() const;
  
  /**
   * @brief Set the signature to a copy of the given signature.
   * @param signature The signature object which is cloned.
   * @return This Data so that you can chain calls to update values.
   */
  inline Data& 
  setSignature(const Signature& signature);

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

private:
  Name name_;
  MetaInfo metaInfo_;
  mutable Block content_;
  Signature signature_;

  mutable Block wire_;
};

inline
Data::Data()
{
}

inline
Data::Data(const Name& name)
  : name_(name)
{
}

inline
Data::~Data()
{
}

inline const Name& 
Data::getName() const
{
  return name_;
}
  
inline void
Data::setName(const Name& name)
{ 
  onChanged();
  name_ = name; 
}
  
inline const MetaInfo& 
Data::getMetaInfo() const
{
  return metaInfo_;
}
  
inline void
Data::setMetaInfo(const MetaInfo& metaInfo) 
{ 
  onChanged();
  metaInfo_ = metaInfo; 
}

inline uint32_t 
Data::getContentType() const
{
  return metaInfo_.getType();
}
  
inline void 
Data::setContentType(uint32_t type)
{
  onChanged();
  metaInfo_.setType(type);
}
  
inline Milliseconds 
Data::getFreshnessPeriod() const
{
  return metaInfo_.getFreshnessPeriod();
}
  
inline void 
Data::setFreshnessPeriod(Milliseconds freshnessPeriod)
{
  onChanged();
  metaInfo_.setFreshnessPeriod(freshnessPeriod);
}

inline const Block& 
Data::getContent() const
{
  if (!content_.hasWire())
      content_.encode();
  return content_;
}

inline void
Data::setContent(const uint8_t* content, size_t contentLength) 
{
  onChanged();

  OBufferStream os;
  Tlv::writeVarNumber(os, Tlv::Content);
  Tlv::writeVarNumber(os, contentLength);
  os.write(reinterpret_cast<const char *>(content), contentLength);
    
  content_ = Block(os.buf());
}

inline void
Data::setContent(const ConstBufferPtr &contentValue)
{
  onChanged();

  content_ = Block(Tlv::Content, contentValue); // not real a wire encoding yet
}
  
inline void
Data::setContent(const Block& content) 
{ 
  onChanged();

  content_ = content;
}

inline const Signature&
Data::getSignature() const
{
  return signature_;
}
  
inline Data& 
Data::setSignature(const Signature& signature) 
{
  onChanged();
  signature_ = signature;

  return *this;
}

inline void 
Data::onChanged()
{
  // The values have changed, so the wire format is invalidated

  // !!!Note!!! Signature is not invalidated and it is responsibility of
  // the application to do proper re-signing if necessary
  
  wire_ = Block();
}

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

} // namespace ndn

#endif
