/* -*- 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-info.hpp"

namespace chronochat {

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


EndorseInfo::EndorseInfo()
{
}

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

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

  // EndorseInfo := ENDORSE-INFO-TYPE TLV-LENGTH
  //                  ENDORSEMENT+
  //
  // Endorsement := ENDORSEMENT-TYPE TLV-LENGTH
  //                  EndorseType
  //                  EndorseValue
  //                  EndorseCount
  //
  // EndorseType := ENDORSETYPE-TYPE TLV-LENGTH
  //                  String
  //
  // EndorseValue := ENDORSEVALUE-TYPE TLV-LENGTH
  //                   String
  // EndorseCount := ENDORSECOUNT-TYPE TLV-LENGTH
  //                   String

  // Entries
  size_t entryLength = 0;
  for (std::vector<Endorsement>::const_reverse_iterator it = m_endorsements.rbegin();
       it != m_endorsements.rend(); it++) {

    // Endorse Count
    const uint8_t *countWire = reinterpret_cast<const uint8_t*>(it->count.c_str());
    entryLength += block.prependByteArrayBlock(tlv::EndorseCount, countWire, it->count.length());

    // Endorse Value
    const uint8_t *valueWire = reinterpret_cast<const uint8_t*>(it->value.c_str());
    entryLength += block.prependByteArrayBlock(tlv::EndorseValue, valueWire, it->value.length());

    // Endorse Type
    const uint8_t *typeWire = reinterpret_cast<const uint8_t*>(it->type.c_str());
    entryLength += block.prependByteArrayBlock(tlv::EndorseType, typeWire, it->type.length());

    // Endorsement
    entryLength += block.prependVarNumber(entryLength);
    entryLength += block.prependVarNumber(tlv::Endorsement);
    totalLength += entryLength;
    entryLength = 0;
  }

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

  return totalLength;

}

const Block&
EndorseInfo::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
EndorseInfo::wireDecode(const Block& endorseWire)
{
  m_wire = endorseWire;
  m_wire.parse();
  m_endorsements.clear();

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

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

  while (i != m_wire.elements_end() && i->type() == tlv::Endorsement) {
    Endorsement endorsement;
    Block temp = *i;
    temp.parse();
    Block::element_const_iterator j = temp.elements_begin();

    // Endorse Type
    if (j == temp.elements_end())
      NDN_THROW(Error("Missing Endorse Type"));
    if (j->type() != tlv::EndorseType)
      NDN_THROW(Error("Expect Endorse Type but get TLV Type " + std::to_string(j->type())));

    endorsement.type = std::string(reinterpret_cast<const char* >(j->value()),
                                   j->value_size());;
    ++j;

    // Endorse Value
    if (j == temp.elements_end())
      NDN_THROW(Error("Missing Endorse Value"));
    if (j->type() != tlv::EndorseValue)
      NDN_THROW(Error("Expect Endorse Value but get TLV Type " + std::to_string(j->type())));

    endorsement.value = std::string(reinterpret_cast<const char* >(j->value()),
                                    j->value_size());
    ++j;

    // Endorse Count
    if (j == temp.elements_end())
      NDN_THROW(Error("Missing Endorse Count"));
    if (j->type() != tlv::EndorseCount)
      NDN_THROW(Error("Expect Endorse Count but get TLV Type " + std::to_string(j->type())));

    endorsement.count = std::string(reinterpret_cast<const char* >(j->value()),
                                    j->value_size());
    ++j;
    if (j != temp.elements_end())
      NDN_THROW(Error("Unexpected element"));

    m_endorsements.push_back(endorsement);
    ++i;
  }

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

void
EndorseInfo::addEndorsement(const std::string& type, const std::string& value,
                            const std::string& count) {
  Endorsement endorsement;
  endorsement.type = type;
  endorsement.value = value;
  endorsement.count = count;
  m_endorsements.push_back(endorsement);
}

} // namespace chronochat
