/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2022,  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,
 *                           The University of Memphis.
 *
 * 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 "lp-fragmenter.hpp"
#include "link-service.hpp"

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

namespace nfd::face {

NFD_LOG_INIT(LpFragmenter);

static_assert(lp::tlv::LpPacket < 253, "LpPacket TLV-TYPE must fit in 1 octet");
static_assert(lp::tlv::Sequence < 253, "Sequence TLV-TYPE must fit in 1 octet");
static_assert(lp::tlv::FragIndex < 253, "FragIndex TLV-TYPE must fit in 1 octet");
static_assert(lp::tlv::FragCount < 253, "FragCount TLV-TYPE must fit in 1 octet");
static_assert(lp::tlv::Fragment < 253, "Fragment TLV-TYPE must fit in 1 octet");

/**
 * \brief Maximum overhead on a single fragment, not counting other NDNLPv2 headers.
 */
constexpr size_t MAX_SINGLE_FRAG_OVERHEAD =
  1 + 9 + // LpPacket TLV-TYPE and TLV-LENGTH
  1 + 1 + 8 + // Sequence TLV
  1 + 9; // Fragment TLV-TYPE and TLV-LENGTH

/**
 * \brief Maximum overhead of adding fragmentation to payload, not counting other NDNLPv2 headers.
 */
constexpr size_t MAX_FRAG_OVERHEAD =
  1 + 9 + // LpPacket TLV-TYPE and TLV-LENGTH
  1 + 1 + 8 + // Sequence TLV
  1 + 1 + 8 + // FragIndex TLV
  1 + 1 + 8 + // FragCount TLV
  1 + 9; // Fragment TLV-TYPE and TLV-LENGTH

LpFragmenter::LpFragmenter(const LpFragmenter::Options& options, const LinkService* linkService)
  : m_options(options)
  , m_linkService(linkService)
{
}

void
LpFragmenter::setOptions(const Options& options)
{
  m_options = options;
}

const LinkService*
LpFragmenter::getLinkService() const
{
  return m_linkService;
}

std::tuple<bool, std::vector<lp::Packet>>
LpFragmenter::fragmentPacket(const lp::Packet& packet, size_t mtu)
{
  BOOST_ASSERT(packet.has<lp::FragmentField>());
  BOOST_ASSERT(!packet.has<lp::FragIndexField>());
  BOOST_ASSERT(!packet.has<lp::FragCountField>());

  if (MAX_SINGLE_FRAG_OVERHEAD + packet.wireEncode().size() <= mtu) {
    // fast path: fragmentation not needed
    // To qualify for fast path, the packet must have space for adding a sequence number,
    // because another NDNLPv2 feature may require the sequence number.
    return {true, {packet}};
  }

  auto [netPktBegin, netPktEnd] = packet.get<lp::FragmentField>();
  size_t netPktSize = std::distance(netPktBegin, netPktEnd);

  // compute size of other NDNLPv2 headers to be placed on the first fragment
  size_t firstHeaderSize = 0;
  const auto& packetWire = packet.wireEncode();
  if (packetWire.type() == lp::tlv::LpPacket) {
    for (const auto& element : packetWire.elements()) {
      if (element.type() != lp::tlv::Fragment) {
        firstHeaderSize += element.size();
      }
    }
  }

  // compute payload size
  if (MAX_FRAG_OVERHEAD + firstHeaderSize + 1 > mtu) { // 1-octet fragment
    NFD_LOG_FACE_WARN("fragmentation error, MTU too small for first fragment: DROP");
    return {false, {}};
  }
  size_t firstPayloadSize = std::min(netPktSize, mtu - firstHeaderSize - MAX_FRAG_OVERHEAD);
  size_t payloadSize = mtu - MAX_FRAG_OVERHEAD;
  size_t fragCount = 1 + ((netPktSize - firstPayloadSize) / payloadSize) +
                     ((netPktSize - firstPayloadSize) % payloadSize != 0);

  // compute FragCount
  if (fragCount > m_options.nMaxFragments) {
    NFD_LOG_FACE_WARN("fragmentation error, FragCount over limit: DROP");
    return {false, {}};
  }

  // populate fragments
  std::vector<lp::Packet> frags(fragCount);
  frags.front() = packet; // copy input packet to preserve other NDNLPv2 fields
  size_t fragIndex = 0;
  auto fragBegin = netPktBegin,
       fragEnd = fragBegin + firstPayloadSize;
  while (fragBegin < netPktEnd) {
    lp::Packet& frag = frags[fragIndex];
    frag.add<lp::FragIndexField>(fragIndex);
    frag.add<lp::FragCountField>(fragCount);
    frag.set<lp::FragmentField>({fragBegin, fragEnd});
    BOOST_ASSERT(frag.wireEncode().size() <= mtu);

    ++fragIndex;
    fragBegin = fragEnd;
    fragEnd = std::min(netPktEnd, fragBegin + payloadSize);
  }
  BOOST_ASSERT(fragIndex == fragCount);

  return {true, frags};
}

std::ostream&
operator<<(std::ostream& os, const FaceLogHelper<LpFragmenter>& flh)
{
  if (flh.obj.getLinkService() == nullptr) {
    os << "[id=0,local=unknown,remote=unknown] ";
  }
  else {
    os << FaceLogHelper<LinkService>(*flh.obj.getLinkService());
  }
  return os;
}

} // namespace nfd::face
