/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2020, Regents of the University of California
 *
 * BSD license, See the LICENSE file for more information
 *
 * Author: Qiuhan Ding <qiuhanding@cs.ucla.edu>
 */

#include "endorse-extension.hpp"

namespace chronochat {

BOOST_CONCEPT_ASSERT((ndn::WireEncodable<EndorseExtension>));
BOOST_CONCEPT_ASSERT((ndn::WireDecodable<EndorseExtension>));

EndorseExtension::EndorseExtension()
{
}

EndorseExtension::EndorseExtension(const Block& endorseWire)
{
  this->wireDecode(endorseWire);
}

template<ndn::encoding::Tag T>
size_t
EndorseExtension::wireEncode(ndn::EncodingImpl<T>& block) const
{
  size_t totalLength = 0;

  // EndorseExtension := ENDORSE-EXTENSION-TYPE TLV-LENGTH
  //                       EntryData+
  //
  // EntryData := ENTRYDATA-TYPE TLV-LENGTH
  //                String
  //

  // EntryData
  for (std::list<std::string>::const_reverse_iterator it = m_entries.rbegin();
       it != m_entries.rend(); it++) {
    const uint8_t *entryWire = reinterpret_cast<const uint8_t*>(it->c_str());
    totalLength += block.prependByteArrayBlock(tlv::EntryData, entryWire, it->length());
  }

  // EndorseExtension
  totalLength += block.prependVarNumber(totalLength);
  totalLength += block.prependVarNumber(tlv::EndorseExtension);

  return totalLength;
}

const Block&
EndorseExtension::wireEncode() const
{
  ndn::EncodingEstimator estimator;
  size_t estimatedSize = wireEncode(estimator);

  ndn::EncodingBuffer buffer(estimatedSize, 0);
  wireEncode(buffer);

  m_wire = buffer.block();
  m_wire.parse();

  return m_wire;
}

void
EndorseExtension::wireDecode(const Block& endorseWire)
{
  m_wire = endorseWire;
  m_wire.parse();

  // EndorseExtension := ENDORSE-EXTENSION-TYPE TLV-LENGTH
  //                       EntryData+
  //
  // EntryData := ENTRYDATA-TYPE TLV-LENGTH
  //                String
  //

  if (m_wire.type() != tlv::EndorseExtension)
    NDN_THROW(Error("Unexpected TLV number when decoding endorse extension packet"));

  // EntryData
  Block::element_const_iterator i = m_wire.elements_begin();
  if (i == m_wire.elements_end())
    NDN_THROW(Error("Missing Entry Data"));
  if (i->type() != tlv::EntryData)
    NDN_THROW(Error("Expect Entry Data but get TLV Type " + std::to_string(i->type())));

   while (i != m_wire.elements_end() && i->type() == tlv::EntryData) {
     m_entries.push_back(std::string(reinterpret_cast<const char* >(i->value()),
                                     i->value_size()));
     ++i;
  }

  if (i != m_wire.elements_end())
    NDN_THROW(Error("Unexpected element"));
}

void
EndorseExtension::addEntry(const std::string& entry)
{
  if (find(m_entries.begin(), m_entries.end(), entry) == m_entries.end()) {
    m_entries.push_back(entry);
  }
}

void
EndorseExtension::removeEntry(const std::string& entry)
{
  m_entries.remove(entry);
}

} // namespace chronochat
