/* -*- 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.
   *
   * This is virtual so that a subclass can override to validate the name.
   *
   * @param name The Name which is copied.
   * @return This Data so that you can chain calls to update values.
   */
  inline virtual 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();
}

} // namespace ndn

#endif
