/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2011-2018  Regents of the University of California.
 *
 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
 * contributors.
 *
 * ndnSIM 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.
 *
 * ndnSIM 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
 * ndnSIM, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 **/

#include "ndn-consumer-pcon.hpp"

NS_LOG_COMPONENT_DEFINE("ndn.ConsumerPcon");

namespace ns3 {
namespace ndn {

NS_OBJECT_ENSURE_REGISTERED(ConsumerPcon);

constexpr double ConsumerPcon::CUBIC_C;
constexpr uint32_t ConsumerPcon::BIC_MAX_INCREMENT;
constexpr uint32_t ConsumerPcon::BIC_LOW_WINDOW;

TypeId
ConsumerPcon::GetTypeId()
{
  static TypeId tid =
    TypeId("ns3::ndn::ConsumerPcon")
      .SetGroupName("Ndn")
      .SetParent<ConsumerWindow>()
      .AddConstructor<ConsumerPcon>()

      .AddAttribute("CcAlgorithm",
                    "Specify which window adaptation algorithm to use (AIMD, BIC, or CUBIC)",
                    EnumValue(CC_ALGORITHM::AIMD),
                    MakeEnumAccessor(&ConsumerPcon::m_ccAlgorithm),
                    MakeEnumChecker(CC_ALGORITHM::AIMD, "AIMD", CC_ALGORITHM::BIC, "BIC",
                                    CC_ALGORITHM::CUBIC, "CUBIC"))

      .AddAttribute("Beta",
                    "TCP Multiplicative Decrease factor",
                    DoubleValue(0.5),
                    MakeDoubleAccessor(&ConsumerPcon::m_beta),
                    MakeDoubleChecker<double>())

      .AddAttribute("CubicBeta",
                    "TCP CUBIC Multiplicative Decrease factor",
                    DoubleValue(0.8),
                    MakeDoubleAccessor(&ConsumerPcon::m_cubicBeta),
                    MakeDoubleChecker<double>())

      .AddAttribute("AddRttSuppress",
                    "Minimum number of RTTs (1 + this factor) between window decreases",
                    DoubleValue(0.5), // This default value was chosen after manual testing
                    MakeDoubleAccessor(&ConsumerPcon::m_addRttSuppress),
                    MakeDoubleChecker<double>())

      .AddAttribute("ReactToCongestionMarks",
                    "If true, process received congestion marks",
                    BooleanValue(true),
                    MakeBooleanAccessor(&ConsumerPcon::m_reactToCongestionMarks),
                    MakeBooleanChecker())

      .AddAttribute("UseCwa",
                    "If true, use Conservative Window Adaptation",
                    BooleanValue(true),
                    MakeBooleanAccessor(&ConsumerPcon::m_useCwa),
                    MakeBooleanChecker())

      .AddAttribute("UseCubicFastConvergence",
                    "If true, use TCP CUBIC Fast Convergence",
                    BooleanValue(false),
                    MakeBooleanAccessor(&ConsumerPcon::m_useCubicFastConv),
                    MakeBooleanChecker());

  return tid;
}

ConsumerPcon::ConsumerPcon()
  : m_ssthresh(std::numeric_limits<double>::max())
  , m_highData(0)
  , m_recPoint(0.0)
  , m_cubicWmax(0)
  , m_cubicLastWmax(0)
  , m_cubicLastDecrease(time::steady_clock::now())
  , m_bicMinWin(0)
  , m_bicMaxWin(std::numeric_limits<double>::max())
  , m_bicTargetWin(0)
  , m_bicSsCwnd(0)
  , m_bicSsTarget(0)
  , m_isBicSs(false)
{
}

void
ConsumerPcon::OnData(shared_ptr<const Data> data)
{
  Consumer::OnData(data);

  uint64_t sequenceNum = data->getName().get(-1).toSequenceNumber();

  // Set highest received Data to sequence number
  if (m_highData < sequenceNum) {
    m_highData = sequenceNum;
  }

  if (data->getCongestionMark() > 0) {
    if (m_reactToCongestionMarks) {
      NS_LOG_DEBUG("Received congestion mark: " << data->getCongestionMark());
      WindowDecrease();
    }
    else {
      NS_LOG_DEBUG("Ignored received congestion mark: " << data->getCongestionMark());
    }
  }
  else {
    WindowIncrease();
  }

  if (m_inFlight > static_cast<uint32_t>(0)) {
    m_inFlight--;
  }

  NS_LOG_DEBUG("Window: " << m_window << ", InFlight: " << m_inFlight);

  ScheduleNextPacket();
}

void
ConsumerPcon::OnTimeout(uint32_t sequenceNum)
{
  WindowDecrease();

  if (m_inFlight > static_cast<uint32_t>(0)) {
    m_inFlight--;
  }

  NS_LOG_DEBUG("Window: " << m_window << ", InFlight: " << m_inFlight);

  Consumer::OnTimeout(sequenceNum);
}

void
ConsumerPcon::WindowIncrease()
{
  if (m_ccAlgorithm == CC_ALGORITHM::AIMD) {
    if (m_window < m_ssthresh) {
      m_window += 1.0;
    }
    else {
      m_window += (1.0 / m_window);
    }
  }
  else if (m_ccAlgorithm == CC_ALGORITHM::CUBIC) {
    CubicIncrease();
  }
  else if (m_ccAlgorithm == CC_ALGORITHM::BIC) {
    BicIncrease();
  }
  else {
    BOOST_ASSERT_MSG(false, "Unknown CC Algorithm");
  }
  NS_LOG_DEBUG("Window size increased to " << m_window);
}

void
ConsumerPcon::WindowDecrease()
{
  if (!m_useCwa || m_highData > m_recPoint) {
    const double diff = m_seq - m_highData;
    BOOST_ASSERT(diff > 0);

    m_recPoint = m_seq + (m_addRttSuppress * diff);

    if (m_ccAlgorithm == CC_ALGORITHM::AIMD) {
      // Normal TCP Decrease:
      m_ssthresh = m_window * m_beta;
      m_window = m_ssthresh;
    }
    else if (m_ccAlgorithm == CC_ALGORITHM::CUBIC) {
      CubicDecrease();
    }
    else if (m_ccAlgorithm == CC_ALGORITHM::BIC) {
      BicDecrease();
    }
    else {
      BOOST_ASSERT_MSG(false, "Unknown CC Algorithm");
    }

    // Window size cannot be reduced below initial size
    if (m_window < m_initialWindow) {
      m_window = m_initialWindow;
    }

    NS_LOG_DEBUG("Window size decreased to " << m_window);
  }
  else {
    NS_LOG_DEBUG("Window decrease suppressed, HighData: " << m_highData << ", RecPoint: " << m_recPoint);
  }
}


void
ConsumerPcon::BicIncrease()
{
  if (m_window < BIC_LOW_WINDOW) {
    // Normal TCP AIMD behavior
    if (m_window < m_ssthresh) {
      m_window = m_window + 1;
    }
    else {
      m_window = m_window + 1.0 / m_window;
    }
  }
  else if (!m_isBicSs) {
    // Binary increase
    if (m_bicTargetWin - m_window < BIC_MAX_INCREMENT) { // Binary search
      m_window += (m_bicTargetWin - m_window) / m_window;
    }
    else {
      m_window += BIC_MAX_INCREMENT / m_window; // Additive increase
    }
    // FIX for equal double values.
    if (m_window + 0.00001 < m_bicMaxWin) {
      m_bicMinWin = m_window;
      m_bicTargetWin = (m_bicMaxWin + m_bicMinWin) / 2;
    }
    else {
      m_isBicSs = true;
      m_bicSsCwnd = 1;
      m_bicSsTarget = m_window + 1.0;
      m_bicMaxWin = std::numeric_limits<double>::max();
    }
  }
  else {
    // BIC slow start
    m_window += m_bicSsCwnd / m_window;
    if (m_window >= m_bicSsTarget) {
      m_bicSsCwnd = 2 * m_bicSsCwnd;
      m_bicSsTarget = m_window + m_bicSsCwnd;
    }
    if (m_bicSsCwnd >= BIC_MAX_INCREMENT) {
      m_isBicSs = false;
    }
  }
}

void
ConsumerPcon::BicDecrease()
{
  // BIC Decrease
  if (m_window >= BIC_LOW_WINDOW) {
    auto prev_max = m_bicMaxWin;
    m_bicMaxWin = m_window;
    m_window = m_window * m_cubicBeta;
    m_bicMinWin = m_window;
    if (prev_max > m_bicMaxWin) {
      // Fast Convergence
      m_bicMaxWin = (m_bicMaxWin + m_bicMinWin) / 2;
    }
    m_bicTargetWin = (m_bicMaxWin + m_bicMinWin) / 2;
  }
  else {
    // Normal TCP Decrease:
    m_ssthresh = m_window * m_cubicBeta;
    m_window = m_ssthresh;
  }
}


void
ConsumerPcon::CubicIncrease()
{
  // 1. Time since last congestion event in Seconds
  const double t = time::duration_cast<time::microseconds>(
                     time::steady_clock::now() - m_cubicLastDecrease).count() / 1e6;

  // 2. Time it takes to increase the window to cubic_wmax
  // K = cubic_root(W_max*(1-beta_cubic)/C) (Eq. 2)
  const double k = std::cbrt(m_cubicWmax * (1 - m_cubicBeta) / CUBIC_C);

  // 3. Target: W_cubic(t) = C*(t-K)^3 + W_max (Eq. 1)
  const double w_cubic = CUBIC_C * std::pow(t - k, 3) + m_cubicWmax;

  // 4. Estimate of Reno Increase (Currently Disabled)
  //  const double rtt = m_rtt->GetCurrentEstimate().GetSeconds();
  //  const double w_est = m_cubic_wmax*m_beta + (3*(1-m_beta)/(1+m_beta)) * (t/rtt);
  constexpr double w_est = 0.0;

  // Actual adaptation
  if (m_window < m_ssthresh) {
    m_window += 1.0;
  }
  else {
    BOOST_ASSERT(m_cubicWmax > 0);

    double cubic_increment = std::max(w_cubic, w_est) - m_window;
    // Cubic increment must be positive:
    // Note: This change is not part of the RFC, but I added it to improve performance.
    if (cubic_increment < 0) {
      cubic_increment = 0.0;
    }
    m_window += cubic_increment / m_window;
  }
}


void
ConsumerPcon::CubicDecrease()
{
  // This implementation is ported from https://datatracker.ietf.org/doc/rfc8312/

  const double FAST_CONV_DIFF = 1.0; // In percent

  // A flow remembers the last value of W_max,
  // before it updates W_max for the current congestion event.

  // Current w_max < last_wmax
  if (m_useCubicFastConv && m_window < m_cubicLastWmax * (1 - FAST_CONV_DIFF / 100)) {
    m_cubicLastWmax = m_window;
    m_cubicWmax = m_window * (1.0 + m_cubicBeta) / 2.0;
  }
  else {
    // Save old cwnd as w_max:
    m_cubicLastWmax = m_window;
    m_cubicWmax = m_window;
  }

  m_ssthresh = m_window * m_cubicBeta;
  m_ssthresh = std::max<double>(m_ssthresh, m_initialWindow);
  m_window = m_ssthresh;

  m_cubicLastDecrease = time::steady_clock::now();
}

} // namespace ndn
} // namespace ns3
