/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2015 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 "detail/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;
  detail::FieldInfo prev;
  for (const Block& element : wire.elements()) {
    detail::FieldInfo info(element.type());

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

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

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

    isFirst = false;
    prev = info;
  }

  m_wire = wire;
}

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

} // namespace lp
} // namespace ndn
