/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2011 University of California, Los Angeles
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 */

#ifndef _CCNX_ENCODING_HELPER_H_
#define _CCNX_ENCODING_HELPER_H_

#include <sys/types.h>

#include "ccnb-parser/ccnb-parser-common.h"
#include "ns3/ptr.h"
#include "ns3/nstime.h"
#include "ns3/buffer.h"

namespace ns3 {

class CcnxNameComponents;

class CcnxInterestHeader;
class CcnxContentObjectHeader;
  
/**
 * \brief Helper to encode/decode ccnb formatted CCNx message
 *
 */
class CcnxEncodingHelper
{
public:
  /**
   * \brief Serialize CcnxInterestHeader to Buffer::Iterator
   * @param start Buffer to store serialized CcnxInterestHeader
   * @param interest Pointer to CcnxInterestHeader to be serialized 
   * @return length of serialized CcnxInterestHeader
   */
  static size_t
  Serialize (Buffer::Iterator start, const CcnxInterestHeader &interest);

  /**
   * \brief Compute the size of serialized CcnxInterestHeader
   * @param interest Pointer to CcnxInterestHeader
   * @return length 
   */
  static size_t
  GetSerializedSize (const CcnxInterestHeader &interest);
  
public:
  static size_t
  AppendBlockHeader (Buffer::Iterator &start, size_t value, CcnbParser::ccn_tt block_type);

  static size_t
  EstimateBlockHeader (size_t value);

  static size_t
  AppendNumber (Buffer::Iterator &start, uint32_t number);

  static size_t
  EstimateNumber (uint32_t number);

  static size_t
  AppendCloser (Buffer::Iterator &start);

  static size_t
  AppendNameComponents (Buffer::Iterator &start, const CcnxNameComponents &name);

  static size_t
  EstimateNameComponents (const CcnxNameComponents &name);

  /**
   * Append a binary timestamp as a BLOB using the ccn binary
   * Timestamp representation (12-bit fraction).
   *
   * @param start start iterator of  the buffer to append to.
   * @param time - Time object
   *
   * @returns written length
   */
  static size_t
  AppendTimestampBlob (Buffer::Iterator &start, const Time &time);

  static size_t
  EstimateTimestampBlob (const Time &time);

  /**
   * Append a tagged BLOB
   *
   * This is a ccnb-encoded element with containing the BLOB as content
   *
   * @param start start iterator of  the buffer to append to.
   * @param dtag is the element's dtab
   * @param data points to the binary data
   * @param size is the size of the data, in bytes
   *
   * @returns written length
   */
  static size_t
  AppendTaggedBlob (Buffer::Iterator &start, CcnbParser::ccn_dtag dtag,
                    const uint8_t *data, size_t size);
  
  static size_t
  EstimateTaggedBlob (CcnbParser::ccn_dtag dtag, size_t size);

  /**
   * Append value as a tagged BLOB (templated version)
   *
   * This is a ccnb-encoded element with containing the BLOB as content
   *
   * Data will be reinterpret_cast<const uint8_t*> and size will be obtained using sizeof
   *
   * @param start start iterator of  the buffer to append to.
   * @param dtag is the element's dtab
   * @param data a value to add
   *
   * @returns written length
   */
  template<class T>
  static inline size_t
  AppendTaggedBlob (Buffer::Iterator &start, CcnbParser::ccn_dtag dtag, const T &data);

  /**
   * Append a tagged string (should be a valid UTF-8 coded string)
   *
   * This is a ccnb-encoded element with containing UDATA as content
   *
   * @param start start iterator of  the buffer to append to.
   * @param dtag is the element's dtab
   * @param string UTF-8 string to be written
   *
   * @returns written length
   */
  static size_t
  AppendString (Buffer::Iterator &start, CcnbParser::ccn_dtag dtag,
                const std::string &string);

  static size_t
  EstimateString (CcnbParser::ccn_dtag dtag, const std::string &string);
};


template<class T>
size_t
CcnxEncodingHelper::AppendTaggedBlob (Buffer::Iterator &start, CcnbParser::ccn_dtag dtag, const T &data)
{
  return AppendTaggedBlob (start, dtag, reinterpret_cast<const uint8_t*> (&data), sizeof (data));
}

} // namespace ns3

#endif // _CCNX_ENCODING_HELPER_H_

