/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014  Regents of the University of California,
 *                     Arizona Board of Regents,
 *                     Colorado State University,
 *                     University Pierre & Marie Curie, Sorbonne University,
 *                     Washington University in St. Louis,
 *                     Beijing Institute of Technology
 *
 * This file is part of NFD (Named Data Networking Forwarding Daemon).
 * See AUTHORS.md for complete list of NFD authors and contributors.
 *
 * NFD is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * NFD 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
 * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 **/

#include "ndnlp-slicer.hpp"

#include <ndn-cxx/encoding/encoding-buffer.hpp>

namespace nfd {
namespace ndnlp {

Slicer::Slicer(size_t mtu)
  : m_mtu(mtu)
{
  this->estimateOverhead();
}

Slicer::~Slicer()
{
}

template<bool T>
static inline size_t
Slicer_encodeFragment(ndn::EncodingImpl<T>& blk,
                      uint64_t seq, uint16_t fragIndex, uint16_t fragCount,
                      const uint8_t* payload, size_t payloadSize)
{
  size_t totalLength = 0;

  // NdnlpPayload
  size_t payloadLength = blk.prependByteArray(payload, payloadSize);
  totalLength += payloadLength;
  totalLength += blk.prependVarNumber(payloadLength);
  totalLength += blk.prependVarNumber(tlv::NdnlpPayload);

  bool needFragIndexAndCount = fragCount > 1;
  if (needFragIndexAndCount) {
    // NdnlpFragCount
    size_t fragCountLength = blk.prependNonNegativeInteger(fragCount);
    totalLength += fragCountLength;
    totalLength += blk.prependVarNumber(fragCountLength);
    totalLength += blk.prependVarNumber(tlv::NdnlpFragCount);

    // NdnlpFragIndex
    size_t fragIndexLength = blk.prependNonNegativeInteger(fragIndex);
    totalLength += fragIndexLength;
    totalLength += blk.prependVarNumber(fragIndexLength);
    totalLength += blk.prependVarNumber(tlv::NdnlpFragIndex);
  }

  // NdnlpSequence
  uint64_t sequenceBE = htobe64(seq);
  size_t sequenceLength = blk.prependByteArray(
    reinterpret_cast<uint8_t*>(&sequenceBE), sizeof(sequenceBE));
  totalLength += sequenceLength;
  totalLength += blk.prependVarNumber(sequenceLength);
  totalLength += blk.prependVarNumber(tlv::NdnlpSequence);

  // NdnlpData
  totalLength += blk.prependVarNumber(totalLength);
  totalLength += blk.prependVarNumber(tlv::NdnlpData);

  return totalLength;
}

void
Slicer::estimateOverhead()
{
  ndn::EncodingEstimator estimator;
  size_t estimatedSize = Slicer_encodeFragment(estimator,
                         0, 0, 2, 0, m_mtu);

  size_t overhead = estimatedSize - m_mtu;
  m_maxPayload = m_mtu - overhead;
}

PacketArray
Slicer::slice(const Block& block)
{
  BOOST_ASSERT(block.hasWire());
  const uint8_t* networkPacket = block.wire();
  size_t networkPacketSize = block.size();

  uint16_t fragCount = static_cast<uint16_t>(
                         (networkPacketSize / m_maxPayload) +
                         (networkPacketSize % m_maxPayload == 0 ? 0 : 1)
                       );
  PacketArray pa = make_shared<std::vector<Block> >();
  pa->reserve(fragCount);
  SequenceBlock seqBlock = m_seqgen.nextBlock(fragCount);

  for (uint16_t fragIndex = 0; fragIndex < fragCount; ++fragIndex) {
    size_t payloadOffset = fragIndex * m_maxPayload;
    const uint8_t* payload = networkPacket + payloadOffset;
    size_t payloadSize = std::min(m_maxPayload, networkPacketSize - payloadOffset);

    ndn::EncodingBuffer buffer(m_mtu, 0);
    size_t pktSize = Slicer_encodeFragment(buffer,
      seqBlock[fragIndex], fragIndex, fragCount, payload, payloadSize);

    BOOST_VERIFY(pktSize <= m_mtu);

    pa->push_back(buffer.block());
  }

  return pa;
}

} // namespace ndnlp
} // namespace nfd
