/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2017 Regents of the University of California.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * ndn-cxx library 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 Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 */

#include "packet.hpp"
#include "field-info.hpp"

#include <boost/range/adaptor/reversed.hpp>

namespace ndn {
namespace lp {

Packet::Packet()
  : m_wire(Block(tlv::LpPacket))
{
}

Packet::Packet(const Block& wire)
{
  wireDecode(wire);
}

template<encoding::Tag TAG>
size_t
Packet::wireEncode(EncodingImpl<TAG>& encoder) const
{
  if (m_wire.hasWire()) {
    return m_wire.size();
  }

  size_t length = 0;

  for (const Block& element : boost::adaptors::reverse(m_wire.elements())) {
    length += encoder.prependBlock(element);
  }

  length += encoder.prependVarNumber(length);
  length += encoder.prependVarNumber(tlv::LpPacket);

  return length;
}

template size_t
Packet::wireEncode<encoding::EncoderTag>(EncodingImpl<encoding::EncoderTag>& encoder) const;

template size_t
Packet::wireEncode<encoding::EstimatorTag>(EncodingImpl<encoding::EstimatorTag>& encoder) const;

Block
Packet::wireEncode() const
{
  if (m_wire.hasWire()) {
    return m_wire;
  }

  // If no header or trailer, return bare network packet
  Block::element_container elements = m_wire.elements();
  if (elements.size() == 1 && elements.front().type() == FragmentField::TlvType::value) {
    elements.front().parse();
    elements.front().elements().front().parse();
    return elements.front().elements().front();
  }

  EncodingEstimator estimator;
  size_t estimatedSize = wireEncode(estimator);

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

  m_wire = buffer.block();
  return m_wire;
}

void
Packet::wireDecode(const Block& wire)
{
  if (wire.type() == ndn::tlv::Interest || wire.type() == ndn::tlv::Data) {
    m_wire = Block(tlv::LpPacket);
    add<FragmentField>(make_pair(wire.begin(), wire.end()));
    return;
  }

  if (wire.type() != tlv::LpPacket) {
    BOOST_THROW_EXCEPTION(Error("unrecognized TLV-TYPE " + to_string(wire.type())));
  }

  wire.parse();

  bool isFirst = true;
  FieldInfo prev;
  for (const Block& element : wire.elements()) {
    FieldInfo info(element.type());

    if (!info.isRecognized && !info.canIgnore) {
      BOOST_THROW_EXCEPTION(Error("unrecognized field " + to_string(element.type()) + " cannot be ignored"));
    }

    if (!isFirst) {
      if (info.tlvType == prev.tlvType && !info.isRepeatable) {
        BOOST_THROW_EXCEPTION(Error("non-repeatable field " + to_string(element.type()) + " cannot be repeated"));
      }

      else if (info.tlvType != prev.tlvType && !compareFieldSortOrder(prev, info)) {
        BOOST_THROW_EXCEPTION(Error("fields are not in correct sort order"));
      }
    }

    isFirst = false;
    prev = info;
  }

  m_wire = wire;
}

bool
Packet::comparePos(uint64_t first, const Block& second)
{
  FieldInfo firstInfo(first);
  FieldInfo secondInfo(second.type());
  return compareFieldSortOrder(firstInfo, secondInfo);
}

} // namespace lp
} // namespace ndn
